Pourquoi ne devrais-je pas utiliser les commandes unix de PHP?

Pourquoi préféreriez-vous continuer à utiliser les commandes bash via exec() dans php?

Je ne considère pas le problème de portabilité (je ne vais certainement pas le porter pour qu’il fonctionne sous Windows). C’est juste une bonne façon d’écrire des scripts.

D’un côté:

  1. J’ai besoin d’écrire beaucoup plus de lignes dans php que dans bash pour accomplir la même tâche. Par exemple, lorsque je dois filtrer des lignes dans un fichier, je ne peux pas créer d’images à l’aide d’un cat file | grep ssortingng > new_file plutôt que d’un cat file | grep ssortingng > new_file cat file | grep ssortingng > new_file . Cela prendrait beaucoup plus de temps et d’efforts à faire en PHP.
  2. Je ne veux pas parsingr toutes les situations où quelque chose pourrait mal tourner. Je vais juste montrer la sortie de commande bash à l’utilisateur pour qu’il sache exactement ce qui s’est passé.
  3. Je n’ai pas besoin d’écrire un autre wrapper autour des fonctions du système de fichiers et de l’utiliser. Il est beaucoup plus efficace de tirer parti du système d’exploitation pour la recherche de fichiers, la manipulation, etc.

D’autre part:

  1. Appeler la commande unix avec exec() peut être inefficace dans la plupart des cas. Il est très coûteux de créer un processus distinct. Ne pas parler de scripts exécutés sous Apache, ce qui est encore moins efficace que de générer des scripts en ligne de commande.
  2. Parfois, il s’agit de «magie noire» et de scriptage de type perl. Bien que cela puisse être évité via des commentaires détaillés.
  3. J’essaie peut-être d’utiliser deux outils différents ensemble lorsqu’ils ne sont pas censés le faire. Chaque outil a sa propre application et ne doit pas être mélangé.
  4. Même si je suis sûr que les utilisateurs n’essaieront pas d’exécuter le script à des fins malveillantes, l’utilisation de exec() est une menace potentielle pour la sécurité. Dans la plupart des cas, les données utilisateur peuvent être échappées avec escapeshellarg() , mais cela rest un problème à prendre en compte.

Qu’est-ce que vous essayez de réaliser? PHP a des fonctions basées sur les regex pour trouver ce dont vous avez besoin dans un fichier. Oui, vous aurez probablement besoin d’environ 5 lignes de code pour le faire, mais ce ne sera probablement pas plus ou moins efficace.

La principale raison contre l’utilisation de exec () en PHP est pour la sécurité. Si vous faites confiance à votre utilisateur pour qu’il vous commande exec () dans bash, il peut facilement exécuter des commandes malveillantes, telles que l’installation et le démarrage de chevaux de Troie, la suppression de fichiers, etc.

Tant que vous êtes prudent (utilisez les commandes d’échappement du shell pour nettoyer les entrées de l’utilisateur, restreignez les permissions des utilisateurs Apache, etc.), cela ne devrait pas poser de problème. Je ne fais que travailler sur une plate-forme complète en ce moment, qui repose sur l’exécution des processus shell tout simplement parce que C ++ est beaucoup plus rapide que PHP, donc j’ai écrit beaucoup de logique de backend en tant qu’application shell et je garde PHP pour la logique frontale.

Une autre raison d’éviter cela est qu’il est beaucoup plus facile de créer des failles de sécurité comme celle-ci. par exemple, si un utilisateur parvient à se faufiler

 `rm -rf /` 

(Avec des backticks) dans l’entrée, votre code bash pourrait en fait détruire le serveur (ou au moins quelque chose).

c’est surtout une chose religieuse, la plupart des développeurs essaient d’écrire du code qui fonctionne toujours. s’appuyer sur des commandes externes est un moyen sûr de faire échouer votre code sur certains systèmes (même sur le même système d’exploitation).

Même si vous dites que la portabilité n’est pas un problème, vous ne savez jamais avec certitude ce que l’avenir vous réserve, alors je vous encourage à reconsidérer cette position. Par exemple, on m’a déjà demandé de porter un éditeur écrit (par quelqu’un d’autre) d’Unix sur DOS. Le programme d’origine ne devait pas être porté et a été écrit avec des appels spécifiques à Unix profondément incorporés dans le code. Après avoir examiné la quantité de travail requirejse, nous avons abandonné la tâche car cela prend trop de temps.

J’ai utilisé des appels exec en PHP; Cependant, je n’avais pas d’autre moyen d’accomplir ce dont j’avais besoin (j’ai dû appeler un autre programme écrit dans une autre langue sans autre pont entre les langues). Cependant, IMO, les appels exec qui ne sont pas nécessaires sont laids. Comme d’autres l’ont dit, ils peuvent également créer des risques pour la sécurité et ralentir votre programme.

Comme vous l’avez dit vous-même, vous devez bien documenter les appels exec pour vous assurer qu’ils seront compris par les programmeurs. Pourquoi créer le travail supplémentaire? Pas seulement maintenant, mais à l’avenir, lorsque des modifications à l’appel exec devront également être documentées.

Enfin, je vous suggère d’apprendre un peu mieux PHP et ses fonctions. Je ne suis pas très bon avec PHP, mais en quelques minutes avec Google et php.net , je pense avoir accompli la même chose que vous avez donné comme exemple avec:

 $search_results = preg_grep($search_ssortingng, file($file_name)); foreach ($search_results as $result) { echo $result . "\n"; } 

