2009-07-17 18 views
9

¿Hay alguna forma de que el código continúe (no salga) cuando se produce un error grave en PHP? Por ejemplo, recibo un error de tiempo de espera fatal y quiero cuando se salte esta tarea y la continúe con otras. En este caso, la secuencia de comandos se cierra.Error grave php

+0

Si está ejecutando un script PHP que requiere dicen más de 2-4 segundos en ejecutarse, entonces están haciendo algo muy mal. Use otra tecnología o cambie su flujo de trabajo. –

+3

@Alec Smart No estoy de acuerdo con eso: los trabajos de cron, etc., suelen tardar más de unos segundos. Tal vez funcionaría más rápido en C++, pero luego tendría que contratar un programador de C++ ... – Greg

Respuesta

13

Hay un truco que utiliza el almacenamiento en búfer de salida que le permitirá registrar ciertos errores fatales, pero no hay forma de continuar un script después de que se produce un error fatal, ¡eso es lo que lo hace fatal!

Si el script se agota, puede usar set_time_limit() para tener más tiempo para ejecutar.

1

Depende del tipo de error exacto. Puede detectar errores al crear su propio controlador de errores. Consulte la documentación en set_error_handler(), pero no todos los tipos de errores pueden detectarse. Mire el error de tiempo de espera que obtiene y vea qué tipo es. Si es uno de E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR o E_COMPILE_WARNING, entonces no puede atraparlo con un controlador de errores. Si es otro tipo, entonces puedes. Captúralo con el controlador de errores y simplemente devuelve.

0

¿Hay alguna manera de limitar el tiempo de ejecución de una función, pero no todas las secuencias de comandos? Por ejemplo

function blabla() 
{ 
return "yes"; 
} 

a hacerlo de modo que si no se ejecuta en 25 segundos para no volver;

+0

no, no puede limitar el tiempo de ejecución de una función. – Quamis

7

"Fatal Error", como su nombre indica, es fatal: detiene la ejecución del script/programa.

Si está utilizando PHP para generar páginas web y obtiene un error fatal relacionado con max_execution_time que, por defecto, equivale a 30 segundos, ciertamente está haciendo algo que realmente toma demasiado tiempo: los usuarios probablemente no esperarán tan largo para obtener la página.

Si está usando PHP para hacer algunos cálculos pesados, no en una página web (pero a través de CLI o un cron, o cosas por el estilo), se puede establecer otra (mayor) valor de max_execution_time. Tiene dos formas de hacerlo:

Lo primero es modificar php.ini, establecer este valor (ya está en el archivo, simplemente edite el valor de la propiedad). El problema es que lo modificará también para el servidor web, que es malo (esta es una medida de seguridad, después de todo). Mejor manera es crear una copia de php.ini, llamada, por ejemplo, phpcli.ini, y modificar este archivo. A continuación, utilizarlo cuando se invoca php:

php -c phpcli.ini myscript.php 

Esto va a funcionar muy bien si usted tiene muchas propiedades que necesita para configurar la CLI para su ejecución. (Al igual que memory_limit, que a menudo tiene que ser fijado a un valor más alto para los lotes de larga duración)

La otra forma es definir un valor diferente para max_execution_time cuando se invoca php, así:

php -d max_execution_time=60 myscript.php 

Esto es genial si lo inicia a través del crontab, por ejemplo.

1

Si tiene una versión de PHP adecuada (PHP> = 5.2 para error_get_last) puede probar la técnica descrita here que usa register_shutdown_function y error_get_last.

Esto no le permitirá "continuar" cuando obtenga un error fatal, pero al menos le permite registrar el error (y tal vez enviar un correo electrónico de advertencia) antes de mostrar una página de error personalizada al usuario.

funciona algo como esto:

function fatalErrorHandler() 
{ 
    $lastError = error_get_last(); 
    if (isset($lastError["type"]) && $lastError["type"]==E_ERROR) { 
     // do something with the fatal error 
    } 
} 
... 
register_shutdown_function('fatalErrorHandler'); 


Unos pocos puntos:

  • puede utilizar ob_clean() para eliminar cualquier contenido que se generó antes del error fatal.
  • es realmente mala idea para hacer algo para intensivo en el controlador de apagado, esta técnica es sobre la falla elegante en lugar de recuperación.
  • Hagas lo que hagas, no intentes registrar el error en una base de datos ... ¿y si fue un tiempo de espera de la base de datos que causó el error fatal?
  • por alguna razón He tenido problemas para hacer que esta técnica funcione el 100% del tiempo cuando se desarrolla en Windows usando WAMP.
0

La respuesta más sencilla que puedo darle es esta función: http://php.net/manual/en/function.pcntl-fork.php

Con más detalle, lo que puede hacer es:

  • Tenedor de la parte del proceso se cree que puede o podría no causa un error fatal (es decir, la mayor parte del código)
  • El script que bifurca el proceso debe ser un script muy simple.

Por ejemplo, esto es algo que lo haría con una cola de trabajos que tengo:

<?php 
// ... load stuff regarding the job queue 

while ($job = $queue->getJob()) { 
    $pid = pcntl_fork(); 
    switch ($pid) { 
     case -1: 
      echo "Fork failed"; 
      break; 
     case 0: 
      // do your stuff here 
      echo "Child finished working"; 
      break; 
     default: 
      echo "Waiting for child..."; 
      pcntl_wait($status); 
      // check the status using other pcntl* functions if you want 
      break; 
    } 
} 
Cuestiones relacionadas