Активировать URL-адрес с заданием cron

Я работаю над веб-сайтом Symfony 3, и мне нужно вызвать URL-адрес моего веб-сайта с помощью задания cron.

Мой веб-сайт размещен на 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-адреса? Или я должен позвонить напрямую моему контроллеру? Как ?


person Olivia    schedule 07.03.2017    source источник
comment
Было бы намного лучше и безопаснее написать команду symfony, которая будет делать то, что вы хотите, и вызывать ее вместо этого.   -  person DevDonkey    schedule 07.03.2017
comment
как и DevDonkey, я бы сделал то же самое, если бы ваш хост разрешил вам выполнять команды.   -  person Favian Ioel P    schedule 07.03.2017


Ответы (2)


хорошо, наконец-то это работает!!!

Вот шаг, который я выполнил для других:

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('[email protected]' => '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/ Вызов контроллера как услуга

приложение/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

..Веб/Пакет/Электронная почтаНовыеПользователи.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: он должен соответствовать вашей версии PHP на OVH.

Не забудьте загрузить файл bin/console на сервер

homez.xxxx/name должен совпадать с вашим конфигом (я нашел свой на OVH, а потом в логах)

ВАЖНО: при загрузке файла на сервер добавьте права на выполнение (CHMOD 704)

6/ Создайте задание cron в OVH

Вызовите свой скрипт с помощью команды: ./demo/Becowo/web/Batch/EmailNewUsers.sh

Язык : другой

7/ Подождите!

Нужно дождаться следующего запуска. Затем посмотрите журналы OVH cron или ваши собственные журналы, созданные с помощью команды в файле .sh.

Мне потребовалось несколько дней, чтобы получить его. Наслаждайтесь !!

person Olivia    schedule 08.03.2017
comment
Очевидно, проблема уже решена, так что же делать дальше с этим постом? - person BentCoder; 09.03.2017

Как отмечалось выше, вы должны сделать это с помощью запятой Symfony. Это пример для вас.

ПРИМЕЧАНИЕ. Несмотря на то, что это работает, вы всегда можете улучшить этот пример. Особенно то, как команда вызывает вашу конечную точку.

Определение службы контроллера:

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
person BentCoder    schedule 07.03.2017
comment
Привет ! спасибо за Ваш ответ. Вы имеете в виду, что я могу вызвать команду «php bin/console email:users» с помощью задачи cron? - person Olivia; 08.03.2017
comment
Что-то вроде */5 * * * * cd /path/to/your/app && php bin/console --env=prod email:users должно подойти. Я полагаю, вы знаете, что означает флаг --env. - person BentCoder; 08.03.2017
comment
дело в том, что для запуска задания cron мне нужно сделать это через OVH, где я могу вызвать только файл PHP. Поэтому я создаю файл, содержащий ‹?php exec(php bin/console app:send-email-new-users); ?› Я скажу вам, если это работает - person Olivia; 08.03.2017