13

PHP's built in web server allows "router scripts" to be used, allowing for rewriting URLs internally.

The problem with such a router script is the fact that whenever it actually handles a file instead of letting PHP handle it, this causes the request log output for that request to be suppressed. For example, consider the following script:

<?php
if (preg_match('/^\/(js|css)/', $_SERVER['REQUEST_URI']) === 1) {
  return false;
}
else {
  echo 'hello world!'
}

This causes requests for /js/* and /css/* to be logged on the console; whereas requests for any other URLs simply skip logging the request.

How can I enable logging of all requests to the console?

cn007b
  • 16,596
  • 7
  • 59
  • 74

2 Answers2

3

router.php :

if (preg_match('/^\/(js|css)/', $_SERVER['REQUEST_URI']) === 1) {
    return false;
}
else {
    $stdErr = fopen("php://stderr",'w+');
    fwrite($stdErr, 'LogRequest:'.$_SERVER['REQUEST_URI']."\n");
    echo 'hello world!1';
}

Server start: php -S localhost:8000 router.php 2>&1

To log response headers:

if (preg_match('/^\/(js|css)/', $_SERVER['REQUEST_URI']) === 1) {
    return false;
}
else {
    ob_start() 
    $stdErr = fopen("php://stderr",'w+');
    fwrite($stdErr, 'Request:'.json_encode($_SERVER)."\n");
    try {
      echo 'hello world!1';
    } catch (\Exception $e) {
        http_response_code(500);
    }
    $response = ob_get_clean();
    fwrite($stdErr, 'Response:'.json_encode([ http_response_code(),headers_list() ])."\n");
    echo $response;
}
cske
  • 2,233
  • 4
  • 26
  • 24
  • Unfortunately, unlike the built-in webserver's logging, it doesn't cause the response HTTP status to be logged (which is kinda the point of the log...) –  Aug 13 '16 at 14:48
  • i think the challenging part was to write to the console from the else case, if you want more than quick view about what happening i avdise to consider to put a real webserver before php, anyway i've added a sample for response code logging – cske Aug 15 '16 at 07:09
2

In your log you can see errors from php build-in server, so you can do like @cske, but i think you should stick another approach.You can use own logger and write explicitly info to this log. The best logger right now it is monolog, so you don't have to reveal the wheel. Here my example:

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// Create a log channel.
$log = new Logger('general');
$log->pushHandler(new StreamHandler('/var/log/php/general.log', Logger::INFO));

if (preg_match('/^\/(js|css)/', $_SERVER['REQUEST_URI']) === 1) {
    $log->error('Invalid request.');
    return false;
} else {
    $log->info('Success.');
    echo 'hello world!';
}

I hope you agree that it looks much clear and simple.
Also when you will move from php build-in server to for example nginx your code will work correctly. You need just run in another window into terminal tail -f /var/log/php/general.log and you will observe behavior of your script like in window with php build-in server.

PS: I hope you don't use php build-in server in production

cn007b
  • 16,596
  • 7
  • 59
  • 74
  • if the problem would have been how to log to file with php, my first though was similar log to file and merge `tail` and `php -S` output, but sdterr solved the problem so there is even no need for a writeable filepath – cske Aug 12 '16 at 10:15