php shell_exec 不使用木偶操作
php shell_exec not working with puppeteer
- 网络服务器:nginx
- PHP 框架:Laravel 5.5
- 生成 PDF 的库:puppeteer
所以我想做的是,当用户点击 下载 按钮时,服务器将执行以下操作:
- 构造一个HTML文件,内容为
- 运行以下代码
Laravel 控制器
$shell_output = shell_exec('`which node` ' . base_path('bin/export.js') . ' ' . $html_file . ' ' . $pdf_file . ' A4');
print($shell_output); // <------- empty output
$workable_output = shell_exec('echo `which node`');
print($shell_output); // <------- THIS IS SHOWING "/usr/local/bin/node"
export.js内容
const puppeteer = require('puppeteer');
var filename = process.argv[2];
var output = process.argv[3];
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1000, height: 1415 });
await page.goto('file://' + filename, { waitUntil: 'networkidle2' });
await page.emulateMedia('print');
await page.pdf({
path: output,
format: 'A4',
printBackground: true,
landscape: false,
margin: {
top: '60px',
right: '20px',
bottom: '30px',
left: '20px'
}
});
await browser.close();
})();
但问题是,没有生成PDF文件,$shell_output
也是空的
然后我在终端中尝试 运行 和 shell 命令,它运行良好。即
$ `which node` export.js content.html content.pdf A4
同样,我尝试创建一个 php 文件,并使用 php-cli 创建 运行,即
$ php test.php
test.php内容如下
<?php
$shell_output = shell_exec('env DEBUG="puppeteer:*" `which node` export.js content.html content.pdf A4');
echo $shell_output;
服务器日志
/var/log/nginx/error.log
2018/03/13 10:37:05 [error] 13017#13017: send() failed (111: Connection refused) while resolving, resolver: 127.0.0.1:53
P/S:我托管在 AWS EC2 中。当我在本地机器上 运行 时没有问题。
更新于 2018-03-14 14:55PM (UTC+8)
我试图将代码放入 Laravel
中的测试文件夹
./tests/Unit/ExampleTest.php
$shell_output = shell_exec('`which node` ' . base_path('bin/export.js') . ' ' . $html_file . ' ' . $pdf_file . ' A4');
和 运行 与 ubuntu 用户,有效
ubuntu@ip-xxx-xx-xx-xx:/var/www/project$ ./vendor/phpunit/phpunit/phpunit --filter ExampleTest
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.
.
. 2 / 2 (100%)
Time: 4.82 seconds, Memory: 14.00MB
但是,当我尝试 运行 使用 www-data 用户时,它失败了
ubuntu@ip-xxx-xx-xx-xx:/var/www/project$ sudo -u www-data ./vendor/phpunit/phpunit/phpunit --filter ExampleTest
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.
.(node:7991) UnhandledPromiseRejectionWarning: Error: spawn EACCES
at ChildProcess.spawn (internal/child_process.js:330:11)
at Object.exports.spawn (child_process.js:500:9)
at Function.launch (/var/www/project/node_modules/puppeteer/lib/Launcher.js:106:40)
at <anonymous>
(node:7991) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:7991) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
. 2 / 2 (100%)
Time: 276 ms, Memory: 14.00MB
OK (2 tests, 2 assertions)
知道问题出在哪里吗?
我找到了问题,它是由 chrome
可执行文件本身引起的
解决者
$ chmod 777 /var/www/project/node_modules/puppeteer/.local-chromium/linux-536395/chrome-linux/*
从 GitHub issue 找到这个。
- 网络服务器:nginx
- PHP 框架:Laravel 5.5
- 生成 PDF 的库:puppeteer
所以我想做的是,当用户点击 下载 按钮时,服务器将执行以下操作:
- 构造一个HTML文件,内容为
- 运行以下代码
Laravel 控制器
$shell_output = shell_exec('`which node` ' . base_path('bin/export.js') . ' ' . $html_file . ' ' . $pdf_file . ' A4');
print($shell_output); // <------- empty output
$workable_output = shell_exec('echo `which node`');
print($shell_output); // <------- THIS IS SHOWING "/usr/local/bin/node"
export.js内容
const puppeteer = require('puppeteer');
var filename = process.argv[2];
var output = process.argv[3];
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1000, height: 1415 });
await page.goto('file://' + filename, { waitUntil: 'networkidle2' });
await page.emulateMedia('print');
await page.pdf({
path: output,
format: 'A4',
printBackground: true,
landscape: false,
margin: {
top: '60px',
right: '20px',
bottom: '30px',
left: '20px'
}
});
await browser.close();
})();
但问题是,没有生成PDF文件,$shell_output
也是空的
然后我在终端中尝试 运行 和 shell 命令,它运行良好。即
$ `which node` export.js content.html content.pdf A4
同样,我尝试创建一个 php 文件,并使用 php-cli 创建 运行,即
$ php test.php
test.php内容如下
<?php
$shell_output = shell_exec('env DEBUG="puppeteer:*" `which node` export.js content.html content.pdf A4');
echo $shell_output;
服务器日志
/var/log/nginx/error.log
2018/03/13 10:37:05 [error] 13017#13017: send() failed (111: Connection refused) while resolving, resolver: 127.0.0.1:53
P/S:我托管在 AWS EC2 中。当我在本地机器上 运行 时没有问题。
更新于 2018-03-14 14:55PM (UTC+8)
我试图将代码放入 Laravel
中的测试文件夹./tests/Unit/ExampleTest.php
$shell_output = shell_exec('`which node` ' . base_path('bin/export.js') . ' ' . $html_file . ' ' . $pdf_file . ' A4');
和 运行 与 ubuntu 用户,有效
ubuntu@ip-xxx-xx-xx-xx:/var/www/project$ ./vendor/phpunit/phpunit/phpunit --filter ExampleTest
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.
.
. 2 / 2 (100%)
Time: 4.82 seconds, Memory: 14.00MB
但是,当我尝试 运行 使用 www-data 用户时,它失败了
ubuntu@ip-xxx-xx-xx-xx:/var/www/project$ sudo -u www-data ./vendor/phpunit/phpunit/phpunit --filter ExampleTest
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.
.(node:7991) UnhandledPromiseRejectionWarning: Error: spawn EACCES
at ChildProcess.spawn (internal/child_process.js:330:11)
at Object.exports.spawn (child_process.js:500:9)
at Function.launch (/var/www/project/node_modules/puppeteer/lib/Launcher.js:106:40)
at <anonymous>
(node:7991) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:7991) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
. 2 / 2 (100%)
Time: 276 ms, Memory: 14.00MB
OK (2 tests, 2 assertions)
知道问题出在哪里吗?
我找到了问题,它是由 chrome
可执行文件本身引起的
解决者
$ chmod 777 /var/www/project/node_modules/puppeteer/.local-chromium/linux-536395/chrome-linux/*
从 GitHub issue 找到这个。