Oui, c’est un peu plus de code, mais pas beaucoup, et vous pouvez le mettre dans une fonction si nécessaire … et je ne serais pas surpris si un gourou PHP pouvait le raccourcir.

IMHO, la principale préoccupation avec l’utilisation de exec () pour exécuter des commandes * nix via PHP est la sécurité, plus que la performance ou même le style de code.

Si vous avez une très bonne désinfection des intrants (et c’est très difficile à réaliser), vous risquez de ne pas avoir de trou de sécurité.

Personnellement, si la portabilité n’est pas un problème, j’utiliserais totalement les commandes * nix comme grep, Locate, etc. anyday plutôt que d’essayer de dupliquer cette fonctionnalité en PHP.

Il s’agit d’utiliser le meilleur outil pour le travail. Dans certains cas, sans doute plus souvent que la plupart des gens ne le réalisent, il est beaucoup plus efficace de tirer parti du système d’exploitation pour la recherche de fichiers, la manipulation, etc. (entre autres choses).

Beaucoup de gens descendraient sur votre comme une tonne de briques pour même mentionner en utilisant exec. Certaines personnes considéreraient le blasphème mais pas moi. Je ne vois rien de mal avec exec dans certaines situations si votre serveur a été correctement configuré. L’inconvénient est que vous créez un autre processus.

Si vous utilisez votre PHP en utilisant un serveur Web, l’utilisateur qui exécute le script peut ne pas être autorisé à exécuter certaines commandes du shell. vous avez dit que la portabilité n’est pas un problème, mais je peux vous garantir qu’elle EST un problème (sauf si vous créez des scripts PHP pour le plaisir). Dans le monde des affaires où les choses et les conditions changent rapidement, vous ne saurez pas que vous devrez peut-être un jour exécuter vos scripts sur d’autres plates-formes.

Il n’est pas sécurisé à moins que vous ne preniez des précautions extrêmes pour vous assurer qu’il ne peut pas être utilisé par des personnes exécutant le code.

php n’est pas un bon exécuteur. php génère un processus à partir d’Apache, et si ce processus se bloque, votre serveur Apache va se bloquer, si votre site fonctionne également sur le même Apache; ça va échouer.

Vous pouvez vous attendre à avoir des problèmes idiots comme ceux-ci, si cela arrive, vous ne pouvez même pas redémarrer apache sans tuer manuellement le processus généré à partir du shell.

http://bugs.php.net/bug.php?id=38915

par conséquent, je ne parle pas de sécurité, exécuter des commandes linux à partir de php échoue plus que vous ne le pensiez, pire dans l’utilisation de exec, il n’est pas toujours possible de récupérer des messages d’erreur en php. ou écrivez la méthode suivante qui dépend de ce qui s’est passé avec exec.

considérez ce pseudo exemple:

 exec ('bash myscript.sh',$x) if (myScriptWasOk == true) then do this 

Vous ne pouvez pas obtenir cette variable «myScriptWasOk» correctement. Vous n’en savez rien, $ x vous aidera parfois.

Tout cela étant dit, si vous avez besoin de quelque chose de simple, et si vous avez testé votre script et que cela fonctionne correctement, allez-y.

Si vous ne visez que la compatibilité Unix (ce qui est parfaitement correct), je ne vois rien de mal à cela. Pratiquement le système d’exploitation serveur disponible aujourd’hui est un clone Unix, sauf bien sûr pour Windows, que je trouve ridicule à utiliser en tant que plate-forme serveur (et je parle de l’expérience ici, ce n’est pas juste de la haine Microsoft). La compatibilité Unix est une exigence parfaitement légitime sur tout serveur, à mon avis.

La seule vraie raison pour laquelle je peux l’éviter est la performance. Vous constaterez rapidement que l’exécution de processus externes en général est extrêmement lente. C’est lent en C, et c’est lent en PHP. Je pense que c’est la plus grande préoccupation réelle et non religieuse.

EDIT: Oh, et en ce qui concerne le problème de sécurité, il s’agit simplement de s’assurer que vous contrôlez totalement les variables transmises au système d’exploitation. C’est une préoccupation que vous devez faire lors de la communication entre les processus et les langues, par exemple lorsque vous effectuez des requêtes SQL. À mon avis, ce n’est pas une raison suffisante pour ne pas faire quelque chose, c’est juste quelque chose qui doit être pris en compte dans ce cas, comme dans tous les cas.

Si la portabilité n’est vraiment pas un problème, parce que vous construisez une solution d’entreprise qui sera toujours sur vos propres serveurs, totalement contrôlés, je vous conseille de choisir les commandes shell autant que vous le souhaitez. Il n’y a pas de problème de sécurité inhérent tant que vous faites un assainissement de base correct en utilisant escapeshellarg () et consorts.

Dans le même temps, dans mes projets, la portabilité est surtout un problème, et quand c’est le cas, j’essaye de ne pas utiliser de commandes shell – seulement quand quelque chose ne peut pas être fait en PHP (par exemple décodage / encodage MP3, ImageMagick, Opérations vidéo) ou pas raisonnablement (c.-à-d. Une solution basée sur PHP est beaucoup trop lente) utiliserai-je des commandes externes.