PHP, PHPExcel and DOMPDF woes



  • OK, so I have a problem in PHP and I spent 4 hours debugging this crap and I'm out of ideas. I'd do what my coworkers do and ask Stack Overflow but I doubt that would be productive either.

    So here's the situation: I collect some data from the database, and render a nice HTML table out of it. So far so good. Then I use PHPExcel to export that to an Excel spreadsheet. All is still well.

    Then the boss wanted PDF export - which is fine, PHPExcel talks to DOMPDF, and can output a nice enough PDF file from it. And this all worked until this morning.

    Last night something changed, and since all this is outside version control I don't know what changed, but something changed. The HTML still works, the Excel still works, but the PDF doesn't.

    More specifically, the PDF generation step works just fine if I have it output to a file on the local filesystem. But if I have it output to PHP's regular output, PHP (and Apache) will send the first 8KB then crash completely.

    Similarly, if I have it put the content to the local filesystem then try to serve the contents of it back (e.g. through readfile), it crashes.

    I've done all the steps I could think of - checking memory use before it flails (43MB used, 128M is the memory limit but raising it to 1G didn't help), it's not hitting the 30 second limit or anything either.

    I tried closing all output buffers before, then doing it, closing them all and then opening one fresh just for purpose, no dice.

    There are three servers I tried this on, two of which it fails on with reproducible symptoms, the third it works fine on - yet all three are Windows boxes, all three have Apache 2.4.9 / PHP 5.5.12 (yes yes I know). The only thing I can think of is that there is something in the hundreds of other included files that are somehow different between the third server and the other two but none of the PDF generation code has been touched, meaning that whatever changed to cause it to crash is somewhere else in the code base but I have absolutely NFI where it might be.

    I have no idea what changed in the last day to cause it to crash either. So, um, help? Lemme know if there's anything that would be useful in diagnosing this, I'll provide what I can. Thanks 😄

    Apache 2.4.9 / PHP 5.5.12 / PHPExcel 1.8.1 / DOMPDF 0.6.1



  • This may sound dumb, but can't you search by last changed date and zero in on files that have changed?

    Also, is it possible you absolutely don't have an older version somewhere, even in a zip file on a shared drive? It would help if you can determine that something has DEFINITELY changed in the code, as opposed to a Windows update or some external resource or licence expiration date or whatever.

    (BTW after that, try rolling the clock back two days)



  • I'll have to try that tomorrow, don't know why that didn't occur to me. There was one file that changed but I reverted that back to an older version (that's the one that's got like 6 versions and has since been harmonised) but that didn't appear to help 😦



  • @Arantor said:

    But if I have it output to PHP's regular output, PHP (and Apache) will send the first 8KB then crash completely.

    What if you send something else along that output? Some other file (bigger than 8KB), just to double check it isn't something to do with how big a thing you are trying to give.



  • I tried sending just 'hello world' down that (it still sent it and still crashed) as well as another file, it didn't matter - anything going down that pipe in that branch caused it to crash.



  • OK, I've just been bitten by changing configs causing limits on the size of things sent out so figured that if it worked then you could eliminate that as a possibility.


  • :belt_onion:

    What kind of crash? Memory address dumped to screen 0x45fe338a style?

    No error log file either?



  • You could at least upgrade to 5.5.26...there is quite a few seg faults that were fixed between .12 and .26
    Assuming you mean seg fault when you say crash.

    Also remembering how DOMPDF works...make sure you aren't hitting php memory limits.



  • You have one box that works and two that don't.

    Having one working as a baseline is priceless. If it's a VM, snapshot and back up that machine!

    Check your file at each step:

    1. Render the HTML on each server. Compare the HTML output of the working server to the two non-working servers to ensure it's identical. If it's not, focus here. If it is, go to step 2.
    2. PHPExcel export. Again, compare output of working server to the two non-working servers to ensure it's identical. If it's not, focus here. If it is, go to step 3.
    3. Now check the components that convert the Excel to PDF to see if any of those changed or are different as compared to the baseline working server. Thoroughly investigate any differences.

    The above will not solve your problem, but it will help you to narrow your focus so you can find the problem - especially if it's something that changed a few steps back before the PDF export process that's tripping things up later.

    Let us know how it goes, and good luck! :)


  • :belt_onion:

    @Arantor said:

    and since all this is outside version control

    No idea what the problem is, but perhaps you can use this fustercluck as an example of why you need VCS? You might be able to get something out of it :)


  • :belt_onion:

    seg faults in php may or may not even be related to the PHP code in any way.

    That's php5.5 on apache 2.4.9 segfaulting due to xcache for one guy and on a coded debug printout for another.

    Also, https://bugs.php.net/bugs-generating-backtrace.php might help with finding the cause of the segfault.



  • I know PHP 5.3.8 segfaults if any included file is an exact multiple of 4KB, but it is really weird that one machine running the same versions as the others doesn't crash.

    As for getting VCS in play, this is happening at present where I'm bringing the code together to get it into one central repository... This just supports the decision...

    I will look at getting a backtrace, that will be useful :) getting one on Windows has always been more interesting though...


  • :belt_onion:

    @Arantor said:

    As for getting VCS in play, this is happening at present where I'm bringing the code together to get it into one central repository... This just supports the decision...

    Paging @Yamikuronue and the cupcake thread



  • I have not used PHPExcel, although it is installed on my "inherited" server. But from what you say, that's not the issue. I can recommend a very good file comparison program that has network drive, ftp, web dav support:

    Tree Compare then use winmerge as your compare engine.

    the thing about treecomp is you just give it the directories, and the engine and UI do the rest.

    Sometime it is an advantage to have a windows platform.



  • Thanks for the recommendation, though I just RDP'd into the server, used Windows Explorer to find all files modified in the last month, and nothing relevant showed up.

    This is now suddenly lower priority so I'll worry about it later next week before I take two weeks' leave if I have time. Meanwhile I need to add more to the thread in the Lounge... If ever you doubted your job, just read that thread ;)



  • I do not know your level of experience with PHP, but log everything error_reporting(-1) should be the first line of every PHP file, include, class, HTML or other script that has embedded PHP commands because if it not explicitly there it will default to whatever is in your ini file.

    To me "code base" means all configuration files and dependencies. Two of the servers may have "updated", somebody may have had a :wtf: moment with "a" configuration. And as has been stated, take a complete snapshot of the "working" server whilst you can. Version Control Systems or not, I always do on a very regular basis. Because not everything goes in there.

    Be prepared for severe haranguing about using VCS, and PHP in general.

    You are not alone.


  • Java Dev

    @loose said:

    if it not explicitly there it will default to whatever is in your ini file.

    That's bollocks. It's a run-time flag. It only takes the php.ini value if you never called error_reporting().

    Methinks you have been hit with a library that calls that function as well. Solution: Kill the library.



  • Sir! Are you calling me a liar!

    Here! :throw: :gauntlet: :ground:

    I dare you Sir, to pick that up!

    :rofl:

    No, really. I may not be exact when I say it defaults - I have never bothered to check. But I am damn sure there are significant circumstances where errors will go unreported if you don't explicitly state the error reporting level to the same or lower than that of the script that called it.

    The same goes for the use of @([insert error inducing statement here])

    I have been using PHP for 15 years, In my current role I am working on 10 year old code that has "evolved" where errors have been repressed and similarly gone unreported. Only recently, I discovered a line of code:

    $result = @mysql_query($query);
    

    Where the query was constructed from various strings depending on various conditions where (in this case) the resulting query generated was

    SELECT ... WHERE ... table_a.column_x = table_b.column_xAND ...
    

    Other than

    SELECT ... WHERE ... table_a.column_x = table_b.column_x AND ...
    

    Which resulted in MySQL throwing and ...unknown column column_xAND in table b... and because $result did not have the expected value, the program flow was forever changed.

    I appreciate that the above has nothing to do with the response, but I thought I would save some time. And please, I really do not see the need to argue this further. Thank you.

    Otherwise. Have a nice day and enjoy the rest of your weekend. :)


  • Java Dev

    @loose said:

    @([insert error inducing statement here])

    Should die in a fire. There are some limited cases of builtin functions that may throw errors for retarded reasons which cannot otherwise be simply checked, and direct calls to those functions may have their errors suppressed. Otherwise the syntax should be avoided.

    I don't even care to know what that symbol does when not directly attached to such a function.



  • I know how to use PHP, I am well aware about error_reporting(E_ALL) and I am well aware of how to use VCS. As per the Lounge thread... Well, you'll see it for yourself soon enough I think.

    The fact is, error reporting doesn't matter here. we habitually ignore all errors because why bothering fixing them? If I turned error reporting on, I guarantee I'd find so many errors, like undeclared variables, undeclared constants, re declared constants...

    The mystery, though, the real mystery is why PHP keeps crashing. I don't mean my script fails, or something like that, that I could diagnose myself. I mean flat out, PHP segfaults and Apache has to physically restart because of it. I don't mean any condition that could be tracked by way of error_reporting either. I mean, physically, this is PHP itself going :wtf: and dying.



  • When not attached directly to a function, it will act to suppress errors for that statement. It does this by way of ninja-updating the error_reporting value for that statement to 0, then resetting it after.



  • I cannot recall having this sort of issue. So I can really advise, and you seem pretty much on top of PHP quirksfeatures another such one is if you have Unix / windows line termination issues. Sorry I cant help you more, bit it is going to be a really stupid thing. Good luck, and preserve your sanity :)



  • PHP does crap itself occasionally but only once before did I see a repeatable cause in person. 5.3.8 has a bug where if any included PHP file is an exact multiple of 4KB it will just crash. This is a 5.5.12 setup though, so I dunno.


  • :belt_onion:

    @Arantor said:

    PHP does crap itself occasionally but only once before did I see a repeatable cause in person. 5.3.8 has a bug where if any included PHP file is an exact multiple of 4KB it will just crash. This is a 5.5.12 setup though, so I dunno.

    Pretty much it seems like it is almost always some module at fault (har), so I'd probably start removing the more exotic modules until it stops failing... or causes DOMPDF to stop working due to missing modules rather than segfaults.



  • That was something I didn't check out yet, thanks for the suggestion.

    I would still like to get a stack trace but this is now officially a live deployment so taking it down for that is unlikely to happen :(



  • This doesn't exactly help you with your problem, but http://wkthtmltopdf.org has always worked way better for me than any of the pure <insert language here> html to pdf renderers. You may check it out next time the need arises. (It's based on QtWebkit, so it's rendering is quite good).

    The supplied static builds are preferred for me, as they have patched Qt to improve handling of page break css, added page outlines, &c.


Log in to reply