0

I have a Zend Framework 1 (ZF1) application running in a Docker container with PHP 7.1.9-1. Now I have updated such container and the PHP version has changed to 7.1.11-1. For some reason unknow to me the application has stopped working (I got a blank page) and the only error I can see is:

[Sat Nov 04 16:05:45.500626 2017] [php7:notice] [pid 61] [client 172.18.0.1:49356] PHP Warning:  session_write_close(): Failed to write session data using user defined save handler. (session.save_path: /var/lib/php/sessions) in /var/www/html/vendor/zendframework/zendframework1/library/Zend/Session.php on line 732
[Sat Nov 04 16:05:45.500637 2017] [php7:notice] [pid 61] [client 172.18.0.1:49356] PHP Stack trace:
[Sat Nov 04 16:05:45.500653 2017] [php7:notice] [pid 61] [client 172.18.0.1:49356] PHP   1. Zend_Session_SaveHandler_DbTable->__destruct() /var/www/html/vendor/zendframework/zendframework1/library/Zend/Session/SaveHandler/DbTable.php:0
[Sat Nov 04 16:05:45.500658 2017] [php7:notice] [pid 61] [client 172.18.0.1:49356] PHP   2. Zend_Session::writeClose($readonly = *uninitialized*) /var/www/html/vendor/zendframework/zendframework1/library/Zend/Session/SaveHandler/DbTable.php:217
[Sat Nov 04 16:05:45.500661 2017] [php7:notice] [pid 61] [client 172.18.0.1:49356] PHP   3. session_write_close() /var/www/html/vendor/zendframework/zendframework1/library/Zend/Session.php:732

I know there is a lot of info about this but nothing I have tried did work for me. Some of them are:

This is how the Session Save Handler has been setup in the bootstrap.php file as explained here in docs:

$config = [
    'name'           => 'session',
    'primary'        => 'id',
    'modifiedColumn' => 'modified',
    'dataColumn'     => 'data',
    'lifetimeColumn' => 'lifetime',
];

Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable($config));
Zend_Session::start();

I did know also that ZF1 reached it's EOL recently and there is no support but for now I can get rid of ZF1 on my application and I do not want to go back to PHP5.

My guess is something has changed between 7.1.9 and 7.1.10 but I don't have a clue about it.

Any ideas in what could be going wrong here?

ReynierPM
  • 17,594
  • 53
  • 193
  • 363
  • is thist all of error_log on this error? it seems you are using db handler for sessions and its having trouble to write to table. If this's true can you check this link and confirm your table is what's supposed to be? http://zendframework.github.io/zend-session/save-handler/#dbtablegateway – Mehmet SÖĞÜNMEZ Nov 06 '17 at 21:30
  • @MehmetSÖĞÜNMEZ this is ZF1 I think the docs you give me is for other version rather than 1 :( – ReynierPM Nov 07 '17 at 14:59
  • yup you'are right :/ but reason is session save handler. what's your settings? is it file or db handler? can you share session settings? – Mehmet SÖĞÜNMEZ Nov 07 '17 at 19:36
  • @MehmetSÖĞÜNMEZ sorry for the delay. Take a look to my recent edit, is that what you are asking for? – ReynierPM Nov 15 '17 at 01:16
  • there's an other config in documentations if you are using multi-column database. Is it first example or second one are you working on? – Mehmet SÖĞÜNMEZ Nov 21 '17 at 08:32

2 Answers2

0

Alright there's a bug report for this at https://github.com/zendframework/zf1/issues/665 and a pull request at https://github.com/zendframework/zf1/pull/654. But due EOL they'll not work about it.

So as @zerocrates mentioned you can work around code or just ignore it. This's the code on Zend/Session/SaveHandler/DbTable.php line 338

public function write($id, $data)
{
    $return = false;
    $data = array($this->_modifiedColumn => time(),
                  $this->_dataColumn     => (string) $data);
    $rows = call_user_func_array(array(&$this, 'find'), $this->_getPrimary($id));
    if (count($rows)) {
        $data[$this->_lifetimeColumn] = $this->_getLifetime($rows->current());
        if ($this->update($data, $this->_getPrimary($id, self::PRIMARY_TYPE_WHERECLAUSE))) {
            $return = true;
        }
    } else {
        $data[$this->_lifetimeColumn] = $this->_lifetime;
        if ($this->insert(array_merge($this->_getPrimary($id, self::PRIMARY_TYPE_ASSOC), $data))) {
            $return = true;
        }
    }
    return $return;
}

As you can see it's return false if db can't write. You can edit code base or extend it and return always true.

Why db can't write it? I don't know. Its expecting to work well if your table and config is valid. Its seems you are using one column session due your config so your table have to be like;

CREATE TABLE `session` (
`id` char(32),
`modified` int,
`lifetime` int,
`data` text,
PRIMARY KEY (`id`)
);
  • I don't think write or not is the issue at all. I am debugging that function and I can see the `$data` var coming as an array of values but `$data['data']` only contains: `Zend_Auth|a:1:{s:7:"storage";N;}` which is weird to me, do you have any ideas? – ReynierPM Nov 22 '17 at 16:25
  • Either way still not working and I can't find why. I have tested in PHP 7.1.9 and it works but as soon as I upgrade to 7.1.11 it fails this is driving me crazy – ReynierPM Nov 23 '17 at 03:06
  • I couldn't find anything usefull in 7.1.11 changelog about session. http://www.php.net/ChangeLog-7.php#7.1.11 seems like they made some change on Apache2Handler but i don't think if it's the reason. if you wish take a look: https://bugs.php.net/bug.php?id=75311 – Mehmet SÖĞÜNMEZ Nov 27 '17 at 07:10
  • Anyway there's a something wrong in zf1 session with 7.1 and zend won't fix it. if it's possible upgrade your code. – Mehmet SÖĞÜNMEZ Nov 27 '17 at 07:11
  • Sadly I can't get rid of ZF1 atm but anyway I am not working anymore for the company where I was having the issue. However this is a personal fight because I want to discover what is breaking the application on newest PHP versions. – ReynierPM Nov 27 '17 at 18:55
  • sorry to hear that – Mehmet SÖĞÜNMEZ Nov 28 '17 at 08:42
0

I have faced a similar issue like this before.

Since an update that returns 0 but doesn't throw an exception was still a successful query with no error

Hence the function write will return false instead of true, and PHP 7 requires a true result.

I have fixed that by changing, in Zend/Session/SaveHandler/DbTable.php:

if ($this->update($data, $this->_getPrimary($id, 
self::PRIMARY_TYPE_WHERECLAUSE))) {

To:

if (is_int($this->update($data, $this->_getPrimary($id, 
self::PRIMARY_TYPE_WHERECLAUSE)))) {
Lachu V
  • 1
  • 2
  • I've found such workaround|"fix" in a [PR](https://github.com/zendframework/zf1/pull/654/files) a while ago also in [this post](https://stackoverflow.com/a/46153020/719427) but sadly it does not fix my issue either. Thank you anyway – ReynierPM Nov 30 '17 at 14:00