首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >php ()权限- soffice命令在终端中工作,但在php exec()中不起作用

php ()权限- soffice命令在终端中工作,但在php exec()中不起作用
EN

Stack Overflow用户
提问于 2020-03-28 00:14:01
回答 1查看 1.1K关注 0票数 1
代码语言:javascript
复制
<?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的IIS,PHP 5.6.39。我无法通过调用LibreOffice将docx文档转换为pdf。如果在MS窗口中执行,则代码示例中屏幕上的命令输出可以工作,但在php的exec()或shell_exec()中不工作。该文件夹似乎具有适当的权限,因为我的上载脚本和exec("mkdir newdir")正在工作。exec("dir");还输出上述路径的目录列表,因此DOS导航命令似乎也能工作。

我想在避免使用解决方案上做另一个用户。不优雅。这不应该是困难的安沙阿拉。

如果不工作,我的意思是exec()既不生成文档,也不生成输出/错误,这给调试带来了困难。

谢谢您抽时间见我。

  • 更新:经过一些修改后,我意识到返回代码是:-1073741515 Google结果显示它显然是文件I/O失败。我下载的另一个脚本做了类似的事情,也给出了同样的错误。所以调查原因。正如我前面所说,目录和文件可以上传,因为它有权限。

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

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

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-21 03:07:51

比斯米拉

ALHAMDOLILLAH经过多次搜索,终于找到了答案。

Windows:

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

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

另外,请参见相同的解决方案这里

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

所以,

  1. 给IUSR写(修改?)我给出了完整的)权限,以便能够写入C:\inetpub\wwwroot\path目录。
  2. soffice.com目录更改为soffice.com路径(如果在执行时提供完整路径,则不需要):
代码语言:javascript
复制
chdir("C:\\Program Files\\LibreOffice\\program");
  1. 设置主环境变量,因为LibreOffice需要一个可写的临时路径。IUSR必须具有此路径的权限。我只是重复使用wwwroot (这个步骤可以是可选的):
代码语言:javascript
复制
putenv("HOME=C:\\inetpub\\wwwroot\\temp");
  1. 在PHP中执行,类似于:
代码语言:javascript
复制
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并发会话创建唯一的目录,所以您也希望删除它们。下面是来自这里的片段
代码语言:javascript
复制
exec("rmdir /S /Q \"C:\\inetpub\\wwwroot\\LibreOfficeProfilePath1\"");

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

代码语言:javascript
复制
// 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删除包含文件的目录,如这里所示。

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

Linux:

  • 对于www-data也有类似的步骤,因为这是Linux中apache的用户帐户。请参阅解决方案这里
  • www-数据没有$HOME目录,因此需要按照上文(3)中的指示进行指定。
  • env路径将类似于:
代码语言:javascript
复制
\"-env:UserInstallation=file:///var/www/tmp\"

请注意,尽管Linux中的路径以/开头,或者可能忽略了file:中的斜杠,但在我看来,不管是Windows还是Linux,都需要注意三个file:之后的路径。

安沙安拉,在那之后它会起作用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60895795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档