【问题标题】:Trigger an URL with a cron job使用 cron 作业触发 URL
【发布时间】:2017-03-07 08:58:44
【问题描述】:

我正在开发一个 Symfony 3 网站,我需要使用 cron 作业调用我网站的 URL。

我的网站托管在 OVH 上,我可以在其中配置我的 cron 作业。

目前,我已经设置了命令:./demo/Becowo/batch/emailNewUser.php

emailNewUser.php 内容:

<?php

header("Location: https://demo.becowo.com/email/newusers");

?>

在我的日志中:

[2017-03-07 08:08:04] ## OVH ## END - 2017-03-07 08:08:04.448008 退出代码:0

[2017-03-07 09:08:03] ## OVH ## START - 2017-03-07 09:08:03.988105 执行:/usr/local/php5.6/bin/php /homez.2332 /coworkinwq/./demo/Becowo/batch/emailNewUser.php

但没有发送电子邮件。 我应该如何配置我的 cron 作业来执行这个 URL? 还是我应该直接打电话给我的控制器?怎么样?

【问题讨论】:

  • 写一个 symfony 命令来做你想做的事然后调用它会更好,也更安全。
  • 像 DevDonkey 一样,如果您的主机允许您执行命令,我也会这样做。

标签: cron symfony ovh


【解决方案1】:

好的,终于成功了!!!

这是我为其他人遵循的步骤:

1/ 您需要一个控制器来发送电子邮件:

由于控制器会通过命令调用,所以需要注入一些服务

em : 刷新数据的实体管理器

mailer : 访问 swiftMailer 服务发送邮件

模板:访问 TWIG 服务以在电子邮件正文中使用模板

MemberController.php

<?php

namespace Becowo\MemberBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Becowo\CoreBundle\Form\Type\ContactType;
use Becowo\CoreBundle\Entity\Contact;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;

class MemberController extends Controller
{
  private $em = null;
  private $mailer = null;
  private $templating = null;
  private $appMember = null;

  public function __construct(EntityManager $em, $mailer, EngineInterface $templating, $appMember)
  {
      $this->em = $em;
      $this->mailer = $mailer;
      $this->templating = $templating;
      $this->appMember = $appMember;
  }

 

  public function sendEmailToNewUsersAction()
  {
    // To call this method, use the command declared in Becowo\CronBundle\Command\EmailNewUserCommand 
    // php bin/console app:send-email-new-users

  	$members = $this->appMember->getMembersHasNotReceivedMailNewUser();
  	$nbMembers = 0;
  	$nbEmails = 0;
  	$listEmails = "";
    
  	foreach ($members as $member) {
  		$nbMembers++;
  		if($member->getEmail() !== null)
  		{
  			$message = \Swift_Message::newInstance()
	        ->setSubject("Hello")
	        ->setFrom(array('toto@xxx.com' => 'Contact Becowo'))
	        ->setTo($member->getEmail())
          ->setContentType("text/html")
	        ->setBody(
	            $this->templating->render(
	                'CommonViews/Mail/NewMember.html.twig',
	                array('member' => $member)
	            ))
          ;

	      	$this->mailer->send($message);
	      	$nbEmails++;
	      	$listEmails = $listEmails . "\n" . $member->getEmail() ;

	      	$member->setHasReceivedEmailNewUser(true);
	      	
	  		$this->em->persist($member);
  		}
  	}
      $this->em->flush();

  	$result = " Nombre de nouveaux membres : " . $nbMembers . "\n Nombre d'emails envoyes : " . $nbEmails . "\n Liste des emails : " . $listEmails ;
    

  	return $result;
  }

}

2/ 将控制器称为服务

app/config/services.yml

  app.member.sendEmailNewUsers :
        class: Becowo\MemberBundle\Controller\MemberController
        arguments: ['@doctrine.orm.entity_manager', '@mailer', '@templating', '@app.member'] 

3/ 创建一个控制台命令来调用你的控制器

文档:http://symfony.com/doc/current/console.html

YourBundle/Command/EmailNewUserCommand.php

<?php

namespace Becowo\CronBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;

class EmailNewUserCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        
        // the name of the command (the part after "php bin/console")
        $this->setName('app:send-email-new-users')
			 ->setDescription('Send welcome emails to new users') 
    	;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
    	// outputs a message to the console followed by a "\n"
        $output->writeln('Debut de la commande d\'envoi d\'emails');

     	// access the container using getContainer()
        $memberService = $this->getContainer()->get('app.member.sendEmailNewUsers');
        $results = $memberService->sendEmailToNewUsersAction();

        $output->writeln($results);
    }
}

4/ 测试你的命令!

在控制台中,调用你的命令:php bin/console app:send-email-new-users

5/ 创建一个脚本来运行命令

文档(法语):http://www.christophe-meneses.fr/article/deployer-son-projet-symfony-sur-un-hebergement-perso-ovh

..Web/Batch/EmailNewUsers.sh

#!/bin/bash

today=$(date +"%Y-%m-%d-%H")
/usr/local/php5.6/bin/php /homez.1111/coworkinwq/./demo/toto/bin/console app:send-email-new-users --env=demo > /homez.1111/coworkinwq/./demo/toto/var/logs/Cron/emailNewUsers-$today.txt

我花了一些时间才得到正确的脚本。

注意 php5.6:它必须与您在 OVH 上的 PHP 版本相匹配

别忘了在服务器上上传 bin/console 文件

homez.xxxx/name 必须与您的配置匹配(我在 OVH 上找到了我的,然后在日志中找到了)

重要提示:当您在服务器上上传文件时,添加执行权限(CHMOD 704)

6/ 在 OVH 中创建 cron 作业

使用以下命令调用您的脚本:./demo/Becowo/web/Batch/EmailNewUsers.sh

语言:其他

7/等等!

您需要等待下一次运行。然后查看 OVH cron 日志,或通过 .sh 文件中的命令创建的您自己的日志

我花了好几天才拿到它.. 享受!!

【讨论】:

  • 显然问题已经解决了,那么关于这篇文章的下一步是什么?
【解决方案2】:

如上所述,您应该使用 symfony commaad 来执行此操作。这是给你的一个例子。

注意:虽然它有效,但您始终可以改进此示例。尤其是命令调用端点的方式。

控制器服务定义:

services:
    yow_application.controller.default:
        class: yow\ApplicationBundle\Controller\DefaultController

控制器本身

namespace yow\ApplicationBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Response;

/**
 * @Route("", service="yow_application.controller.default")
 */
class DefaultController
{
    /**
     * @Method({"GET"})
     * @Route("/plain", name="plain_response")
     *
     * @return Response
     */
    public function plainResponseAction()
    {
        return new Response('This is a plain response!');
    }
}

命令服务定义

services:
    yow_application.command.email_users:
        class: yow\ApplicationBundle\Command\EmailUsersCommand
        arguments:
            - '@http_kernel'
        tags:
            - { name: console.command }

命令本身

namespace yow\ApplicationBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class EmailUsersCommand extends Command
{
    private $httpKernel;

    public function __construct(HttpKernelInterface $httpKernel)
    {
        parent::__construct();

        $this->httpKernel = $httpKernel;
    }

    protected function configure()
    {
        $this->setName('email:users')->setDescription('Emails users');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $request = new Request();
        $attributes = [
            '_controller' => 'yow_application.controller.default:plainResponseAction',
            'request' => $request
        ];
        $subRequest = $request->duplicate([], null, $attributes);

        $response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);

        $output->writeln($response);
    }
}

测试

$ php bin/console email:users
Cache-Control:      no-cache, private
X-Debug-Token:      99d025
X-Debug-Token-Link: /_profiler/99d025

This is a plain response!
1.0
200
OK

【讨论】:

  • 嗨!感谢您的回答。你的意思是我可以用 cron 任务调用命令 'php bin/console email:users' 吗?
  • */5 * * * * cd /path/to/your/app &amp;&amp; php bin/console --env=prod email:users 之类的东西应该可以。我想你知道--env 标志是什么意思。
  • 问题是,要运行 cron 作业,我必须通过 OVH 来完成,我只能调用 PHP 文件。所以我创建了一个包含 我会告诉你它是否有效
猜你喜欢
  • 2014-11-26
  • 2012-10-26
  • 2017-07-26
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2022-12-09
相关资源
最近更新 更多