Yii2: the at sign (@) session_regenerate_id

Created on 15 Jan 2016  ·  26Comments  ·  Source: yiisoft/yii2

  • php7.0.2
  • yii2.0.6

yii2/web/Session.php

public function regenerateID($deleteOldSession = false)
{
    // add @ to inhibit possible warning due to race condition
    // https://github.com/yiisoft/yii2/pull/1812
    @session_regenerate_id($deleteOldSession);
}

I know this is a php7's bug https://bugs.php.net/bug.php?id=71187 .
But when I use yii2 debug, there is no any error messages expect http 500.

easy bug

Most helpful comment

My workaround for PHP7's recoverable fatal error:

class Php7SafeSession extends Session
{
    public function regenerateID($deleteOldSession = false)
    {
        if (interface_exists('\Throwable')) {
            try {
                session_regenerate_id($deleteOldSession);
            } catch (\Throwable $t) { /* Check error content here */ }
        } else {
            @session_regenerate_id($deleteOldSession);
        }
    }

All 26 comments

I can't suggest the ideal solution for the problem.

Maybe, we can remove stfu when YII_DEBUG is true...

SilverFire nice !

@yiisoft/core-developers

That's a good idea.

I can confirm this issue with php7.0.2, yii2.0.6 and yii\redis\Session. I had to switch to yii\web\CacheSession for now.

@georgekaf try update yii2-redis to "yiisoft/yii2-redis": "dev-master",
https://github.com/yiisoft/yii2-redis/commit/3c8c6a42c0177a244b5bb878d60c3ad1d2d14f96

@githubjeka Seems to be working properly, thanks!

My workaround for PHP7's recoverable fatal error:

class Php7SafeSession extends Session
{
    public function regenerateID($deleteOldSession = false)
    {
        if (interface_exists('\Throwable')) {
            try {
                session_regenerate_id($deleteOldSession);
            } catch (\Throwable $t) { /* Check error content here */ }
        } else {
            @session_regenerate_id($deleteOldSession);
        }
    }

I'm using Yii 2.0.6 - \yii\web\Session->regenerateID looks like this:

    public function regenerateID($deleteOldSession = false)
    {
        // add @ to inhibit possible warning due to race condition
        // https://github.com/yiisoft/yii2/pull/1812
        @session_regenerate_id($deleteOldSession);
    }

@session_regenerate_id($deleteOldSession); Errors as people have stated above.

I assume simply ignoring the error (using a try catch to hide it) is going to be insecure? If so is there a workaround? The above workarounds don't seem to apply.

Just to clarify if I leave the @ sign I just get a white page after login and if I remove it I get a full blown exception. Thanks!

@adamdry what's exception text? What's your PHP version?

@samdark Exception message is session_regenerate_id(): Failed to create(read) session ID: user (path: /var/lib/php/sessions)

Php version is 7.0.9-1+deb.sury.org~trusty+1

FYI Php 5.6 seems to work fine - I'm in the process of testing php 7 with our Yii2 powered app

Which session backend is used?

Ah we're using redis \yii\redis\Session - does that mean this should work for me?

It does work. Apologies! I forgot we were using redis. Thanks for the quick reply :smile:

Ошибка осталась:
PHP Recoverable Error 'yii\base\ErrorException' with message 'session_regenerate_id(): Failed to create(read) session ID: memcache (path: tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15)'

in /home/**/site/common/web/Session.php:20

Stack trace:

0 {main}

<?php

namespace common\web;

class Session extends \yii\web\Session
{
    /**
     * 
     * Ждём исправления в https://github.com/yiisoft/yii2/issues/10583
     *
     *
     * @inheritdoc
     */
    public function regenerateID($deleteOldSession = false)
    {
        if ($this->getIsActive()) {
            // add @ to inhibit possible warning due to race condition
            // https://github.com/yiisoft/yii2/pull/1812
            if (YII_DEBUG && !headers_sent()) {
                session_regenerate_id($deleteOldSession);
            } else {
                @session_regenerate_id($deleteOldSession);
            }
        }
    }
}

@KhristenkoYura как воспроизвести?

Переопределить параметры в php.ini:

session.save_handler = memcache
session.save_path = "tcp://127.0.0.1:11211"

И авторизироваться

Какая ОС, версия memcahed и версия PECL-расширения?

Заметь, используется memcache а не memcached

CentOS Linux release 7.1.1503 (Core)
]$ php -v
PHP 7.0.7 (cli) (built: May 28 2016 07:53:22) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans

$ php -i

memcache

memcache support => enabled
Active persistent connections => 0
Version => 2.2.7
Revision => $Revision$

Directive => Local Value => Master Value
memcache.allow_failover => 1 => 1
memcache.chunk_size => 8192 => 8192
memcache.default_port => 11211 => 11211
memcache.default_timeout_ms => 1000 => 1000
memcache.hash_function => crc32 => crc32
memcache.hash_strategy => standard => standard
memcache.max_failover_attempts => 20 => 20

memcached

memcached support => enabled
Version => 3.0.0b1
libmemcached version => 1.0.16
SASL support => yes
Session support => yes
igbinary support => no
json support => no
msgpack support => no

Directive => Local Value => Master Value
memcached.compression_factor => 1.3 => 1.3
memcached.compression_threshold => 2000 => 2000
memcached.compression_type => fastlz => fastlz
memcached.default_binary_protocol => 0 => 0
memcached.default_connect_timeout => 0 => 0
memcached.default_consistent_hash => 0 => 0
memcached.serializer => php => php
memcached.sess_binary_protocol => 1 => 1
memcached.sess_connect_timeout => 0 => 0
memcached.sess_consistent_hash => 1 => 1
memcached.sess_lock_expire => 0 => 0
memcached.sess_lock_max_wait => not set => not set
memcached.sess_lock_retries => 5 => 5
memcached.sess_lock_wait => not set => not set
memcached.sess_lock_wait_max => 2000 => 2000
memcached.sess_lock_wait_min => 1000 => 1000
memcached.sess_locking => 1 => 1
memcached.sess_number_of_replicas => 0 => 0
memcached.sess_persistent => 0 => 0
memcached.sess_prefix => memc.sess. => memc.sess.
memcached.sess_randomize_replica_read => 0 => 0
memcached.sess_remove_failed_servers => 0 => 0
memcached.sess_sasl_password => no value => no value
memcached.sess_sasl_username => no value => no value
memcached.sess_server_failure_limit => 0 => 0
memcached.store_retry_count => 2 => 2

А версия самого демона какая?

$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
version
VERSION 1.4.15

@KhristenkoYura that's expected behavior. PECL memcache (w/o d) isn't compatible with PHP 7 as noted in the description of this issue. Previously it was failing w/ responding 500 without giving out any details on why, not it shows error message.

The incompatibility itself can't be affected from within Yii.

Точно такая же ошибка вылетает если в качестве сессии используется redis:
PHP Warning – yii\base\ErrorException
session_regenerate_id(): Session object destruction failed. ID: user (path: /tmp/php/sessions)

  1. in /srv/http/vic/www/myshop/trunk/dev/src/vendor/yiisoft/yii2/web/Session.php at line 284
    Это строка: session_regenerate_id($deleteOldSession);
    Нужно сделать вот так: @session_regenerate_id($deleteOldSession); тогда все работает.

@only-victor this should be fixed on redis master already, it is not yet released.

Такая же проблема возникла на зеркале сайта с кирилличиским доменом (низнаю как это может быть сзязано) если глушить @session_regenerate_id($deleteOldSession); ошибки не отображаются но сессия не пишется всеравно, пробовал сохранять в memcached результат тотже

Was this page helpful?
0 / 5 - 0 ratings