【问题标题】:PHP FPM Docker ZF1: The session has already been started. The session id must be set firstPHP FPM Docker ZF1:会话已经开始。必须先设置会话 id
【发布时间】:2016-11-10 05:07:33
【问题描述】:

在我的开发环境中,我正在尝试用 Docker 替换旧的重型 Vagrant VM,使用 docker-compose:

version: '2'
services:
    nginx:
        build: ./containers/nginx
        networks:
            mm:
                ipv4_address: 172.25.0.101
        environment:
            APPLICATION_ENV: development
        extra_hosts:
            - "mysite.dev:127.0.0.1"
        ports:
            - 80:80
        links:
            - php
        volumes:
            - ../:/srv

    php:
        build: ./containers/php-fpm
        networks:
            mm:
                ipv4_address: 172.25.0.102
        volumes:
            - ../:/srv
        links:
            - memcached
        ports:
            - 9000:9000

    memcached:
        image: memcached:latest
        ports:
            - 1234:11211
        networks:
            mm:
                ipv4_address: 172.25.0.103

networks:
    mm:
        driver: bridge
        ipam:
            driver: default
            config:
                - subnet: 172.25.0.0/24

但是应用程序是用 ZF1 编写的,每当我在 Zend_Session::start() 之后实例化一个 Zend_Session_Namespace 对象时,就会出现以下错误:

Zend_Session_Exception: The session has already been started. The session id must be set first. in /srv/mm/vendor/zendframework/zendframework1/library/Zend/Session.php on line 667

我已经尝试了所有方法,使用VOLUME 设置会话路径,更改session.save_path,一遍又一遍地安装它,但没有任何反应。

【问题讨论】:

    标签: php session zend-framework docker docker-compose


    【解决方案1】:

    在花了很长时间调试这个问题后,我找到了您问题的答案。在您第二次调用Zend_Session::start() 时,ZF 将通过检查会话 ID 是否由 php_ini 设置 session.hash_bits_per_character 定义的正确 hash_bits_per_character 生成来验证会话 ID。

    /**
     * From Zend_Session 
     */
    protected static function _checkId($id)
    {
        $saveHandler = ini_get('session.save_handler');
        if ($saveHandler == 'cluster') { // Zend Server SC, validate only after last dash
            $dashPos = strrpos($id, '-');
            if ($dashPos) {
                $id = substr($id, $dashPos + 1);
            }
        }
    
        $hashBitsPerChar = ini_get('session.hash_bits_per_character');
        if (!$hashBitsPerChar) {
            $hashBitsPerChar = 5; // the default value
        }
        switch($hashBitsPerChar) {
            case 4: $pattern = '^[0-9a-f]*$'; break;
            case 5: $pattern = '^[0-9a-v]*$'; break;
            case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break;
        }
        return preg_match('#'.$pattern.'#', $id);
    }
    

    问题在于,由于某种原因,会话 ID 是使用 hash_bits_per_character = 5 而不是 hash_bits_per_character = 4 生成的。因此,要解决这个问题,您需要做的就是在第一次调用Zend_Session::start() 之前强制设置session.hash_bits_per_character,Zend_Session 将使用正确的模式检查哈希位:

    Zend_Session::setOptions(['hash_bits_per_character' => 5]);
    

    【讨论】:

    • 像魅力一样工作!只有一点点更正,它是hash_bits_per_character,而不是设置选项中的hash_bits_per_char。您可以在应用程序或php.ini 文件中使用session.hash_bits_per_character = 5 进行设置。谢谢大佬!
    • @IgorBrites 用正确的选项编辑了答案(这也节省了我的时间):)
    猜你喜欢
    • 2023-03-23
    • 2019-09-16
    • 2012-05-25
    • 2011-09-09
    • 1970-01-01
    • 2018-12-25
    相关资源
    最近更新 更多