New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-init component on fly #3436

Closed
MUTOgen opened this Issue May 11, 2014 · 18 comments

Comments

Projects
None yet
3 participants
@MUTOgen
Contributor

MUTOgen commented May 11, 2014

Is it possible to modify some components on fly in modules?

I try something like this:

\Yii::$app->set('errorHandler',array(
                'class'=>'app\components\ApiErrorHandler',
                'errorAction'=>'site/error',
            ));

But object of errorHandler doesn't change (it's \yii\web\ErrorHandler by default)

@cebe cebe added this to the 2.0 RC milestone May 11, 2014

@cebe cebe added the type:bug label May 11, 2014

@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

The docs of set() say:

If a component definition with the same ID already exists, it will be overwritten.

this is not the case atm. @qiangxue looks like a bug to me, right?

@qiangxue

This comment has been minimized.

Member

qiangxue commented May 11, 2014

Nope. This is because errorHandler is specially handled in application. The error handler has to be created and registered.

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

@qiangxue once created errorHandler object will be returned by ServiceLocator always...
Is there fancy way to overwrite?

@qiangxue

This comment has been minimized.

Member

qiangxue commented May 11, 2014

You may try the following. However you probably need to override register() to properly handle the problem of registering multiple exception handlers.

$handler = new \app\components\ApiErrorHandler;
\Yii::$app->set('errorHandler', $handler);
$handler->register();
@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

@qiangxue have you checked the implementation of ServiceLocator? once you have accessed a component, get() will never return a new one that may have been registered with set()
you have to call clear() before setting a new component. Is this expected? if yes, docs should be adjusted.

@qiangxue

This comment has been minimized.

Member

qiangxue commented May 11, 2014

@cebe You are right. I have fixed the issue. However, the issue reported here is different. It's because of the special handling at : https://github.com/yiisoft/yii2/blob/master/framework/base/Application.php#L305

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

@qiangxue i have PHP Fatal Error

Class 'app\components\Yii' not found

right after calling

$handler->register();
@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

@MUTOgen this looks like you are using Yii without importing it in the namespace. add use Yii; to the class file or use \Yii instead.

@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

@qiangxue yes, I know. See also #3431 working on a fix for that right now.

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

@cebe importing doesn't work.... i guess it's because of dealing with register();
looks like somewhere inside \Yii class uses without \

@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

can you please post the full error stack trace?

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

@cebe looks pretty "simple"

<response>
<type>yii\base\ErrorException</type>
<name>PHP Fatal Error</name>
<message>Class 'app\components\Yii' not found</message>
<code>1</code>
<stack-trace>
<item>#0 {main}</item>
</stack-trace>
</response>
@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

have you made any changes to app index.php? if yes, show the whole file please.

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

No, i didn't
Ctrl+C Ctrl+V


// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

$config = require(__DIR__ . '/../config/web.php');

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

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

When i comment line

$handler = new \app\components\ApiErrorHandler;
        \Yii::$app->set('errorHandler', $handler);
        //$handler->register();

There is no fatals

@cebe

This comment has been minimized.

Member

cebe commented May 11, 2014

where is this line? in which file?

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

 public function init()
    {
        parent::init();

        $handler = new \app\components\ApiErrorHandler;
        \Yii::$app->set('errorHandler', $handler);
        //$handler->register();
    }

It's init in module class

@MUTOgen

This comment has been minimized.

Contributor

MUTOgen commented May 11, 2014

now this option to overwrite handler works for me in module init method

$handler = new \app\components\ApiErrorHandler;
        \Yii::$app->set('errorHandler', $handler);
        $handler->register();

@cebe cebe closed this May 11, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment