php命令執行函數
首先先要給大家介紹PHP執行linux系統命令的幾個基本函數。
system函數
說明:執行外部程序並顯示輸出資料。
語法:string system(string command, int [return_var]);
返回值: 字元串
詳細介紹:
本函數就像是 C 語中的函數 system(),用來執行指令,並輸出結果。若是 return_var 參數存在,則執行 command 之後的狀態會填入 return_var 中。同樣值得注意的是若需要處理用戶輸入的資料,而又要防止用戶耍花招破解系統,則可以使用 EscapeShellCmd()。若 PHP 以模塊式的執行,本函數會在每一行輸出後自動更新 Web 伺服器的輸出緩沖暫存區。若需要完整的返回字元串,且不想經過不必要的其它中間的輸出界面,可以使用 PassThru()。
實例代碼:
< ?php
$last_line = system('ls', $retval);
echo 'Last line of the output: ' . $last_line;
echo '<hr/>Return value: ' . $retval;
?>
exec函數
說明:執行外部程序。
語法:string exec(string command, string [array], int [return_var]);
返回值: 字元串
詳細介紹:
本函數執行輸入 command 的外部程序或外部指令。它的返回字元串只是外部程序執行後返回的最後一行;若需要完整的返回字元串,可以使用 PassThru() 這個函數。
要是參數 array 存在,command 會將 array 加到參數中執行,若不欲 array 被處理,可以在執行 exec() 之前呼叫 unset()。若是 return_var 跟 array 二個參數都存在,則執行 command 之後的狀態會填入 return_var 中。
值得注意的是若需要處理使用者輸入的資料,而又要防止使用者耍花招破解系統,則可以使用 EscapeShellCmd()。
實例代碼:
< ?php
echo exec('whoami');
?>
popen函數
說明:打開文件。
語法:int popen(string command, string mode);
返回值: 整數
詳細介紹:
本函數執行指令開檔,而該文件是用管道方式處理的文件。用本函數打開的文件只能是單向的 (只能讀或只能寫),而且一定要用 pclose() 關閉。在文件操作上可使用 fgets()、fgetss() 與 fputs()。若是開檔發生錯誤,返回 false 值。
實例代碼:
< ?
$fp = popen( "/bin/ls", "r" );
?>
通過上述函數,PHP可以執行linux系統的shell命令。
2. PHP中的文件系統函數(一)
從這篇文章開始,我們將學習一系列的 PHP 文件系統相關函數。其實這些函數中,有很多都是我們經常用到的,大家並不需要刻意地去記住它們,只要知道有這么個東西,在使用的時候記得來查文檔就可以了。
文件路徑相關的函數往往在一些框架中會比較常見,而且多會配合 __FILE__ 、 __DIR__ 之類的魔術常量使用。
basename() 函數是獲得路徑中的文件名,它有兩個參數,第一個是文件的路徑,第二個是過濾掉的內容,比如第一條測試語句我們過濾掉文件的後綴名。
dirname() 返回的是路徑中的路徑部分,也就是不包含文件名的那部分內容,和 basename() 正好是相反的功能。
pathinfo() 函數用於以數組的形式返迴路徑中的信息,從結果來看,我們可以看到文件的 dirname 部分,basename 部分,以及文件的擴展名 extension 和不包含擴展名的 filename 內容。
realpath() 返回的是規范化的絕對路徑名,它擴展所有的符號連接並且處理輸入的路徑中的 ./ 、 ../ 以及多餘的 / ,返回的內容是標准規范的絕對路徑。
接下來,我們學習一些修改文件相關屬性的函數,主要就是在 Linux 系統環境中的文件許可權信息的操作。
當然,首先我們得創建一個文件。和 Linux 中的命令是非常類似的。
touch() 函數除了給出要創建的文件名之外,還有兩個可選參數可以指定文件的創建時間及訪問時間,不給參數的話默認就是當前時間。這個文件名可以是相對或絕對路徑中有許可權的目錄,並在該目錄下創建一個空的文件。
通過 fileowner() 函數,我們可以獲得某個文件所屬的用戶,默認情況下我們的用戶是當前運行 PHP 腳本的用戶,也就是系統目前的登錄用戶。在這里,我們使用 chown() 函數,將用戶改為 www 用戶。clearstatcache() 是用於清理文件系統的緩存信息,如果不清理一下的話,fileowner() 返回的依然還是之前的用戶信息。
同理,使用 filegroup() 函數獲得文件的屬組信息,chgrp() 用於修改文件的屬組。fileperms() 用於返迴文件的許可權信息,它返回的是數字模式的文件訪問許可權,這里我們使用 sprintf() 格式化結果後獲得我們常用的 Linux 系統許可權格式。chmod() 函數用於修改文件的許可權,它的許可權參數是三個 8 進制數據組成的數字,也就是代表 Linux 系統中的 1 、2 、4 和它們的組合,所以我們需要在前面再加上一個 0 用於確保操作能夠正常執行。關於系統文件許可權的知識大家需要認真學習 Linux 系統中相關的內容。
注意,上述函數如果在命令行中運行失敗,大部分原因是沒有許可權,可以使用 sudo 進行測試。在 fastcgi 中運行時,就更加需要注意許可權問題,僅在我們伺服器可以操作的目錄中進行安全的文件許可權修改。
stat() 函數可以獲取到指定文件的所有屬性信息,在這里我們可以看到文件的 uid 、 gid 、 ctime 、 mtime 等信息。
在 Linux 系統中,有軟連接和硬連接的相關知識。其實軟連接就像是 Windows 中的快捷方式,而硬連接相關於復制了一份數據。在 PHP 中,也為我們提供了創建軟硬連接以及相關的一些操作。
使用 link() 函數創建的就是一個指定文件的硬連接文件,而使用 symlink() 創建的則是一個軟連接文件。相對來說,我們使用軟連接的場景會更多一些。lstat() 就和 stat() 函數的功能一樣,查看文件的各種屬性信息,不過 lstat() 函數針對的是軟硬連接文件。
同樣地,我們也可以修改軟硬連接的用戶和用戶組信息,不過它們的信息不能通過 fileowner() 或 filegroup() 查看。因為它們是連接文件,本身還是和原始文件綁定在一起的,使用 fileowner() 這類的函數查看到的依然是原始文件的信息。我們可以在系統環境中使用 ls -l 查看連接文件的用戶和用戶組信息是否修改成功。
今天的內容比較簡單,而且修改許可權的操作也並不常用。不過對於系統安全來,它們還是非常有用的,比如對於上傳來說,我們要預防上傳可執行文件的話,就可以通過修改文件的許可權來讓文件無法直接運行,從而起到安全保護的作用。另外,目錄路徑相關的操作也是一些框架的基礎,幾乎所有框架的入口或者說是 Composer 的入口,都會見到 dirname() 以及 basename() 之類函數的身影。
測試代碼:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/6.PHP中的文件系統函數(一).php
參考文檔:
https://www.php.net/manual/zh/ref.filesystem.php
3. php eval怎樣執行系統命令
eval — 把字元串作為PHP代碼執行
說明
mixedeval( string $code_str )
把字元串code_str作為PHP代碼執行。 除了其他,該函數能夠執行儲存於資料庫文本欄位內的PHP代碼。
使用eval()時需注意幾個因素:注意字元必須是有效的PHP代碼,包括結尾的分號,以不至於解釋器在eval()之後退出。並且正確地轉義code_str中的東西。你可以使用一個PHP閉合標簽來混合輸出HTML和PHP代碼。
同時需注意eval中的變數會被保留在之後的主腳本中。
參數
code_str需要被執行的字元串code_str不能包含 PHP Opening tags。
return語句會立即中止當前字元串的執行。
返回值
eval()返回NULL,除非在執行的代碼中return了一個值,函數返回該值。 如果在執行的代碼中有一個解析錯誤,eval()返回FALSE,之後的代碼將正常執行。無法使用 set_error_handler() 捕獲eval()中的解析錯誤。
範例
Example #1eval()例子 - 簡單的文本合並
<?php
$string = 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo $str. "\n";
eval("\$str = \"$str\";");
echo $str. "\n";
?>
以上常式會輸出:
This is a $string with my $name in it.This is a cup with my coffee in it.
Note: 因為是一個語言構造器而不是一個函數,不能被 可變函數 調用。
Tip和直接將結果輸出到瀏覽器一樣,可使用輸出控制函數來捕獲當前函數的輸出,然後(例如)保存到一個 string 中。
Note:
如果在執行的代碼中產生了一個致命的錯誤(fatal error),整個腳本會退出。
Linux 中
shell中的eval命令將會首先掃描命令行進行所有的替換,然後再執行命令。該命令使用於那些一次掃描無法實現其功能的變數。該命令對變數進行兩次掃描。這些需要進行兩次掃描的變數有時候被稱為復雜變數。
例如
$:cat ext
count=3
cmd=echo
cmd="$cmd \$$count"
ext 11 22 33
此時cmd=" echo $3"
eval $cmd 等價於 "echo 33 "
4. 怎麼用php命令執行php代碼
PHP執行命令的四種方法
方法一:使用exec函數執行系統外部命令
原型:function exec(string $command,array[optional] $output,int[optional]
$return_value)
<?
exec("dir",$outPut);
print_r($outPut);
?>
說明:列出和PHP執行文件同級目錄下的所有目錄及文件信息。
知識點:exec執行系統外部命令時不會輸出結果,而是返回結果的最後一行,如果你想得到結果你可以使用第二個參數,讓其輸出到指定的數組,此數組一個記錄代表輸出的一行,即如果輸出結果有20行,則這個數組就有20條記錄,所以如果你需要反復輸出調用不同系統外部命令的結果,你最好在輸出每一條系統外部命令結果時清空這個數組,以防混亂。第三個參數用來取得命令執行的狀態碼,通常執行成功都是返回0。
方法二:使用system函數執行系統外部命令
原型:function system(string $command,int[optional] $return_value)
1
2
3
<?
system("dir");
?>
知識點:system和exec的區別在於system在執行系統外部命令時,直接將結果輸出到游覽器,如果執行命令成功則返回true,否則返回false。第二個參數與exec第三個參數含義一樣。
方法三:使用函數passthru執行系統外部命令
原型:function passthru(string $command,int[optional] $return_value)
知識點:passthru與system的區別,passthru直接將結果輸出到游覽器,不返回任何值,且其可以輸出二進制,比如圖像數據。
方法四:反撇號`(和~在同一個鍵)執行系統外部命令
1
2
3
<?
echo `dir`;
?>
知識點:在使用這種方法執行系統外部命令時,你要確保shell_exec函數可用,否則是無法使用這種反撇號執行系統外部命令的。
5. 如何配置伺服器的php,使得能成功運行exec函數
如果是命令行使用的話,直接運行即可,如果是apache使用的話,需要重啟apache,如果是nginx配合使用的話,需要重啟php-fpm,exec函數執行命令並不需要安全目錄,只要有執行許可權就可以執行。