nativeSerialize = ( ini_get( 'apc.serializer' ) !== 'default' ); $this->useIncrTTLArg = version_compare( phpversion( 'apcu' ), '5.1.12', '>=' ); // Avoid back-dated values that expire too soon. In particular, regenerating a hot // key before it expires should never have the end-result of purging that key. Using // the web request time becomes increasingly problematic the longer the request lasts. ini_set( 'apc.use_request_time', '0' ); } protected function doGet( $key, $flags = 0, &$casToken = null ) { $casToken = null; $blob = apcu_fetch( $key . self::KEY_SUFFIX ); $value = $this->nativeSerialize ? $blob : $this->unserialize( $blob ); if ( $value !== false ) { $casToken = $blob; // don't bother hashing this } return $value; } protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) { $blob = $this->nativeSerialize ? $value : $this->getSerialized( $value, $key ); $success = apcu_store( $key . self::KEY_SUFFIX, $blob, $exptime ); return $success; } protected function doAdd( $key, $value, $exptime = 0, $flags = 0 ) { $blob = $this->nativeSerialize ? $value : $this->getSerialized( $value, $key ); $success = apcu_add( $key . self::KEY_SUFFIX, $blob, $exptime ); return $success; } protected function doDelete( $key, $flags = 0 ) { apcu_delete( $key . self::KEY_SUFFIX ); return true; } public function incr( $key, $value = 1, $flags = 0 ) { $result = false; // https://github.com/krakjoe/apcu/issues/166 for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) { $oldCount = apcu_fetch( $key . self::KEY_SUFFIX ); if ( !is_int( $oldCount ) ) { break; } $count = $oldCount + (int)$value; if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) { $result = $count; break; } } return $result; } public function decr( $key, $value = 1, $flags = 0 ) { $result = false; // https://github.com/krakjoe/apcu/issues/166 for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) { $oldCount = apcu_fetch( $key . self::KEY_SUFFIX ); if ( !is_int( $oldCount ) ) { break; } $count = $oldCount - (int)$value; if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) { $result = $count; break; } } return $result; } public function incrWithInit( $key, $exptime, $value = 1, $init = null, $flags = 0 ) { $init = is_int( $init ) ? $init : $value; // Use apcu 5.1.12 $ttl argument if apcu_inc() will initialize to $init: // https://www.php.net/manual/en/function.apcu-inc.php if ( $value === $init && $this->useIncrTTLArg ) { /** @noinspection PhpMethodParametersCountMismatchInspection */ $result = apcu_inc( $key . self::KEY_SUFFIX, $value, $success, $exptime ); } else { $result = false; for ( $i = 0; $i < self::$CAS_MAX_ATTEMPTS; ++$i ) { $oldCount = apcu_fetch( $key . self::KEY_SUFFIX ); if ( $oldCount === false ) { $count = (int)$init; if ( apcu_add( $key . self::KEY_SUFFIX, $count, $exptime ) ) { $result = $count; break; } } elseif ( is_int( $oldCount ) ) { $count = $oldCount + (int)$value; if ( apcu_cas( $key . self::KEY_SUFFIX, $oldCount, $count ) ) { $result = $count; break; } } else { break; } } } return $result; } }