首頁  >  文章  >  後端開發  >  PHP實作在linux上執行外部命令的方法

PHP實作在linux上執行外部命令的方法

墨辰丷
墨辰丷原創
2018-05-26 14:28:451395瀏覽

本篇主要介紹PHP實作在linux上執行外部指令的方法,有興趣的朋友參考下,希望對大家有幫助。

目錄:

一、PHP中呼叫外部指令介紹
二、關於安全性問題
三、關於逾時問題
四、關於PHP運行linux環境中命令出現的問題

#一、PHP中呼叫外部命令介紹


在PHP中呼叫外部指令,可以用,1>呼叫專門函數、2>反引號、3>popen()函數開啟進程,三種方法來實作:

#方法一:用PHP提供的專門函數(四個):

PHP提供4個專門的執行外部指令的函數:exec(), system(), passthru(), shell_exec()

##1)exec()

原型: string exec (string $command [, array &$output [, int &$return_var ] )說明: exec執行系統外部指令時不會輸出結果,而是傳回結果的最後一行。如果想要得到結果,可以使用第二個參數,讓其輸出到指定的陣列。此數組一個記錄代表輸出的一行。也就是如果輸出結果有20行,則這個陣列就有20筆記錄,所以如果需要重複輸出呼叫不同系統外部指令的結果,最好在輸出每個系統外部指令結果時清空這個陣列unset($output),以防混亂。第三個參數用來取得指令執行的狀態碼,通常執行成功都是回傳0。

<?php
  exec("dir",$output);
  print_r($output);
?>

2)system()

原型: string system ( string $command [, int &$return_var ] )

說明: system和exec的差別在於,system在執行系統外部指令時,它執行給定的指令,輸出並傳回結果。第二個參數是可選的,用來得到指令執行後的狀態碼。


<?php
system("pwd",$result);
print $result;//输出命令的结果状态码
?>



關於第二個參數結果狀態碼的簡單介紹:

如果傳回0是運行成功, 在Bash中,當錯誤發生在致命訊號時,bash會回傳128 signal number做為回傳值。

如果找不到指令,將會回傳127。

如果命令找到了,但該命令是不可執行的,將返回126。

除此之外,Bash本身會傳回最後一個指令的回傳值。

若是執行中發生錯誤,將會傳回一個非零的值。

Fatal Signal : 128 signoCan't not find command : 127Can't not execute : 126Shell script successfully executed : return the last command exit status#Fcatat during execution : return non-zero

3)passthru()

原型: void passthru (string $command [, int &$return_var ] )

說明: passthru與system的區別,passthru直接將結果輸出到遊覽器,不傳回任何值,且可以輸出二進制,例如映像資料。第二個參數可選,是狀態碼。

<?php
header("Content-type:image/gif");
passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm");
?>

4)shell_exec()

原型: string shell_exec (string $cmd )

說明: 直接執行指令$cmd

<?php
$output = shell_exec(&#39;ls -lart&#39;);
echo "<pre class="brush:php;toolbar:false">$output
"; ?>

方法二:反撇號

原型: 反撇號`(和~在同一個鍵)執行系統外部命令

#說明: 使用這種方法執行系統外部命令時,請確保shell_exec函數可用,否則是無法使用這種反撇號來執行系統外部指令的。

<?php
  echo `dir`;
?>

方法三:用popen()函數開啟進程

原型: resource popen ( string $command , string $mode )######說明: 能夠和指令進行互動。之前介紹的方法只能簡單地執行指令,卻不能與指令互動。有時須向指令輸入一些東西,如在增加系統用戶時,要呼叫su來把目前用戶換到root用戶,而su指令必須要在命令列上輸入root的密碼。這種情況下,用之前提到的方法顯然是不行的。 ######popen( )函數開啟一個進程管道來執行給定的命令,傳回一個檔案句柄,可以對它讀寫。傳回值和fopen()函數一樣,傳回一個檔案指標。除非使用的是單一的模式開啟(讀or寫),否則必須使用pclose()函數關閉。該指標可以被fgets(),fgetss(),fwrite()呼叫。出錯時,返回FALSE。 #########
<?php
error_reporting(E_ALL);
 
/* Add redirection so we can get stderr. */
$handle = popen(&#39;/path/to/executable 2>&1&#39;, &#39;r&#39;);
echo "&#39;$handle&#39;; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);
?>
###############二、關於安全性問題:############由於PHP基本上是用於WEB程式開發的,所以安全性成了人們考慮的重要面向。 ######於是PHP的設計者們為PHP加了一個門:安全模式。 ######在php.ini的設定safe_mode = On####

如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:

执行外部命令
在打开文件时有些限制
连接MySQL数据库
基于HTTP的认证

在安全模式下,只有在特定目录中的外部程序才可以被执行,对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令,或在编译PHP 是加上–with-exec-dir选项来指定,默认是/usr/local/php/bin。

当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。

三、关于超时问题

当执行命令的返回结果非常庞大时,可以需要考虑将返回结果输出至其他文件,再另行读取文件,这样可以显著提高程序执行的效率。

如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是在等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中,如:

<?php
system("/usr/local/bin/order_proc > /tmp/abc ");
?>

但我调用的DOS命令需要几分钟的时间,而且为了批处理不能简单的把结果写入文件了事,要顺序执行以下的程序

PHP设置了调用系统命令的时间限制,如果调用命令超时,虽然这个命令还是会被执行完,但PHP没有得到返回值,被终止了(最可恨的是,不显示任何错误)

修改php.ini并重启Apache以允许系统命令运行更长的时间

max_execution_time = 600

四、关于PHP运行linux环境中命令出现的问题

php一般是以apache用户身份去执行的,也可能是www用户,把apache加入到存储你文件的父文件夹属组里去,然后改该父文件夹权限为775,这样属组成员就有写的权限,而apache属于这个组就可以改写该目录下所有文件的权限。

例如:chown www:www dirName

这样dirName目录才能被php所控制

注意:改apache/php的运行用户方法不安全

另外即使文件或目录已经是www,php的安全设置也都照顾到,一些自己安装linux的命令仍然可能无法运行,例如我曾经安装的ffmpeg软件,原因就是linux的运行权限问题,即使ffmpeg有www权限设置,但由于ffmpeg所依赖的库文件是不允许www用户运行,所以php运行此程序仍然会报127或126错误,通过 ldd 命令可以查看ffmpeg命令依赖的库情况。

这个时候就必须对ffmpeg的依赖库经行设置。具体方法属于linux管理中的话题,这里不就讨论了。

以上就是本文的全部内容,希望对大家的学习有所帮助。


相关推荐:

node.js 命令行工具使用详解

node 命令方式启动修改端口步骤详解

PHP在linux上执行外部命令的方法

以上是PHP實作在linux上執行外部命令的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn