tsingsun / yii2-swoole

make yii2 project runing on swoole
BSD 3-Clause "New" or "Revised" License
163 stars 23 forks source link

How to add dependency injection? #6

Open bubooon opened 5 years ago

bubooon commented 5 years ago

Hi, I have two questions. 1) I trying to add yii2-swoole to my yii2 project. But I saw that you hide Yii::$container interface, and now I can't do injection before app will run, how i can do it? 2) When i did request for app, i got an error that a MySql connection is not established. Logs below:

2019-05-31 18:14:59 [127.0.0.1][-][-][error][yii\base\ErrorException:2] yii\base\ErrorException: Swoole\Coroutine\MySQL::query(): The MySQL connection is not established in /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/db/mysql/PDO.php:146
Stack trace:
#0 [internal function]: tsingsun\swoole\web\ErrorHandler->handleError(2, 'Swoole\\Coroutin...', '/var/www/gostan...', 146, Array)
#1 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/db/mysql/PDO.php(146): Swoole\Coroutine\MySQL->query('SET NAMES 'utf8...')
#2 /var/www/gostandup/vendor/yiisoft/yii2/db/Connection.php(704): tsingsun\swoole\db\mysql\PDO->exec('SET NAMES 'utf8...')
#3 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/db/Connection.php(128): yii\db\Connection->initConnection()
#4 /var/www/gostandup/vendor/yiisoft/yii2/db/Connection.php(996): tsingsun\swoole\db\Connection->open()
#5 /var/www/gostandup/vendor/yiisoft/yii2/db/Connection.php(983): yii\db\Connection->getMasterPdo()
#6 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/db/Command.php(212): yii\db\Connection->getSlavePdo()
#7 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/db/Command.php(261): tsingsun\swoole\db\Command->prepare(true)
#8 /var/www/gostandup/vendor/yiisoft/yii2/db/Command.php(399): tsingsun\swoole\db\Command->queryInternal('fetchAll', NULL)
#9 /var/www/gostandup/vendor/yiisoft/yii2/db/mysql/Schema.php(312): yii\db\Command->queryAll()
#10 /var/www/gostandup/vendor/yiisoft/yii2/db/mysql/Schema.php(125): yii\db\mysql\Schema->findColumns(Object(yii\db\TableSchema))
#11 /var/www/gostandup/vendor/yiisoft/yii2/db/Schema.php(744): yii\db\mysql\Schema->loadTableSchema('gs_cities')
#12 /var/www/gostandup/vendor/yiisoft/yii2/db/Schema.php(194): yii\db\Schema->getTableMetadata('gs_cities', 'schema', false)
#13 /var/www/gostandup/vendor/yiisoft/yii2/db/ActiveRecord.php(384): yii\db\Schema->getTableSchema('gs_cities')
#14 /var/www/gostandup/vendor/yiisoft/yii2/db/ActiveRecord.php(408): yii\db\ActiveRecord::getTableSchema()
#15 /var/www/gostandup/vendor/yiisoft/yii2/db/ActiveRecord.php(178): yii\db\ActiveRecord::primaryKey()
#16 /var/www/gostandup/vendor/yiisoft/yii2/db/BaseActiveRecord.php(112): yii\db\ActiveRecord::findByCondition(373)
#17 /var/www/gostandup/controllers/SiteController.php(196): yii\db\BaseActiveRecord::findOne(373)
#18 [internal function]: app\controllers\SiteController->actionIndex(NULL)
#19 /var/www/gostandup/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#20 /var/www/gostandup/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#21 /var/www/gostandup/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('', Array)
#22 /var/www/gostandup/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('', Array)
#23 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/bootstrap/WebApp.php(45): yii\web\Application->handleRequest(Object(tsingsun\swoole\web\Request))
#24 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/bootstrap/BaseBootstrap.php(124): tsingsun\swoole\bootstrap\WebApp->handleRequest(Object(Swoole\Http\Request), Object(Swoole\Http\Response))
#25 /var/www/gostandup/vendor/tsingsun/yii2-swoole/src/server/HttpServer.php(40): tsingsun\swoole\bootstrap\BaseBootstrap->onRequest(Object(Swoole\Http\Request), Object(Swoole\Http\Response))
#26 {main}

I can't understand why, because simple example like this works fine:


    $mysql = new Swoole\Coroutine\MySQL();
    $server = array(
        'host' => 'mysql',
        'port' => 3306,
        'user' => 'root',
        'password' => 'pw',
        'database' => 'dbname',
    );
    $mysql->connect($server);

    $result = $mysql->prepare('SELECT * FROM `gs_users` LIMIT 1' );
    if ($result == false)
    {
        var_dump($mysql->errno, $mysql->error);
    }
    else
    {
        $ret2 = $result->execute();
        var_dump($ret2);
    }
});```
tsingsun commented 5 years ago

What is your PHP version and SWOOLE version

bubooon commented 5 years ago

What is your PHP version and SWOOLE version

PHP 7.3 Swoole 4.3.4

tsingsun commented 5 years ago

i try Swoole 4.3.4 and it's ok, please check yii2 db config,whether as same as

$server = array(
        'host' => 'mysql',
        'port' => 3306,
        'user' => 'root',
        'password' => 'pw',
        'database' => 'dbname',
    );
bubooon commented 5 years ago

i try Swoole 4.3.4 and it's ok, please check yii2 db config,whether as same as

$server = array(
        'host' => 'mysql',
        'port' => 3306,
        'user' => 'root',
        'password' => 'pw',
        'database' => 'dbname',
    );

Be sure, I checked it many times(

tsingsun commented 5 years ago

i saw mysql host name is 'mysql', can retry instead of ip. BTW, what's your method to do injection in native YII2.

bubooon commented 5 years ago

i saw mysql host name is 'mysql', can retry instead of ip. BTW, what's your method to do injection in native YII2.

My host is "mysql" because my project inside docker and mysql is another service from docker-compose.

In my Yii2 project without swoole I added after included Yii.php:

require(__DIR__ . '/components/dependency/gsDependencies.php');

This file contains code like this:

Yii::$container->set('yii\web\User', 'gscomponents\gsWebUser');
Yii::$classMap['yii\web\View'] = __DIR__.'/gsView.php';

And now with swoole i can't rewrite behaviour of default User class or View etc.

tsingsun commented 5 years ago

add to swoole server start script like

Server::run($config, function (Server $server) {
    $starter = new \tsingsun\swoole\bootstrap\WebApp($server);
    $starter->init = function (\tsingsun\swoole\bootstrap\BaseBootstrap $bootstrap) {
        require(__DIR__ . '/yii2-app-basic/vendor/tsingsun/yii2-swoole/src/Yii.php');
        //additional script
       require(__DIR__ . '/components/dependency/gsDependencies.php');

        Yii::setAlias('@webroot', WEBROOT);
        Yii::setAlias('@web', '/');
        Yii::$swooleServer = $bootstrap->getServer()->getSwoole();
        $bootstrap->appConfig = $config;

    };
}