C'est un conseil assez délicat, mais il fera certainement ce que vous voulez, si vous êtes prêt à modifier et recompiler PHP.
Jetez un œil au code source PHP sur https:// github.com/php/php-src/blob/master/Zend/zend_execute_API.c
(le fichier est Zend/zend_execute_API.c
), à la fonction zend_set_timeout
. C'est la fonction qui implémente la limite de temps. Voici comment cela fonctionne sur différentes plates-formes :
-
sous Windows, créez un nouveau thread, démarrez un minuteur dessus et, lorsqu'il se termine, définissez une variable globale appelée
timed_out
à 1, le noyau d'exécution PHP vérifie cette variable pour chaque instruction, puis quitte (très simplifié) -
sur Cygwin, utilisez itimer avec ITIMER_REAL, qui mesure le réel temps, y compris tout sommeil, attendre, peu importe, puis émettre un signal qui interrompra tout traitement et arrêter le traitement
-
sur d'autres systèmes Unix, utilisez itimer avec ITIMER_PROF, qui ne mesure que le temps CPU passé par le processus en cours (mais à la fois en mode utilisateur et en mode noyau). Cela signifie que l'attente d'autres processus (comme MySQL) n'entre pas en ligne de compte.
Maintenant, ce que vous voulez faire est de changer le itimer sur votre Linux de ITIMER_PROF à ITIMER_REAL, ce que vous devez bien sûr faire manuellement, recompiler, installer, etc. L'autre différence entre ces deux est qu'ils utilisent également un signal différent lorsque le minuteur s'exécute dehors. Donc ma suggestion est de changer l'ifdef :
# ifdef __CYGWIN__
dans
# if 1
afin que vous définissiez à la fois ITIMER_REAL et le signal que PHP attend sur SIGALRM.
Quoi qu'il en soit, toute cette idée n'a pas été testée (je l'utilise pour un système très spécifique, où ITIMER_PROF est cassé, et il semble au travail), sans support, etc. Utilisez-le à vos risques et périls. Cela peut fonctionner avec PHP lui-même, mais cela pourrait casser d'autres modules, en PHP et dans Apache, si pour une raison quelconque, ils utilisent le signal SIGALRM ou une autre minuterie.