简体   繁体   中英

Return value from php top level php script gets swallowed

I am hunting a bug in an application which I could narrow down to a required return value not getting returned as a result of a http request to an http server. The request is a POST uploading a file, the return value should be a confirmation in form of a string that can be used to access that file later.

The server is running a php script to process the uploaded file, all works fine, except I do not get that required string in the return payload. Instead the payload is empty.

The problem is caused be an additional request router I implemented on top of the existing application. The router is a simple top-level script (index.php) which is directly called by the http server (apache2) as a result of some rewriting based routing on server level.

Here is the (reduced and simplyfied) router script. For the test case it is called with these values: service=put&method=logo . As expected it includes the file ...../service/pi.php which does some processing and terminates correctly returning the required string:

<?php

require_once \CONFIG\PATH\BACKEND.'/include/exception.php';

try {

  $service = isset($_GET['service']) ? $_GET['service'] : (isset($_POST['service']) ? $_POST['service'] : NULL);
  $method  = isset($_GET['method'])  ? $_GET['method']  : (isset($_POST['method'])  ? $_POST['method']  : NULL);

  switch ($service) {
    case 'amf':         return include \CONFIG\PATH\BACKEND.'/service/amf.php';
    case 'bof':         return include \CONFIG\PATH\BACKEND.'/service/bof.php';
    case 'put':
      switch ($method) {
        case 'deco':
        case 'img':
        case 'logo':
        case 'plan':    $ret = include \CONFIG\PATH\BACKEND.'/service/pi.php';
                        error_log('+++ '.print_r($ret,true));
                        error_log('*** '.print_r(debug_backtrace(),true));
                        echo "honkitonk";
                        return $ret;
        default:        throw new \PDExceptionLogicalError('Invalid method');
      } // switch method
    case 'get':
      switch ($method) {
        case 'creport': return include \CONFIG\PATH\BACKEND.'/service/gcr.php';
        case 'deco':    return include \CONFIG\PATH\BACKEND.'/service/gdi.php';
        case 'img':     return include \CONFIG\PATH\BACKEND.'/service/gi.php';
        case 'report':  return include \CONFIG\PATH\BACKEND.'/service/gr.php';
        default:        throw new \PDExceptionLogicalError('Invalid method');
      } // switch method
    default:            throw new \PDExceptionLogicalError('Invalid service');
  } // switch service

} catch (PDException $e) { return $e->getPDError(); }

?>

The output in the log files is generated for test purposes only. Normally that branch of the two switch statements would simply return the result of the included script jsut like it is done in the other branches.

The resulting payload sent back to the client is valid and contains the test string "honkitonk", but not the return value in $ret . The script execution does not continue behind the switch statement or anything, the script is terminated with the return $ret; inside the questionable inner switch branch.

The output in the log file shows this:

[Sat Sep 28 09:17:39 2013] [error] [client 127.0.0.1] +++ /backend/get?method=img&id=26
[Sat Sep 28 09:17:39 2013] [error] [client 127.0.0.1] *** Array\n(\n)\n

The empty array in the log file (result of the debug_backtrace() call proves that the script is on top level. A return in a top level script should result in the return value to be handed over into the server reply. However this is not the case here. And I simply do not understand why!

I also made a check using a global output puffer around the script and examining that: exctly the same result: "honkitonk", but not the required string value in $ret .

What am I missing here?

Just a quick guess, put ( and ) around your include statements:

Return ( include 'file' );

Does the included file contains a return statement or do you just print the contents you want?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM