Skip to content
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
Closed

Re-init component on fly #3436

MUTOgen opened this issue May 11, 2014 · 18 comments
Labels
Milestone

Comments

@MUTOgen
Copy link
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
Copy link
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
Copy link
Member

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

@MUTOgen
Copy link
Contributor Author

MUTOgen commented May 11, 2014

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

@qiangxue
Copy link
Member

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
Copy link
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
Copy link
Member

@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
Copy link
Contributor Author

MUTOgen commented May 11, 2014

@qiangxue i have PHP Fatal Error

Class 'app\components\Yii' not found

right after calling

$handler->register();

@cebe
Copy link
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
Copy link
Member

cebe commented May 11, 2014

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

@MUTOgen
Copy link
Contributor Author

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
Copy link
Member

cebe commented May 11, 2014

can you please post the full error stack trace?

@MUTOgen
Copy link
Contributor Author

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
Copy link
Member

cebe commented May 11, 2014

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

@MUTOgen
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Member

cebe commented May 11, 2014

where is this line? in which file?

@MUTOgen
Copy link
Contributor Author

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
Copy link
Contributor Author

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 as completed May 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants