yiisoft / yii2-debug

Debug Extension for Yii 2
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
201 stars 149 forks source link

yii\debug\FlattenException: session_set_cookie_params(): Cannot change session cookie parameters when headers already sent #431

Closed Commifreak closed 4 years ago

Commifreak commented 4 years ago

What steps will reproduce the problem?

Open the debug toolbar with link: ?r=debug%2Fdefault%2Fview&panel=user

What's expected?

The User Panel

What do you get instead?

yii\debug\FlattenException session_set_cookie_params(): Cannot change session cookie parameters when headers already sent

in /vendor/yiisoft/yii2/web/Session.php

     * This method is called by [[open()]] when it is about to open the session.
     * @throws InvalidArgumentException if the parameters are incomplete.
     * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php
     */
    private function setCookieParamsInternal()
    {
        $data = $this->getCookieParams();
        if (isset($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly'])) {
            if (PHP_VERSION_ID >= 70300) {
                session_set_cookie_params($data); // <<<<<<<<<<<<<<<<<<<< This line
            } else {
                if (!empty($data['samesite'])) {
                    $data['path'] .= '; samesite=' . $data['samesite'];
                }
                session_set_cookie_params($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly']); 
            }

        } else {
            throw new InvalidArgumentException('Please make sure cookieParams contains these elements: lifetime, path, domain, secure and httponly.');

Additional info

This happened after Upgrade to PHP 7.4. Before the upgrade, the toolbar showed the UID - now its showing User "error".

Any ideas whats wrong? Problem with the Toolbar or problem at my side?

err2 err1

Q A
Yii version 2.0.35
Yii-Debug version 2.1.13
PHP version 7.4.5
Operating system Ubuntu 18.04
Commifreak commented 4 years ago

Okay, got a bit further...

The debug module loads the identity ($identityData = $this->identityData($identity); in UserPanel.php). SO far so good. To get the identity, the panel get it from the identity class, configured in the app config, right?

Well, in the Identity class, I do something like:

    public static function getDb() {

        if ( Yii::$app->session->get( 'isAdmin' ) || Yii::$app->session->get( 'getGlobalNewsUser' ) ) {
            Yii::$app->session->remove( 'getGlobalNewsUser' );

            return Yii::$app->db;
        } else {
            return parent::getDb();
        }
    }

Which determines the correct user-db. But this is regardles, the fact is: I work with Session inside the getDB function. And this seem the reason, why it breaks.

Test:

    public static function getDb() {
            return Yii::$app->db;
    }

is working, while:

    public static function getDb() {

        Yii::$app->session->set('test', true);
        return Yii::$app->db;
    }

is NOT working.

In conclusion: The debug Userpanel does not work, if someone between start and output is using session inside the Identity class.

Bug or design-problem by me?

Regards,

samdark commented 4 years ago

I think that there should be a way to deal with it. That's not straightforward through so can't promise we'll solve it anytime soon. Any further digging or fix from your side would be very much appreciated.

Commifreak commented 4 years ago

The main thing: the toolbar really outputs content before it reaches the session related code. I dont know how the debug toolbar works internally.

But the Configuration panel works with Session as well, so I dont know where to start. I try my best.

Commifreak commented 4 years ago

Update: A simple session->isActive check made it. I dont know if I tested this earlier or if a Yio update changed things bit this solves the problem here.