In PHP werden sowohl Shell_exec als auch EXEC -Funktionen verwendet, um externe Befehle oder Skripte auszuführen, aber sie haben einige wichtige Unterschiede in der Ausgabemittelverarbeitungs- und Ausführungsverhalten. Das Verständnis der Nutzungsszenarien und -vorteile und -Abwindungen dieser beiden Funktionen ist sehr wichtig, um einen effizienten und sicheren Code zu schreiben. In diesem Artikel wird die Unterschiede zwischen diesen beiden Funktionen sowie deren anwendbaren Szenarien und Vor- und Nachteilen in tatsächlichen Anwendungen ausführlich analysiert.
Shell_exec :
Die Funktion Shell_exec wird verwendet, um externe Befehle auszuführen und die vollständige Ausgabe zurückzugeben. Diese Funktion gibt die Standardausgabe des Befehls (STDOut) als Zeichenfolge zurück. Wenn der Befehl nicht ausgeführt wird oder es keine Ausgabe gibt, gibt er NULL zurück.
Beispiel:
<span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">'ls -l'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$output</span></span><span>;
</span></span> Exec :
Die EXEC -Funktion führt externe Befehle aus und gibt das Ausführungsergebnis zurück. Im Gegensatz zu Shell_exec kann die EXEC -Funktion die Ausgabe eines Befehls als Array zurückgeben und die letzte Zeile der Befehlsausgabe zurückgeben, mit der normalerweise der Ausführungsstatus des Befehls verarbeitet wird.
Beispiel:
<span><span><span class="hljs-variable">$output</span></span><span> = [];
</span><span><span class="hljs-variable">$return_var</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">'ls -l'</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>, </span><span><span class="hljs-variable">$return_var</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">implode</span></span><span>(</span><span><span class="hljs-string">"\n"</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$return_var</span></span><span>; </span><span><span class="hljs-comment">// Der Rückgabestatuscode des Befehls</span></span><span>
</span></span> Shell_exec :
Shell_exec gibt die Standardausgabe des gesamten Befehls als Zeichenfolge zurück. Da die gesamte Ausgabe zurückgegeben wird, ist es für Fälle geeignet, in denen die Befehlsergebnisse verarbeitet oder ausgegeben werden müssen. Es gibt jedoch keine Fehlermeldung zurück, und wenn die Befehlsausführung fehlschlägt, kann der Fehlercode nicht direkt erhalten werden.
Beispiel:
<span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">'cat non_existing_file'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$output</span></span><span> === </span><span><span class="hljs-literal">null</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Command failed."</span></span><span>;
}
</span></span> Exec :
EXEC ermöglicht es, die Standardausgabe als Array zurückzugeben, und die Befehlsausgabe kann weiter verarbeitet werden. Darüber hinaus gibt Exec den Exit -Statuscode des Befehls zurück, der sehr nützlich ist, um festzustellen, ob der Befehl erfolgreich ausgeführt wird. EXEC bietet eine stärkere Kontrolle, geeignet für die feinere granulare Verarbeitung des Staates und die Ergebnisse der Befehlsausführung.
Beispiel:
<span><span><span class="hljs-variable">$output</span></span><span> = [];
</span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">'ls non_existing_directory'</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>, </span><span><span class="hljs-variable">$status_code</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$status_code</span></span><span> !== </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Command failed with status code: <span class="hljs-subst">$status_code</span></span></span><span>";
}
</span></span>Obwohl sowohl exec als auch Shell_exec externe Befehle ausführen können, stellen sie potenzielle Sicherheitsrisiken aus, insbesondere bei der Verarbeitung von Benutzereingaben. Jede ungefilterte Benutzereingabe kann bei der Ausführung externer Befehle Befehlsinjektionsanfälligkeiten verursachen.
Befehlsinjektion verhindern :
Bei Verwendung dieser beiden Funktionen müssen Sie besonders vorsichtig mit den Benutzereingaben umgehen. Es ist am besten, Escapeshellarg und EscapeshellCMD zu verwenden, um die Benutzereingabe zu entkommen, um sicherzustellen, dass der Befehl bei der Ausführung nicht durch böswilligen Code ausgenutzt wird.
Beispiel:
<span><span><span class="hljs-variable">$user_input</span></span><span> = </span><span><span class="hljs-title function_ invoke__">escapeshellarg</span></span><span>(</span><span><span class="hljs-variable">$user_input</span></span><span>);
</span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">"grep <span class="hljs-subst">$user_input</span></span></span><span> file.txt");
</span></span>In Bezug auf die Leistung ist der Unterschied zwischen Shell_exec und EXEC nicht sehr groß, aber eine zu beachten ist, dass EXEC flexibler große Mengen an Ausgabedaten verarbeiten kann, da sie die Ausgabe pro Zeile zurückgeben kann. Die Shell_exec gibt die gesamte Ausgangszeichenfolge zurück, die bei der Verarbeitung von Big Data möglicherweise mehr Speicher verbraucht.
Shell_exec :
Geeignet für Szenarien, in denen der gesamte Befehlsausgang als Zeichenfolge erstellt und zurückgegeben werden muss.
Wenn Sie sich nur um das Ergebnis des Befehls kümmern, jedoch nicht um die Ausgabe jeder Zeile oder den Statuscode des Befehls, können Sie Shell_exec auswählen.
Beispielszenario: Holen Sie sich die vollständige Ausgabe eines Skripts oder Befehls, z. B. das Herunterladen von Webinhalten von Curl .
Exec :
Geeignet für Szenarien, in denen die Befehlsausgabe nach einer Zeile verarbeitet werden muss oder um den Exit -Status -Code des Befehls zu erhalten.
EXEC ist angemessener, wenn Sie weitere Vorgänge für die Befehlsausgabe ausführen müssen, z. B. das Überprüfen einer bestimmten Ausgabe oder beim Vergleich mehrerer Befehlsausgänge.
Beispielszenario: Führen Sie eine komplexe Folge von Befehlen oder eine Operation aus, für die Ausführungsstatuscodes zurückgegeben werden müssen.
| Funktion | Vorteil | Mangel | Anwendbare Szenarien |
|---|---|---|---|
| Shell_exec | Geben Sie die gesamte Befehlsausgabe als Zeichenfolge zurück, einfach und einfach zu bedienen | Der Exit -Status -Code wird nicht zurückgegeben, und die Ausgabe kann mehr Speicher verbrauchen, wenn er groß ist. | Nur um Befehlsergebnisse kümmern sich um Befehlsergebnisse, keine feinkörnige Ausgangsanalyse ist erforderlich |
| Geschäftsführer | Unterstützt die Rückgabe mehrerer Ausgangs- und Beenden -Status -Code, mehr Flexibilität | Es ist etwas kompliziert zu verwenden und erfordert Verarbeitungsarrays und Statuscodes | Muss die Befehlsausgabe oder Abhängigkeitsstatus -Code -Beurteilung analysieren |
Im Allgemeinen haben Shell_exec und Exec ihre eigenen Vor- und Nachteile. Welche ausgewählt wird, hängt von Ihren Bedürfnissen nach dem Befehlsausführungsergebnis ab. Wenn Sie sich nur um die vollständige Ausgabe des Befehls kümmern, können Sie Shell_exec verwenden. Wenn Sie die Ausgabezeile nach Leitung verarbeiten müssen oder den Bezug -Statuscode des Befehls überprüfen müssen, ist EXEC eine geeignetere Wahl. In der tatsächlichen Entwicklung ist es wichtig, auf die Verhinderung der Risiken der Befehlsinjektion zu achten und entsprechende Funktionen entsprechend den tatsächlichen Bedürfnissen auszuwählen.