4 votes

Raisons de l'échec de la commande popen de PHP

J'ai un processus de messagerie par lot qui envoie environ 30 000 messages électroniques. J'ai rencontré un problème étrange : le processus est achevé à environ 85 %, puis les courriels commencent à échouer avec le message suivant Could not execute: /usr/sbin/sendmail J'utilise une bibliothèque appelée PHPMailer 1.73 et le code correspondant d'où provient le message d'erreur est le suivant

if(!@$mail = popen($sendmail, "w"))
{
    $this->SetError($this->Lang("execute") . $this->Sendmail);
    return false;
}

La valeur de $sendmail est de la forme : /usr/sbin/sendmail -oi -f support1@example.com -t

J'ai set_time_limit(0); pour que le script n'ait pas de délai d'attente.

Y a-t-il un moyen de comprendre pourquoi tout d'un coup popen() commence à échouer ? Le système d'exploitation pourrait-il être à court de descripteurs de fichiers ou atteindre une autre limite ?

Comment dois-je résoudre ce problème ? Devrais-je faire en sorte qu'il s'endorme puis réessayer la popen() plusieurs fois avant d'échouer ?

Mise à jour : Merci à la suggestion de Marko de vérifier proc_open() J'ai trouvé sur le documentation proc_open un commentaire indiquant que s'il retourne FALSE cela signifie probablement que vous n'avez plus de descripteurs de fichiers ou que vous n'avez plus de mémoire. J'ai découvert que mon processus prenait 20G de la mémoire. Mais comment peut-il prendre autant de mémoire si memory_limit est fixé à 64M ? Eh bien, il semble que l'exécution de programmes externes avec exec() , popen() o proc_open() ne comptent pas dans la limite de mémoire de PHP. Voir cette question de l'OS pour plus d'informations à ce sujet, Déboguer l'utilisation de la mémoire dans mod_php . Je ne sais toujours pas comment cela se produit, mais je soupçonne une sorte de fuite de mémoire.

En résumé, popen() y proc_open() peut retourner FALSE si vous êtes à court de descripteurs de fichiers ou de mémoire.

2voto

Marko Points 367

Je recommande d'utiliser proc_open à la place. Elle est légèrement plus complexe à utiliser, mais vous donne accès à stdout et stderr. Les messages sur ces deux tuyaux vous feront gagner beaucoup de temps de débogage.

Pour l'utiliser, il suffit de lire les exemples et les commentaires dans la documentation PHP.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X