session_set_start_handler выдаёт предупреждения - PullRequest
0 голосов
/ 08 октября 2018

Я пишу свой собственный обработчик сеансов, как показано ниже, чтобы сделать Aerospike менеджером сеансов.Однако он выдает предупреждения об обработчике сеанса.

Warning: session_start(): Cannot find save handler '' - session startup failed in /var/www/session.php on line 165

Я установил значения session.save_path и session.save_handler в "" в php.ini, как я хочууправлять хранением и извлечением данных сеанса самостоятельно с помощью приведенного ниже класса.

ПРИМЕЧАНИЕ: Я могу использовать обработку сеансов аэроспайков по умолчанию, но она сохраняет данные сеансов в байтах (шестнадцатеричный формат), я могу 'Я не могу использовать его как есть, так как другие приложения также должны читать эти данные, поэтому я пытаюсь сохранить данные в виде строки в кодировке json.

Странное поведение заключается в том, что метод close всегда вызывается приЗавершение работы сценария, даже если возвращаемое значение session_set_save_handler равно false!

Это иногда работает без ошибок, а иногда выдает предупреждение, показанное выше.Не уверен, чего не хватает.

Код:

<code><?php
ini_set( 'display_errors', 1 );
ini_set( 'error_reporting', E_ALL );

define('SESS_ID', '66ac548234f96b48b42e18b2d3d7b73a3f1aceb01fa4c20647d3dcaa055b5099');

class MySessionHandler implements SessionHandlerInterface {
    private $database = null;
    private $recordKey = null;

    public function __construct(){
        $this->init();
    }

    private function init() {
        $this->database = new \Aerospike(
            [
                "hosts" => [
                    0 => [
                        "addr" => "IP_HERE",
                        "port" => 3000
                    ]
                ]
            ], false);
        $this->recordKey = $this->database->initKey( 'cache', 'data', SESS_ID);
    }

    private function isConnected() : bool {
        return ( $this->database instanceof \Aerospike ) && $this->database->isConnected();
    }

    public function open($savepath = '', $id = ''){
        // If successful

        if( is_null($this->database) ) {
            $this->init();
        }

        $status = $this->database->get($this->recordKey, $data);

        if ($status == \Aerospike::OK) {
            $data = json_decode($data['bins']['PHP_SESSION'], 1);

            if( !is_array($data) ) {
                $data = [];
            }
        } else {
            $data = [];
        }

        return true;
    }

    public function read($id)
    {
        if( is_null($this->database) ) {
            $this->init();
        }

        $status = $this->database->get($this->recordKey, $data);

        if ($status == \Aerospike::OK) {
            $data = json_decode($data['bins']['PHP_SESSION'], 1);

            if( !is_array($data) ) {
                $data = [];
            }
        } else {
            $data = [];
        }

        $_SESSION = $data;

        return json_encode($data);
    }

    public function write($id, $dataNode)
    {
        if( is_null($this->database) ) {
            $this->init();
        }

        $data = false;

        if( $this->isConnected() ) {
            $bins = [
                "PHP_SESSION" => json_encode($_SESSION)
            ];

            $status = $this->database->put( $this->recordKey, $bins );

            if ($status == \Aerospike::OK) {
                $data = true;
            } else {
                // error while saving data, log it
            }
        }

        return $data;
    }

    public function destroy($id)
    {
        $removeStatus = false;

        if( $this->isConnected() ) {
            $status = $this->database->remove( $this->recordKey );

            if ($status == \Aerospike::OK) {
                $removeStatus = true;
            } else {
                // error while saving data, log it
            }
        }

        return $removeStatus;
    }

    public function close(){
        // Close the database connection
        if($this->isConnected() && $this->database->close()){
            // Return True
            return true;
        }
        // Return False
        return false;
    }

    public function gc($max)
    {
        return 0;
    }

    public function __destruct()
    {
        $this->close();
    }

}

$s = new MySessionHandler();

// Set handler to overide SESSION
$newSession = session_set_save_handler($s, true);

var_dump($newSession); // this returns false sometimes and throws a warning

register_shutdown_function('session_write_close');

session_id(SESS_ID);
session_start();

$_SESSION['dfc'] = 'xdc1';
//unset($_SESSION['dfc']);

pr($_SESSION);

unset($s);

function pr($data) {
    if( is_object($data) ) {
       // $data = serialize($data);
    }

    echo '<pre>' . var_export($data, 1) . '
';}

Эти предупреждения появляются периодически, и я не уверен, что может быть причиной этого.Любая помощь будет оценена.

1 Ответ

0 голосов
/ 08 октября 2018

PHP-клиент для Aerospike поставляется с обработчиком сессии .Установите session.save_handler=aerospike.См. php.ini опции модуля.

Если вы пишете свой собственный обработчик сеанса

  • Не устанавливать session.save_handler=''.Вы хотите закомментировать это в своем php.ini вместо этого, потому что он загружается и выполняется первым (перед вашим скриптом), и это бессмысленно.Нет такого обработчика.Это должно подавить предупреждение.
  • Остерегайтесь нулевых байтов.Строки PHP могут иметь их посередине, но строки Aerospike на этом заканчиваются, поэтому в этот момент они усекаются.Прочитайте документацию по Обработка неподдерживаемых типов , поэтому вам предоставляется класс оболочки \Aerospike\Bytes.
...