joanhey / AdapterMan

Run almost any PHP app faster and asynchronously with Workerman, without touch 1 line of code in your fw or app. Also use it as Serverless.
https://twitter.com/adaptermanphp
MIT License
751 stars 48 forks source link

How to modify start.php if using yii2? #47

Open tangniyuqi opened 1 year ago

tangniyuqi commented 1 year ago

How to modify it?

Thanks.

joanhey commented 1 year ago

Yii2

server.php

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

use Adapterman\Adapterman;
use Workerman\Worker;
use Workerman\Lib\Timer;

Adapterman::init();

require __DIR__.'/start.php';

$http_worker                = new Worker('http://0.0.0.0:8080');
$http_worker->count         = (int) shell_exec('nproc') * 4;
$http_worker->name          = 'AdapterMan-Yii2';

$http_worker->onWorkerStart = static function () {
    WorkerTimer::init();
};

$http_worker->onMessage = static function ($connection) {

    $_SERVER['SCRIPT_FILENAME'] = '/app/index.php'; // fix
    $_SERVER['SCRIPT_NAME'] = '/index.php'; // fix
    header(WorkerTimer::$date); // optional, the Date header is added automatically with Nginx or any other web server
    $connection->send(
        run()
    );
};

class WorkerTimer
{
    public static $date;

    public static function init()
    {
        self::$date = 'Date: '.gmdate('D, d M Y H:i:s').' GMT';
        Timer::add(1, function() {
            WorkerTimer::$date = 'Date: '.gmdate('D, d M Y H:i:s').' GMT';
        });
    }
}

Worker::runAll();

start.php

<?php

// uncomment the following block to debug this app
/*
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
error_reporting(E_ALL);
ini_set('display_errors','on');
 */

define('YII_ENABLE_ERROR_HANDLER', false);

require __DIR__ . '/vendor/yiisoft/yii2/Yii.php';

// Change to your config
$config = [
    'id' => 'benchmark',
    'basePath' => __DIR__ . '/app',
    'components' => [
        // Functions are faster than array declarations,
        // since they avoid the cost of Dependency Injection.
        'db' => function() {
            return new yii\db\Connection([
                'dsn' => 'mysql:host=tfb-database;dbname=hello_world',
                'username' => 'benchmarkdbuser',
                'password' => 'benchmarkdbpass',
                'charset' => 'utf8',
                'attributes' => [
                    PDO::ATTR_PERSISTENT => true,
                ],
                'enableLogging' => false,
                'enableProfiling' => false,
                'enableSchemaCache' => true,
                'schemaCache' => 'cache',
                'schemaCacheDuration' => 3600,
            ]);
        },
        'cache' => function() {
            return new yii\caching\FileCache([
                'cachePath' => '/tmp/yii2-cache',
                'gcProbability' => 0,
            ]);
        },
        'urlManager' => function() {
            return new yii\web\UrlManager([
                'enablePrettyUrl' => true,
            ]);
        },
        // These components are overloaded for a small gain in performance (no DI)
        'request' => function() { return new yii\web\Request(); },
        'response' => function() { return new yii\web\Response(); },
    ],
];

//(new  yii\web\Application($config))->run();

function run()
{
    global $config;
    ob_start();
    (new yii\web\Application($config))->run();
    return ob_get_clean();
}

You can check it in the benchmark, I used the same code that with php-fpm. There I used the same index.php, and only comment the (new yii\web\Application($config))->run(); ~And 1 line changed in the core. vendor/yiisoft/yii2/web/Response.php
(headers_sent($file, $line)) -> (headers_sent())~ (Fixed)

Perhaps will be good to add an issue for this line in Yii2 repo. And perhaps also to don't need to hardcode the $_SERVER, that it's always the same file.

$_SERVER['SCRIPT_FILENAME'] = '/app/index.php'; // fix
$_SERVER['SCRIPT_NAME'] = '/index.php'; // fix

The code in the benchmark https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/PHP/yii2/yii2-workerman.dockerfile

joanhey commented 1 year ago

Yii2 bechmark results with php-fpm and Adapterman:

https://www.techempower.com/benchmarks/#section=data-r21&f=zik0zj-zik0zj-zik0zj-xan9xb-zik0zj-zik0zj-zik0zj-zik0zj-zik0zj-zik0zj-zik0zj-zik0zj-zik0zj-35r&test=json

image

image

joanhey commented 1 year ago

Commit f1f5b3c, fix the headers_sent() problem with Yii2. So it isn't necessary to touch the Yii2 Response in vendor dir.