2

I have a backup script that runs from the browser without a problem. It extracts data from the database and writes it to a ZIP file that's under 2MB .

It mostly runs from the server, but it fails (silently) when it hits a particular line:

require ('/absolute-path/filename');  // pseudo filespec

This is one of several such statements. These are library files that do nothing but 'put stuff in memory'. I have definitely eliminated any possibility that the path is the problem. I'm testing the file with a conditional is_readable(), output it, and sent myself emails.

$fs = '/absolute-path/filename'; // pseudo filespec
if (is_readable ($fs) ) { 
    mail('myaddress','cron','before require'); // this works reliably
    require ($fs); // can be an empty file ie. <?php ?>
    mail('myaddress','cron','after require'); // this never works.
}

When I comment out the require($fs), the script continues (mostly, see below).

I've checked the line endings (invisible chars). Not on every single include-ed file, but certainly the one that is running has newline (NL) endings (Linux-style), as opposed to newline + carriage return (NL CR) (Windows style).

I have tried requiring an empty file (just <?php ?>) to see if the script would get past that point. It doesn't.

I have tried calling mail(); from the included script. I get the mail. So again, I know the path is right. It is getting executed, but it never returns and I get no errors, at least not in the PHP log. The CRON job dies...

This is a new server. I just migrated the application from PHP 5.3.10 to PHP7. Everything else works.

I don't think I am running out of memory. I haven't even gotten the data out of the database at this point in the script, but it seems like some sort of cumulative error because, when I comment out the offending line, the error moves on to another equally puzzling silent failure further down the code.

Are there any other useful tests, logs, or environment conditions I should be looking at? Anything I could be asking the web host?

3 Answers3

0

This usually means that there is some fatal error being triggered in the included file. If you don't have all errors turned on, PHP may fail silently when including files with certain fatal errors. PHP 7 throws fatal errors on certain things that PHP 5.3 did not, such as Division by Zero. If you have no access to server config to turn all errors on, then calling an undefined function will fail silently. You can try debugging by putting die('test'); __halt_compiler(); at the beginning of a line, starting from the top, on the line after the first <?php tag and see if it loads. If it does slowly displace line by line (though don't cut a control structure!) and retest after each time and when it dies you know the error is on the line above.

nzn
  • 1,014
  • 11
  • 20
0

I believe the problem may be a PHP 7 bug. The code only broke when it was called by CRON and the 'fix' was to remove the closing PHP tag ?>. Though it is hard to believe this could be an issue, I did a lot of unit testing, removing prior code, etc. I am running PHP 7.0.33. None of the other dozen or so (backup) scripts broke while run by CRON.

0

As nzn indicated this is most likely caused by an error triggered from the included file. From the outside it is hard to diagnose. A likely case is a relative include/require within that file. A way to verify that is by running the script on console from a different location. A f might be to either call cd from cron before starting PHP or doing a chdir(__DIR__) within the primary file before doing further includes.

johannes
  • 15,807
  • 3
  • 44
  • 57
  • That makes sense, but as I said, I did a LOT of unit testing. I isolated the code ALL the way down until I was as convinced as possible that the only variable was removing the PHP close tag ?> – Mister Zingbat May 30 '19 at 15:35