myaaghubi / PHP-Frameworks-Bench

A library to make benchmarks from PHP frameworks.
GNU General Public License v2.0
109 stars 4 forks source link

The `output_data.php` don't work with PHP-FPM in some frameworks #39

Closed joanhey closed 1 year ago

joanhey commented 1 year ago

PHP-FPM has become the de-facto process manager for PHP, providing more flexibility than the venerable PHP module for Apache.

All frameworks that use the Symfony kernel, output no data after the Hello World!.

Internally, the HttpKernel makes use of the fastcgi_finish_request PHP function.

https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-kernel-terminate

Frameworks that fail:

image

We need to search a solution.

myaaghubi commented 1 year ago

Same issue with nginx, the problem is not about output_data.php the mechanism is to measure via output_data.php at the end of the script but requests get finished before reaching the end via fastcgi_finish_request or litespeed_finish_request

joanhey commented 1 year ago

We can require the output_data.php in the same controller method, for that frameworks.

class HelloWorldController extends Controller {
    public function index(): void {
        echo 'Hello World!';
        /* *** PHP-Frameworks-Bench *** */
        require $_SERVER['DOCUMENT_ROOT'].'/PHP-Frameworks-Bench/libs/output_data.php';
    }
}

I don't think exist a big diff for that framewoks. But first we can test it, to check the diff in apache vs nginx(php-fpm). Memory usage will be different as are different SAPIs, but included files need to be egual or similar. The microtime used will be NOT correct, but we really need it?. We have others way to get it.

PD: my screen capture is using Nginx.

myaaghubi commented 1 year ago

Some libs use return ... instead! accuracy not gonna be accurate too. Try to run some benchmarks on nginx you gonna surprised as I did once you may believe the Apache again

myaaghubi commented 1 year ago

Some frameworks have return ... instead, so let's imagine having something like this to make it work

// a simple controller example for Symfony
class HelloWorldController {
    public function index(): Response {
        function outputData(){
            ob_start();
            require($_SERVER['DOCUMENT_ROOT'].'/PHP-Frameworks-Bench/libs/output_data.php');
            return ob_get_clean();
        }
        return new Response('Hello World!'.outputData());
    }
}

It is gonna work but the measurement for memory not gonna be accurate. Also the cost of rendering output while/after Response and return not gonna measured. It may, in case, there be no considerable cost after Response however this is benchmarking and we need to consider it