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

Session issue in database PHP7 #4

Closed
lexbeelen opened this Issue Dec 15, 2015 · 20 comments

Comments

Projects
None yet
10 participants
@lexbeelen
Copy link

lexbeelen commented Dec 15, 2015

There is a issue with sessions.
This only happens when you set "session_save" in "local.xml" to "db".
If you try with the option "files" there are no problems.

Error.
Recoverable Error: session_regenerate_id(): Failed to create(read) session ID: user (path: /var/lib/php/sessions) in app/code/core/Mage/Core/Model/Session/Abstract/Varien.php on line 492

@icurdinj

This comment has been minimized.

Copy link
Contributor

icurdinj commented Dec 16, 2015

The problem might be in PHP itself: https://bugs.php.net/bug.php?id=70520
I have traced the code a bit, and the workaround in code would be somewhere deep in lib/varien or lib/zend.
Until that's fixed in PHP, just using file sessions seems like a smarter workaround. Other sessions storages, like Redis, need to be tested yet.

@arosenhagen

This comment has been minimized.

Copy link

arosenhagen commented Dec 16, 2015

had this issue too - redis backend is also broken this way (likely as it also uses the db interface).

@Marko-M

This comment has been minimized.

Copy link

Marko-M commented Dec 16, 2015

In hope this will aid your search for solution - when I encountered session issues with Magento 1.x + PHP 7 beta 3 + Redis, I used following workaround as quick fix to regain Magento admin access (save as "whatever.patch" and apply with "patch -p1 < whatever.patch"):

diff --git a/app/code/core/Mage/Core/Model/Session/Abstract.php b/app/code/core/Mage/Core/Model/Session/Abstract.php
index 8386fb8..a287df6 100644
--- a/app/code/core/Mage/Core/Model/Session/Abstract.php
+++ b/app/code/core/Mage/Core/Model/Session/Abstract.php
@@ -564,6 +564,8 @@ class Mage_Core_Model_Session_Abstract extends Mage_Core_Model_Session_Abstract_
      */
     public function renewSession()
     {
+        return $this;
+
         $this->getCookie()->delete($this->getSessionName());
         $this->regenerateSessionId();

Unfortunately I'm unable to do tests with PHP 7 final atm, but I'll test this workaround again first chance I get, if someone doesn't come up with something better in the meantime.

@ivanweiler

This comment has been minimized.

Copy link
Member

ivanweiler commented Dec 16, 2015

Just tested it a bit, win + php7 + db sessions ..

As @Marko-M posted, temp fix is bypassing session renewal.

It seems when session_regenerate_id() is called, write() of session handler is never called. You get new session id in php and $_SESSION value is ok after regeneration, but it's never written because it's never passed to session handler.

Why? No clue :) I also suspect it's php7 bug or some kind of change we're not aware of.

Interesting thing, if you manually change session id and manually set cookie, everything works as expected.

$this->setSessionId('my_custom_value');  
$this->getCookie()->set($this->getSessionName(),  $this->getSessionId());  

Is it possible to (easily) generate/get new session id in php without session_regenerate_id(), to use in above example?

I'm planning to test same thing on M2 tomorrow, to see how it behaves there.

@ivanweiler

This comment has been minimized.

Copy link
Member

ivanweiler commented Dec 17, 2015

Hello all, I managed to trace the problem.

Mage_Core_Model_Resource_Session::read($sessId) needs to always return string, for example changing
return $data; to return (string)$data; fix db session handler, login works.

When called on session_regenerate_id(true) it returns false which breaks regeneration. It seems it's going to be easy fix.

Can someone confirm this is correct? Thx.

@ivanweiler

This comment has been minimized.

Copy link
Member

ivanweiler commented Dec 17, 2015

I didn't test Redis, but I think it could be similar problem since I was getting this error with db handler:
session_regenerate_id(): Failed to create(read) session ID: user (path: )

and similar error is reported here colinmollenhour/Cm_RedisSession#70

@icurdinj

This comment has been minimized.

Copy link
Contributor

icurdinj commented Dec 18, 2015

Ivan, I have just pushed a fix based on your findings. Lets see how it works on database sessions, and when we have a chance, it's probably a good starting point for Redis fix.

@lexbeelen

This comment has been minimized.

Copy link
Author

lexbeelen commented Dec 18, 2015

I have try the fix. But no luck.
I'm getting still the same error.

@ivanweiler

This comment has been minimized.

Copy link
Member

