2012-06-29 24 views
6

Empecé a usar CakePHP (1.2) hace unos meses para agregar pequeñas características a la aplicación de la compañía y no estoy muy familiarizado con ella.Tortphp cron job para llamar a la acción de un controlador

Probamos localmente y luego en un servidor de desarrollo antes de fusionarlo con un servidor de producción.

Quiero que se llame una acción de controlador cada hora con lo que supuse que era la mejor manera de hacerlo a través de mis investigaciones, un trabajo de cron.


Intento 1

Después de leer estos,

http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-actions-from-cron-and-the-command-line

http://book.cakephp.org/1.2/en/view/110/Creating-Shells-Tasks

pude poner en práctica algo sin errores, pero no se ejecuta la acción.

Sobre la base de estos ejemplos, he añadido un llamado cron_dispatcher.php archivo en mi directorio de aplicación (no aplicación/web raíz) y luego se hicieron a este comando desde el directorio de aplicación

php cron_dispatcher.php/controlador/acción/param

Todavía no pasó nada, pero funciona perfecto cuando lo llamo a través de la url.


Intento 2

I intentado crear una concha (email.php) que llame a la acción en/app/vendedores/conchas /.

<?php 

class EmailShell extends Shell { 

    public function main() { 
     $this->out('Test'); 
    } 

} 
?> 

Esto da salida a prueba con éxito en la consola utilizando el correo electrónico

torta principal

pero entonces no puedo encontrar cómo llamar a la acción del controlador. Lo intenté

$ this-> requestAction ('/ controller/action');

También he intentado hacer la llamada desde una función diferente a la principal en el shell.

He tratado de incluir el controlador en el $ utiliza variable como lo haría con un modelo, pero eso no funcionó (y que no tiene sentido creo)

No creo que la creación de una la tarea es la solución, ya que no quiero duplicar la función sendEmails, ¡por eso estoy buscando una forma de llamar la acción del controlador desde un shell o lo que sea!

Es probable que haya alguna teoría que me falta, gracias


Solución

me trasladaron algunos métodos desde el controlador a un modelo y que era capaz de llamar desde un shell.

App::import('Component', 'Email'); 

class SendMemosShell extends Shell { 

    var $uses = array(
     'Memo', 
    ); 

    public function main() { 

    } 

    public function sendEmails() { 
     $this->Email =& new EmailComponent(null); 
     $memoList = $this->Memo->getMemos(); 
     //... 
    } 
} 

Este enlace ayudó http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html


edición: aclaró algunas de las informaciones y ha añadido la solución

Respuesta

3

que es un tema muy común en realidad, se encontró con que también.

Un controlador está decidiendo cómo manejar una solicitud y comenzar esa tarea. En este caso, no hay necesidad de un controlador ya que tiene una tarea de shell, la tarea ya está clara.

Sabiendo eso, no tiene sentido llamar a un método de controlador.

Así que reconsidere sus opciones, y sí, esto es bastante difícil. Por ejemplo, puede decidir que el envío del correo electrónico es un paso lógico comercial, por lo que debe estar en el modelo. Otra opción es separarlo por completo (eso es lo que más nos gusta).

En ese caso, tendrá que crear una cola donde colocar todos los correos electrónicos para enviar. Ese es un buen diseño ya que entonces sabes que la cantidad de lógica en el controlador baja y está separada. De esa forma obtienes un servicio de correo electrónico.

Por ejemplo, puede solicitar al servicio que envíe un correo de "usuario nuevo". Luego, agrega el objeto Usuario a él y debe manejarlo solo. De esa manera usted puede incluso escalar ya que su servicio podría ser, por ejemplo, subcontratado, se podría ampliar varios servidores en el servicio, etc.

Editar:

buenas preguntas.

Pasos a seguir:

  1. centralizar el proceso de "envío de correo electrónico" en primer lugar. Así que elija una ubicación donde ponerlo. Puede decidir: Agregar para enviar un correo electrónico a una cola o llamar al servicio directamente. Por ejemplo, puede agregar una tarea de shell para enviar correos electrónicos.

  2. Llamar al shell: Ahora tiene el problema de llamar al shell. En general, no quieres. Por qué no? Porque un shell (una tarea) podría ejecutarse durante mucho tiempo. Entonces, es por eso que utilizamos colas en el medio. De modo que puede solicitar la cola o dejar que la cola le envíe un mensaje de que se ha hecho algo. Por ejemplo, piense en un servidor de correo que no funciona. Tienes que volver a intentarlo, etc. Eso no debería estar en una solicitud web porque el usuario está esperando una respuesta.

  3. El tercer paso es llamar al intérprete de comandos desde su cron, ahora eso es fácil ya que ya está en la línea de comandos para poder usar las llamadas estándar.

De todos modos, hay opciones para hacer una llamada directa desde un controlador pero no debería.Este post da algunas ideas muy interesantes: CakePHP: Run shell job from controller

Edición 31/08/'13: Véase el sistema de eventos de CakePHP también para algunos ejemplos: http://book.cakephp.org/2.0/en/core-libraries/events.html

+0

Necesito poder llamar esta acción manualmente también (haciendo clic en un botón en la vista, por ejemplo). ¿Sugiere que cree una tarea en lugar de una acción de controlador y llamé a esto en su lugar (de forma automática con un trabajo cron y manualmente al hacer clic)? ¿Es un caparazón algo que llamas totalmente separado de la lógica o estabas hablando de la cola? A veces tengo que enviar múltiples correos electrónicos a la vez (cuando se marca automáticamente) pero no debería ocurrir muy a menudo, así que me pregunto si la cola es demasiado compleja para mis necesidades. Gracias por su respuesta – Catherine

+0

También les respondí, en general, debería pensar en el tamaño de su aplicación y su diseño. La forma en que respondí tu pregunta es una de las formas en que debería hacerse. No significa que es el camino que es bueno para los negocios. Si solo envía un correo a veces, tal vez no valga la pena crear una configuración completa y más compleja para él. –

+1

Hola de nuevo, gracias por su respuesta detallada. Acordamos que no había necesidad de enviar correos electrónicos manualmente, así que creé un shell que envía los correos electrónicos. También me obligó a mover más métodos del controlador al modelo, que es más apropiado si lo entendí bien. Luego seguí este procedimiento para configurar el trabajo cron: http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html Decidí no utilizar las colas, aunque esto parecía interesante porque no valió la pena en este caso! – Catherine

0

Dependiendo de lo que hay que hacer, a menudo mantener a estos métodos en mis acciones de controlador. En la parte superior de la acción, marque $ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR'] para garantizar que solo el sitio web pueda invocar la acción. Luego, en cron me gustaría curvar o wget esta dirección.

Tiene sus ventajas: más fácil de ejecutar localmente durante el desarrollo (solo ingrese la url en su navegador), además hay algunas diferencias entre ejecutar la versión cli de php y la versión de apache, así como las variables de solicitud (por ejemplo, pastel no se puede obtener el dominio/dirección del sitio web a través de cli como se puede ejecutar como módulo de apache, por lo que los enlaces absolutos al sitio web usando html helper no funcionan).

+0

Intenté simplemente actualizar la dirección y no parecía ejecutar la acción como quería, probablemente lo hice mal. Aunque no he tratado de ponerlo en el crontab, supongo que debería experimentar más sobre eso en el futuro. Gracias y lo siento, no puedo calificarte. Todavía soy nuevo en el sitio. – Catherine

Cuestiones relacionadas