96 '@phan-var SessionManager $manager';
97 if ( self::$instance ) {
98 $manager->setupPHPSessionHandler( self::$instance );
103 if ( defined(
'MW_NO_SESSION_HANDLER' ) ) {
104 throw new \BadMethodCallException(
'MW_NO_SESSION_HANDLER is defined' );
108 self::$instance =
new self(
$manager );
111 session_write_close();
114 AtEase::suppressWarnings();
117 ini_set(
'session.use_cookies', 0 );
123 session_cache_limiter(
'' );
126 PhpSessionSerializer::setSerializeHandler();
130 session_set_save_handler( self::$instance,
true );
132 AtEase::restoreWarnings();
209 if ( self::$instance !== $this ) {
210 throw new \UnexpectedValueException( __METHOD__ .
': Wrong instance called!' );
212 if ( !$this->enable ) {
213 throw new \BadMethodCallException(
'Attempt to use PHP session management' );
216 $session = $this->getSessionManager()->getSessionById( $id,
false );
223 $data = iterator_to_array( $session );
224 $this->sessionFieldCache[$id] = $data;
225 return (
string)PhpSessionSerializer::encode( $data );
237 array_walk_recursive( $value,
static function ( $val ) use ( &$result ) {
257 public function write( $id, $dataStr ) {
258 if ( self::$instance !== $this ) {
259 throw new \UnexpectedValueException( __METHOD__ .
': Wrong instance called!' );
261 if ( !$this->enable ) {
262 throw new \BadMethodCallException(
'Attempt to use PHP session management' );
265 $session = $this->getSessionManager()->getSessionById( $id,
true );
269 $this->logger->warning(
270 __METHOD__ .
': Session "{session}" cannot be loaded, skipping write.',
278 $data = PhpSessionSerializer::decode( $dataStr );
279 if ( $data ===
null ) {
287 $cache = $this->sessionFieldCache[$id] ?? [];
288 foreach ( $data as $key => $value ) {
289 if ( !array_key_exists( $key, $cache ) ) {
290 if ( $session->exists( $key ) ) {
292 $this->logger->warning(
293 __METHOD__ .
": Key \"$key\" added in both Session and \$_SESSION!"
297 $session->set( $key, $value );
300 } elseif ( $cache[$key] === $value ) {
303 $this->valueContainsAnyObject( $cache[$key] ) &&
304 $this->valueContainsAnyObject( $value ) &&
305 PhpSessionSerializer::encode( [ $key => $cache[$key] ] ) ===
306 PhpSessionSerializer::encode( [ $key => $value ] )
312 } elseif ( !$session->exists( $key ) ) {
314 $this->logger->warning(
315 __METHOD__ .
": Key \"$key\" deleted in Session and changed in \$_SESSION!"
317 $session->set( $key, $value );
319 } elseif ( $cache[$key] === $session->get( $key ) ) {
321 $session->set( $key, $value );
325 $this->logger->warning(
326 __METHOD__ .
": Key \"$key\" changed in both Session and \$_SESSION!"
332 PhpSessionSerializer::setLogger(
new NullLogger() );
333 foreach ( $cache as $key => $value ) {
334 if ( !array_key_exists( $key, $data ) && $session->exists( $key ) &&
335 PhpSessionSerializer::encode( [ $key =>
true ] )
337 if ( $value === $session->get( $key ) ) {
339 $session->remove( $key );
343 $this->logger->warning(
344 __METHOD__ .
": Key \"$key\" changed in Session and deleted in \$_SESSION!"
349 PhpSessionSerializer::setLogger( $this->logger );
355 foreach ( $changed as $key ) {
356 $this->logger->warning(
"Something wrote to \$_SESSION['$key']!" );
361 $this->sessionFieldCache[$id] = iterator_to_array( $session );
377 if ( self::$instance !== $this ) {
378 throw new \UnexpectedValueException( __METHOD__ .
': Wrong instance called!' );
380 if ( !$this->enable ) {
381 throw new \BadMethodCallException(
'Attempt to use PHP session management' );
383 $session = $this->getSessionManager()->getSessionById( $id,
false );