PHP exec() 在 Windows 上的 UNC 路徑
我的環境是 Windows Server 2012 R2、IIS 8、Active Directory 和文件共享。IIS、AD 和文件共享都是獨立的 VM。
我在 IIS 中設置了一個網站 www.example.com。應用程序池標識設置為 AD 使用者
IUSR_example
,該使用者對包含站點文件的文件夾具有“完全控制”權限。站點文件位於文件共享上,IIS 通過 UNC 路徑引用該文件共享。通常,該站點的工作原理是它可以提供 PHP、ASP.Net 和 ASP Classic 頁面,並且程式碼甚至可以創建新文件。
但是,我遇到了一個似乎特定於 PHP 的問題
exec()
。我試過打電話給whoami
,dir
和ffmpeg
,但我沒有從他們那裡得到任何回報。使用 Sysinternals Procmon 我已經確認執行檔永遠不會啟動。奇怪的是,我可以使用 ASP Classic(使用 )進行完全相同的呼叫
WScript.Shell
,而且效果很好。exec()
當腳本不在 UNC 路徑上執行時, 我也可以讓 PHP正常工作。這是我嘗試/發現的:
- 使用 ASP 時,procmon 報告 w3wp.exe 生成一個 cmd.exe 程序,該程序又生成 conhost.exe 和(例如)ffmpeg.exe。ffmpeg 的輸出文件成功出現。
- 使用 PHP 時,procmon 報告 w3wp.exe 生成一個 php-cgi.exe 程序,該程序又創建一個 cmd.exe 和一個 conhost.exe。ffmpeg.exe 的執行緒永遠不會出現。
- cmd.exe 使用如下所示的命令行呼叫:
cmd.exe /c ""--the command to be executed--""
- 對於 ASP Classic 和 PHP,cmd.exe 程序的命令行完全相同。
- 在 Procmon 中,使用者總是被報告為
IUSR_example
- 我試過添加
2>&1
到命令的末尾- 我已經嘗試將 IUSR 賦予“替換程序級令牌”的權利
- 我嘗試關閉 FastCGI 模擬並在“程序模型”>“高級設置”下的“NamedPipe”和“TCP”之間切換
- PHP 錯誤日誌中沒有錯誤
- 任何 Windows 事件日誌中都沒有錯誤
請注意,這並不特定於 ffmpeg。的任何其他使用
exec()
也會失敗。另外,我不希望WScript.Shell
在 PHP 中使用,因為最終我們將使用依賴exec()
.我該如何進一步解決這個問題?
正如使用者“pajoye”在 bugs.php.net 上所建議的那樣,使用允許
proc_open()
我成功執行命令。這反過來又讓我可以使用 procmon 來發現方式exec()
和proc_open()
工作之間的區別。長話短說,當 PHP 腳本位於網路共享上時,我將其稱為在 Windows 上執行的 PHP 的核心錯誤。以下是關鍵細節:
exec()
預設目前工作目錄為 PHP 腳本的路徑,在我的例子中是一個 UNC 路徑。cmd.exe
不允許您將 UNC 路徑作為目前工作目錄,並cmd.exe
聲稱它將恢復到 Windows 文件夾。- 儘管
cmd.exe
繼續執行並conhost.exe
生成,但原始工作目錄仍然會導致某種問題,並且從未啟動所需的執行檔。所以一個簡單的解決方法是
chdir()
在呼叫exec()
. 但是,有很多 WordPress 外掛依賴於exec()
,所以我認為exec()
應該不知道 PHP 腳本是否在共享上執行。我會詢問是否可以在未來的版本中包含對此的修復。