ivanweiler commented Dec 18, 2015

@lexbeelen, @arosenhagen: Can you please write on which OS problem occurred, is php stable 7.0.0 version or older RC and is it mod_php, php-fpm, etc.
Thx

@arosenhagen

This comment has been minimized.

Copy link

arosenhagen commented Dec 18, 2015

for me it is ubuntu 14.04.3 / debian 8.2.0 with a nginx / php-fpm setup. I hadn't the chance to try the proposed fix though.

@lexbeelen

This comment has been minimized.

Copy link
Author

lexbeelen commented Dec 18, 2015

Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-57-generic x86_64)

PHP 7.0.0-5+deb.sury.org~trusty+1 (cli) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies

nginx version: nginx/1.4.6 (Ubuntu) php-fpm setup

@icurdinj

This comment has been minimized.

Copy link
Contributor

icurdinj commented Dec 18, 2015

@lexbeelen try now, I think it's fixed. And, we are probably on the right track to fix Redis too.

@lexbeelen

This comment has been minimized.

Copy link
Author

lexbeelen commented Dec 18, 2015

@icurdinj I can confirm you, that the issue is fixed 👍 Great job 👍

@johnbendi

This comment has been minimized.

Copy link

johnbendi commented Jan 3, 2016

Please what did you guys do to fix this issue? I don't understand what the solution to try is here.

@icurdinj

This comment has been minimized.

Copy link
Contributor

icurdinj commented Jan 4, 2016

@johnbendi - the solution was traced by our ingenious @ivanweiler :

Mage_Core_Model_Resource_Session::read($sessId) needs to always return string, for example >changing return $data; to return (string)$data; fix db session handler, login works.

What actually happened was that Magentos function lied in docbloc to always return string, while actually it sometimes returned FALSE. And that function was then fed to PHPs session handler. PHP 5.* silently converted that FALSE to empty string (I guess), and it worked. PHP 7.0 does type checking here and expects string, so it crashed.

Once the problem was traced, the solution was trivial. We replaced original
return $data;
with
return (string)$data;

:-)

@Native-Coder

This comment has been minimized.

Copy link

Native-Coder commented Jan 31, 2017

I'm having this same issue. It looks like it was a simple typecast. Where did you all make the change? I can't log into PhpMyAdmin after switching to memcached and would like to try this workaround

@icurdinj

This comment has been minimized.

Copy link
Contributor

icurdinj commented Feb 1, 2017

@dhaupin

This comment has been minimized.

Copy link

dhaupin commented Feb 16, 2017

@cscart - CS-Cart session handler (PHP7 + Redis session cache) shares a similar fix as Magento. In app/Tygh/Session.php within the read($sess_id) function, change the return $data; into return (string)$data; and all should work again.

In the case of CS-Cart, the way we noticed this error was using Chrome inspector in mobile emulator mode, then going back and forth to desktop mode. One or the other eventually caused session fail with error from a function further down the chain:

Catchable fatal error: session_regenerate_id(): Failed to create(read) session ID: user (path: ) in /app/Tygh/Session.php on line 403

@gcann-tbd

This comment has been minimized.

Copy link

gcann-tbd commented Nov 17, 2017

If you get this problem using memcache, change to memcached into your app/etc/local.xml and remove protocol : tcp://

@reinaldomendes

This comment has been minimized.

Copy link

reinaldomendes commented Jan 21, 2018

I have the same problem with php7 and session db mysql.

The problem is when session_regenerate_id is called it calls: destroy and read.
The destroy will set an expired timestamp in database, when read is called it will return nothing.

I did a fix which use debug_backtrace to check if call is from session_regenerate_id.

   class Mage_Core_Model_Resource_Session implements Zend_Session_SaveHandler_Interface { 
     ///....
    /**
    * @param string $sessId
     * @return string
     */
    public function read($sessId)
    {
        $flags = 0;
        $backtrace = debug_backtrace($flags,2);
        $regenerate = 'session_regenerate_id' === $backtrace[1]['function'];

        $select = $this->_read->select()
                ->from($this->_sessionTable, array('session_data'))
                ->where('session_id = :session_id')
                ->where('session_expires > :session_expires');

        $expires = $regenerate ? 0 : Varien_Date::toTimestamp(true);

        $bind = array(
            'session_id'      => $sessId,
            'session_expires' => $expires
        );


        $data = (string)$this->_read->fetchOne($select, $bind);

        return $data;
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.