2010-05-15 21 views
17

Bueno, básicamente, me gustaría ejecutar un script que puede tomar tanto como 1 hora también.¿Cómo ejecutar un script PHP grande?

Lo que realmente quiero hacer es Enviar SMS a mis usuarios utilizando una API de terceros. Así que básicamente es como si le diera a mi script una serie de números de teléfono y activara el método para enviar SMS.

Sin embargo, suponiendo que tardan 5 segundos para enviar 1 SMS y quiero enviar 1000 SMS, que es aproximadamente de 1 a 2 horas. No puedo usar set_time_limit() porque estoy en el host compartido.

Una forma de hacerlo es almacenar números en una sesión y ejecutar cada SMS y usar javascript para actualizar esa página hasta el final. De esta manera, necesito mantener mi navegador abierto y la ejecución se detendrá si mi conexión a Internet está desconectada.

Entonces, ¿hay alguna forma mejor de hacerlo?

Espero ser lo suficientemente claro para explicar lo que quiero? Quiero ejecutar un script grande que puede tardar horas en ejecutarse sin obtener tiempo de espera.

+0

¿Está hablando con la API desde una computadora local donde puede aumentar el límite de tiempo de la pregunta? –

+1

¿Tiene la capacidad de configurar trabajos cron en su host compartido? – Mathew

+0

Sí, tengo acceso a trabajos cron –

Respuesta

4

Si su host lo permite, los trabajos cron son la mejor solución. Un trabajo cron es básicamente un script php normal que el servidor web ejecuta automáticamente en un intervalo de tiempo específico. Para sus necesidades, crearía una secuencia de comandos que se ejecuta cada 5 minutos y procesa sus números en lotes de 100 (obviamente, querrá modificar el intervalo de tiempo y el tamaño del lote para adaptarlo). Esto mantendrá baja la carga de tu servidor y evitará que tengas problemas con tu proveedor de hosting para acaparar recursos.

Para rastrear qué lote debe procesar su script, configuraría una tabla track_batch.Estas columnas deben darle una buena indicación de la forma de abordar el problema:

Identificación, date_run, start_record, end_record, final_run

Esencialmente:

  • Compruebe la fecha de la última lotes correr. Si no es la fecha actual (o cualquier otro identificador que elija usar ) para el lote actual, entonces proceda.
  • Si la última ejecución por lotes era para la fecha actual, a continuación, compruebe la columna final_run para ver si que ya ha terminado de procesar todos los números.
  • Si todavía tiene los números de proceso, utilice el inicio y final registros en conjunto con LIMIT de MySQL para construir la consulta db que su script utilizará para obtener el siguiente lote.
  • Procese sus números.
  • Almacena toda la información de este lote en la tabla track_batch.
  • Si la cantidad de números de la consulta devuelve es siempre menor que el tamaño máximo lotes, hemos llegado al final y puede establecer la columna final_run a 1.

Una vez que tenga su secuencia de comandos, tendrá que configurar el trabajo cron en sí. Es probable que los hosts compartidos tengan sus propias interfaces personalizadas para hacer esto, por lo que es probable que sean las mejores personas para preguntar una vez que haya hecho funcionar su script.

5

Los scripts PHP que se ejecutan desde la línea de comandos no se ven afectados por la opción max_execution_time.
Así que no tiene que preocuparse en absoluto.

+0

¿Y cómo los ejecuto como CLI en un host compartido? No creo que tenga acceso a eso. –

+0

sí, claro. gracias :) –

+1

Vea si tiene una sección "cron" en su panel de control. Eso le permitirá ejecutar scripts PHP a través de la línea de comando. – zundi

0

Usted puede o no puede uso set_time_limit()?

Si se puede .. Se usa:

<?php 
// Runs forever and ever... 
set_time_limit(-1); 
?> 
+8

Jeje, no voy a menospreciar porque es técnicamente correcto, pero ¿sugeriría que permita que un script se ejecute para siempre si fuera * su * vecino en un host compartido?:) – Mathew

20

Un script PHP se ejecuta desde la línea de comandos o desde un script de shell, trabajo cron, etc no tiene un tiempo de espera.

Para los scripts invocados por CLI, incluso si establece el tiempo de espera del script PHP dinámicamente con la función set_time_limit(), no tiene ningún efecto.

+0

por favor responda mi pregunta en: http://unix.stackexchange.com/questions/98642/run-a-php-script-in-centos-and-time-and-timeout?noredirect=1#comment150287_98642 –

3

No son las mejores opciones para usar set_time_limit(0), porque eso significa que se ejecutará indefinidamente incluso si tiene un error y su secuencia de comandos entra en un ciclo infinito.

En cambio, si usted estima cada SMS se va a tomar de 5 segundos, utilice este método:

while($there_are_more_sms_to_be_sent){ 
    set_time_limit(30); // enough spare time, just in case. 

    // Do your sending, blah blah 
} 

De esta manera, el plazo se actualizará de forma secuencial a 30 segundos. Por supuesto, puede tener el problema de bucle infinito con ese solo while, pero si tiene otras llamadas dentro de ese while ese límite evitará que esas llamadas tengan la culpa.

+0

tan cada vez que se repite, ¿se restablece el contador? –

+0

Eso es correcto. Asumía que estabas usando un cronjob también. Debe usarlo junto con este consejo, de modo que procesa, digamos, 100 mensajes cada vez pero también se asegura de que no se quede sin tiempo. – Seb

+0

¿Estás seguro de que puedes detener los trabajos cron de esta manera? – zehelvion

0

Una alternativa al uso de JavaScript es añadir la etiqueta meta Refresh a su página:

<meta http-equiv="Refresh" content="2; url=http://yoururl/script.php&step=x" ?> 

Los dos en content="2; url=.. indica al navegador a cargar la segunda url 2 después de que la página se ha cargado.

+1

Gracias, pero ya he especificado esto en mi pregunta. Estaba buscando algo que hacer en Server Side. También sabía sobre CRON, pero pensé que podría haber más formas de hacerlo. –

+0

claramente pregunta cómo ... PHP la solución tecnológica no es la mejor solución –

+0

No sé por qué crees que es necesario reaccionar ante una publicación casi 7 años de edad, pero para responder: al usar un cron o un trabajo de línea de comando es una muy buena solución para ejecutar grandes operaciones por lotes, dividir un trabajo en pequeños pasos y ejecutarlos paso a paso es igual de válido. Cron es agradable donde puedes usarlo, pero ejecuté con éxito scripts que tardaron más de 12 horas en el navegador cuando no tenía acceso al shell. – Matijs

0

EN EL CASO puede ejecutar Cron

por lo general tienen una cola, un gerente y los trabajadores. A menos que pueda llamar a la aplicación sms una vez cuando este modelo pueda ayudarlo, y no debe preocuparse por los tiempos de espera ya que cada trabajador se las arreglará solo.

que tienen algo así como:

<?php 
// PSEUDO CODE 
// grab pending from queue 

// <for> { 
// update to running 
exec("/usr/bin/php /path/to/send.php {$id} > /dev/null &"); 
// } 

y send.php enviará a cada SMS. En este momento tengo esto funcionando a una velocidad de 300/minuto ya que es la frecuencia máxima que puede configurar en un trabajo cron

Cuestiones relacionadas