【问题标题】:php exec() permissions - soffice command works in terminal but not in php exec()php exec() 权限 - soffice 命令在终端中有效,但在 php exec() 中无效
【发布时间】:2020-07-08 18:29:22
【问题描述】:
<?php // BISMILLAHIRRAHMANIRRAHEEM
error_reporting(E_ALL);
ini_set("display_errors", 1);

// tried the following with soffice, soffice.com, soffice.exe, soffice.bin
// MS-DOS: soffice, soffice.com, soffice.bin all work successufully and generate the pdf
$ex = "soffice.com --headless --convert-to html \"" . getcwd() . DIRECTORY_SEPARATOR . "sources" . DIRECTORY_SEPARATOR . "test.docx\" --outdir \"" . getcwd() . DIRECTORY_SEPARATOR . "results\"";// 2>&1";

chdir("C:\Program Files\LibreOffice\program");

echo $ex . "<br />";
exec($ex, $output);
//exec("mkdir rr", $output); // generates directory
//exec("dir soff*", $output);
//exec("a.bat", $output); // doesn't generate pdf
print_r($output);
?>

您好,我正在使用带有 Windows 7、PHP 5.6.39 的 IIS。我无法通过 PHP 调用 LibreOffice 将 docx 文档转换为 pdf。如果在 MS-DOS 窗口中执行,代码示例中到屏幕的命令输出有效,但在 php 的 exec() 或 shell_exec() 中无效。该文件夹似乎具有适当的权限,因为我的上传脚本和 exec("mkdir newdir") 正在工作。 exec("dir"); 还输出上述路径的目录列表,因此 DOS 导航命令似乎也能正常工作。

我想avoid the solution 让另一个用户。不优雅。这不应该是困难的 INSHAALLAH。

不工作是指exec() 没有生成文档,也没有生成任何输出/错误,这使得调试变得困难。

感谢您的宝贵时间。

  • 更新: 经过一番摆弄,我意识到返回码是:-1073741515 谷歌结果显示它显然是文件 I/O 故障。 我下载的另一个执行类似操作的脚本也给出了相同的错误。所以要查原因。正如我之前所说,可以创建目录并上传文件,因为它具有权限。

在我发布的链接中,似乎需要创建新用户。 IIS是否有可能对该目录具有权限但没有PHP exec()

  • 在 Linux 上,它给了我错误代码 77,权限被拒绝?

【问题讨论】:

  • 使用单引号,否则\t 将产生一个制表符
  • 谢谢。我已经在需要的地方修复了它。但是,当执行dir 命令时,此代码确实会导致chdir() 中提到的路径的目录列表。
  • 您是否尝试将应用程序池标识设置为本地系统?如果它有效,那么您将应用程序池重新设置并使用进程监视器诊断权限问题
  • 我使用了默认设置中的IUSR。

标签: php apache iis permissions exec


【解决方案1】:

BISMILLAHIRRAHMANIRRAHEEM

ALHAMDOLILLAH经过一番搜索,终于找到了答案。

窗口:

我之前做了一些权限等,对于 IIS 应该是微不足道的。但最终解决问题的是this

显然需要指定 -env:UserInstallation=file:///C:\some\path,因为如果不指定不同的配置文件文件夹 (Reference),您将无法同时运行多个 LibreOffice 实例。

另外,请参阅相同的解决方案 here

在 IIS 上通过 PHP 执行程序时,Windows 的用户帐户是 IUSR 帐户。

所以,

  1. 授予 IUSR 写入(和修改?我授予完整)权限,以便能够写入 C:\inetpub\wwwroot\path 目录。
  2. 将目录更改为 soffice.com 的 LibreOffice 路径(如果在执行时提供完整路径,则不需要):
chdir("C:\\Program Files\\LibreOffice\\program");
  1. 设置 HOME 环境变量,因为 LibreOffice 需要一个可写的临时路径。 IUSR 必须对此路径具有权限。我只是重复使用wwwroot(这一步可以是可选的):
putenv("HOME=C:\\inetpub\\wwwroot\\temp");
  1. 在 PHP 中执行,类似于:
exec("\"C:\\Program Files\\LibreOffice\\program\\soffice.com\" --headless \"-env:UserInstallation=file:///C:/inetpub/wwwroot/LibreOfficeProfilePath1\" --convert-to pdf:writer_pdf_Export --outdir \"C:\\inetpub\\wwwroot\\result\" \"C:\\inetpub\\wwwroot\\source\\file.docx\"", $output, $ret);
// Displaying the command output
print_r($output);
echo "<br />\n\n<br />"; // Line breaks for view-source
echo "Return code: " . $ret;
  1. 通过删除 LibreOffice 的配置文件目录进行清理。由于您将在服务器环境中为 LibreOffice 的并发会话即时创建唯一目录,因此您也想删除它们。关注来自here的sn-p:
exec("rmdir /S /Q \"C:\\inetpub\\wwwroot\\LibreOfficeProfilePath1\"");

您可以查看自动生成此配置文件路径,例如:

// Do this before executing soffice command and pass it to -env
$profilepath = "C:/inetpub/wwwroot/LibreOfficeProfilePath" . date("YmdHis") . rand(0, 999999);
// Make sure to replace '/' with '\' when deleting
exec("rmdir /S /Q \"" . str_replace("/", "\\", $profilepath) . "\""); // Windows
exec("rm -rf \"" . str_replace("/", "\\", $profilepath) . "\"); // Linux

或者改为使用 PHP 删除包含文件的目录,如 here 所示。

LibreOffice 作为服务运行并且 PHP 请求文档转换可能是更好的解决方案,但这篇文章涉及每次需要文档转换时调用 LibreOffice 然后让它关闭。也可以使用单独的处理方法来避免等待 LibreOffice 完成转换。

Linux:

  • www-data 的类似步骤,因为这是 Linux 中 apache 的用户帐户。查看解决方案here
  • www-data 没有$HOME 目录,所以需要按照上面(3)的方式指定。
  • env 路径类似于:
\"-env:UserInstallation=file:///var/www/tmp\"

请注意file: 之后的三个/,无论是Windows 还是Linux,即使Linux 中的路径以/ 开头,或者它们可能忽略Windows 中的斜线,但在我看来似乎不一致。

INSHAALLAH 之后它就会起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多