Closed Bilna75 closed 8 years ago
Sorry, I don't use Windows, so I can't really help. Other Windows users seem to have no problem with the library. You will have to play around with proc_open() yourself to find out, what's wrong. I'd try to build a simple PHP script and use more and more complex shell commands with proc_open().
Hope this helps.
There are a lot of issues with php proc_open
on windows. See:
https://bugs.php.net/bug.php?id=51800
https://bugs.php.net/bug.php?id=60120
https://bugs.php.net/bug.php?id=65650
One workaround is to run the command yourself using exec()
.
However, as far as I know, there's no way to get the command woithout actually running it. I've created a pull request that should address this issue.
If we wanted to fix this, we should do so in the underlying https://github.com/mikehaertl/php-shellcommand. But I'm hesitant to do so. proc_open()
gives you full access to return value, STDIN and STDOUT. You can't do that with exec()
.
The problem seems only to happen with long output (longer than 4096 bytes) on windows.. So I wonder, if adding the quiet
option doesn't fix the problem.
The problem seems only to happen with long output (longer than 4096 bytes) on windows.. So I wonder, if adding the quiet option doesn't fix the problem.
Unfortunately, this is not quite so simple. I've tested on two machines, a i7 3.4Ghz desktop and a dual Xeon E5-2695 server, both running the same exact OS and IIS 7.5)
On the desktop, the php script times-out when converting a 233Kb html file + 295K worth of images to a 757kb pdf. Increasing the time-out time (to hours) on php doesn't fix the problem. The strange thing is that while the script is running, the PDF in the temp directory is empty but immidiately after timing out, the PDF gets created correctly in the temp directory. I can't explain this behaviour.
Things get even weirder in the server. Sometimes the above script works without any problem, other times it behaves like the desktop. It's totally unreliable.
If we wanted to fix this, we should do so in the underlying https://github.com/mikehaertl/php- shellcommand. But I'm hesitant to do so. proc_open() gives you full access to return value, STDIN and STDOUT.
I agree. proc_open
gives you more control over the process and works great on *nix environment. However, unless you're planning to add further features in error digest, as your script stands right now, there's no real difference in using exec
or proc_open
. Since you're not really digesting stdErr anyways, just using the exit code, passing a third argument to exec
gets you the same result
What I propose is either:
exec
or proc_open
(through setOption). Maybe have a sensible default (in windows OS it defaults to exec
all the others get proc_open
). This gives you more flexibility to future features additions in terms of error handling and logging, but increases code complexity and is harder to maintain and test.proc_open
altogether in favor of exec
. Simpler code, easier to maintain, but you might lose the possibility to add complex error handling in the future. Since you're not really digesting stdErr anyways, just using the exit code, passing a third argument to exec gets you the same result
It is used. See https://github.com/mikehaertl/phpwkhtmltopdf/blob/master/src/Pdf.php#L248.
Things get even weirder in the server. Sometimes the above script works without any problem, other times it behaves like the desktop. It's totally unreliable.
So... there's an issue anyway, even on the shell? How can we know, that this is really related to proc_open()
then? This sounds like a different problem to me.
I still recommend to try the quiet
option with wkhtmltopdf
. This should at least workaround the above proc_open()
issues.
So... there's an issue anyway, even on the shell? How can we know, that this is really related to proc_open() then? This sounds like a different problem to me.
No, I might have not explained the issue clearly.
I created the following script (gist) and tested it in both my Desktop and my Home Server.
Results:
(produced phpWkHtmlToPdf command)
wkhtmltopdf --no-outline --enable-local-file-access --encoding "UTF-8" --disable-smart-shrinking --margin-left "0" --margin-right "0" --margin-top "45mm" --margin-bottom "25mm" --header-html "F:\tmp\wktest\inc\header.html" --footer-html "F:\tmp\wktest\inc\footer.html" "htmlfile.html" "F:\tmp\tmpEAAD.tmp.pdf"
I changed mikehaertl\shellcommand\Command
execute()
method as seen in this gist, to use exec instead of proc_open().
Results
Since you're not really digesting stdErr anyways, just using the exit code, passing a third argument to exec gets you the same result
It is used. See https://github.com/mikehaertl/phpwkhtmltopdf/blob/master/src/Pdf.php#L248.
Yes, I know it's used but it's not being parsed. wkHtmlToPdf library writes progress to STDERR: see https://code.google.com/p/wkhtmltopdf/issues/detail?id=825. This is by deisgn since they support dumping the actual PDF to STDOUT.
So what I meant was: since your library does not really use STDOUT for anything, and since wkHtmlToPdf dumps the progress to STDERR, regardless of it having error messages, using proc_open or exec is the same thing.
Why?
Because you can pipe STDERR to STDOUT (and STDOUT to Nul) with exec and then read from it which, in pratical terms it's the same as reading from STDERR with proc_open.
public function execute()
{
$command = $this->getExecCommand();
if (!$command) {
return false;
}
$command = $command . ' 2>&1';
$lastLine = exec($command, $otp, $this->_exitCode);
$this->_stdErr = implode('', $otp);
if ($this->_exitCode!==0) {
$this->_error = $lastLine ? $lastLine : "Failed without error message: $command";
return false;
}
$this->_executed = true;
return true;
}
@tivie I've now update the php-shellcommand. You should be able to do this now:
<?php
use mikehaertl\wkhtmlto\Pdf;
$pdf = new Pdf([
'commandOptions' => [
'useExec' => true,
],
]);
...
Can you please help testing?
@mikehaertl Thanks Michael. I will be testing it and post the results soon.
@mikehaertl The new commandOption is working good (passed all my tests). However, error reporting is lacking. I've fixed this issue in this pull request. Michael, if you don't mind, please have a look.
@mikehaertl I've created a command exec library that address inconsistencies between linux and windows environments. You might wanna consider using it to build your lib commands.
https://github.com/tivie/command
If you wish, I can help you implement this.
@tivie That looks nice. Maybe something to consider for a 3.0 release. On the other hand, from looking at the code I couldn't actually find a big difference in the core part (proc_open()
). If you have some hints how to improve my php-shellcommand, I'm happy to include those changes. Your class makes sense for more advanced scenarios (method chaining, etc.). But our use case here is pretty simple. And I still believe in my own php-shellcommand implemenation ;).
BTW you may also hit this problem: https://github.com/mikehaertl/php-shellcommand/issues/6. Maybe worth adding to your class, too?
@mikehaertl thanks.
The only big difference is in the automatic selection of proc_open
or exec
based on OS (in windows it uses exec
, otherwise uses proc_open
.)
If you have some hints how to improve my php-shellcommand, I'm happy to include those changes
Maybe add this:
exec
in windows environmentsThose two would be awesome.
BTW you may also hit this problem: mikehaertl/php-shellcommand#6. Maybe worth adding to your class, too? Yeah, that's worth adding as an opt-in option when dealing with long outputs. Thanks for the suggestion. =)
use the bypass_shell options of proc_open to make it works on windows
Hi, I'm currently trying to use your wkhtmltopdf but I cannot get passed a Warning call saying :
Warning: proc_open() [function.proc-open]: CreateProcess failed, error code - 87 in Path/To/WkHtmlToPdf.php on line 325
I tried with a basic code given in the tutorial but it doesn't work.
$pdf = new WkHtmlToPdf; $pdf->addPage('http://google.com'); $pdf->send();
The error code 87 stands for invalid parameter. Anyone can help me ?
Thank you