mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-24 17:04:14 +01:00
* APCu/PHP7: fixed not used APCu under PHP7, as it has no APC compatible interface
Apcu class is basicly a copy of Apc, but as its methods are called quite a lot, I dont want to add the overhad of checking to call apc_ or apcu_ on every call, anyway APC died with PHP 5.5 so we can remove Apcu class once we no longer support PHP 5.4
This commit is contained in:
parent
5d90b8f16d
commit
28731fbbb9
@ -555,7 +555,7 @@ class Cache
|
|||||||
}
|
}
|
||||||
if (!$providers[$level] && $log_not_found) error_log(__METHOD__."($level) no provider found ($reason)!".function_backtrace());
|
if (!$providers[$level] && $log_not_found) error_log(__METHOD__."($level) no provider found ($reason)!".function_backtrace());
|
||||||
}
|
}
|
||||||
//error_log(__METHOD__."($level) = ".array2string($providers[$level]).', cache_provider='.array2string($GLOBALS['egw_info']['server']['cache_provider_'.strtolower($level)]));
|
error_log(__METHOD__."($level) = ".array2string($providers[$level]).', cache_provider='.array2string($GLOBALS['egw_info']['server']['cache_provider_'.strtolower($level)]));
|
||||||
return $providers[$level];
|
return $providers[$level];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,11 +730,13 @@ class Cache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setting apc as default provider, if apc_fetch function exists AND further checks in Api\Cache\Apc recommed it
|
// setting apc(u) as default provider, if apc(u)_fetch function exists AND further checks in Api\Cache\Apc(u) recommed it
|
||||||
if (is_null(Cache::$default_provider))
|
if (is_null(Cache::$default_provider))
|
||||||
{
|
{
|
||||||
Cache::$default_provider = function_exists('apc_fetch') && Cache\Apc::available() ?
|
Cache::$default_provider =
|
||||||
'EGroupware\Api\Cache\Apc' : 'EGroupware\Api\Cache\Files';
|
function_exists('apcu_fetch') && Cache\Apcu::available() ? 'EGroupware\Api\Cache\Apcu' :
|
||||||
|
(function_exists('apc_fetch') && Cache\Apc::available() ? 'EGroupware\Api\Cache\Apc' :
|
||||||
|
'EGroupware\Api\Cache\Files');
|
||||||
}
|
}
|
||||||
|
|
||||||
//error_log('Cache::$default_provider='.array2string(Cache::$default_provider));
|
//error_log('Cache::$default_provider='.array2string(Cache::$default_provider));
|
||||||
|
184
api/src/Cache/Apcu.php
Normal file
184
api/src/Cache/Apcu.php
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* EGroupware API: Caching provider storing data in PHP's APCu extension
|
||||||
|
*
|
||||||
|
* @link http://www.egroupware.org
|
||||||
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
|
* @package api
|
||||||
|
* @subpackage cache
|
||||||
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @copyright (c) 2010-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace EGroupware\Api\Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caching provider storing data in PHP's APCu extension / shared memory.
|
||||||
|
*
|
||||||
|
* The provider concats all $keys with '::' to get a single string.
|
||||||
|
*
|
||||||
|
* This provider is used by default, if it is available or explicit enabled in your header.inc.php:
|
||||||
|
* $GLOBALS['egw_info']['server']['cache_provider_instance'] = array('EGroupware\Api\Cache\Apc');
|
||||||
|
* and optional also $GLOBALS['egw_info']['server']['cache_provider_tree'] (defaults to instance)
|
||||||
|
*
|
||||||
|
* APC(u) and CLI:
|
||||||
|
* --------------
|
||||||
|
* APC(u) is not enabled by default for CLI (apc.enable_cli), nor would it access same shared memory!
|
||||||
|
* It makes no sense to fall back to files cache, as this is probably quite outdated,
|
||||||
|
* if PHP via Webserver uses APC. Better to use no cache at all.
|
||||||
|
* Api\Cache::get*() will return NULL for not found and Api\Cache::[un]set*()
|
||||||
|
* false for not being able to (un)set anything.
|
||||||
|
* It also does not make sense to report failure by throwing an Exception and filling
|
||||||
|
* up cron logs.
|
||||||
|
* --> if APC(u) is available for Webserver, we report availability for CLI too,
|
||||||
|
* but use no cache at all!
|
||||||
|
*/
|
||||||
|
class Apcu extends Base implements Provider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor, eg. opens the connection to the backend
|
||||||
|
*
|
||||||
|
* @throws Exception if connection to backend could not be established
|
||||||
|
* @param array $params eg. array('localhost'[,'localhost:11211',...])
|
||||||
|
*/
|
||||||
|
function __construct(array $params)
|
||||||
|
{
|
||||||
|
if (!function_exists('apcu_fetch')) // apc >= 3.0
|
||||||
|
{
|
||||||
|
throw new Exception (__METHOD__.'('.array2string($params).") No function apcu_fetch()!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if APC is available for caching user data
|
||||||
|
*
|
||||||
|
* Default shared memory size of 32M is just enough for the byte code cache,
|
||||||
|
* but not for caching user data, we only use APC by default if we have at least 64M.
|
||||||
|
*
|
||||||
|
* @return boolean true: apc available, false: not
|
||||||
|
*/
|
||||||
|
public static function available()
|
||||||
|
{
|
||||||
|
if (($available = (bool)ini_get('apc.enabled') && function_exists('apcu_fetch')))
|
||||||
|
{
|
||||||
|
$size = ini_get('apc.shm_size');
|
||||||
|
|
||||||
|
switch(strtoupper(substr($size, -1)))
|
||||||
|
{
|
||||||
|
case 'G':
|
||||||
|
$size *= 1024;
|
||||||
|
case 'M':
|
||||||
|
$size *= 1024;
|
||||||
|
case 'K':
|
||||||
|
$size *= 1024;
|
||||||
|
}
|
||||||
|
$size *= ini_get('apc.shm_segments');
|
||||||
|
|
||||||
|
// only cache in APC, if we have at least 64M available (default is 32M)
|
||||||
|
$available = $size >= 67108864;
|
||||||
|
}
|
||||||
|
//error_log(__METHOD__."() size=$size returning ".array2string($available));
|
||||||
|
return $available;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores some data in the cache, if it does NOT already exists there
|
||||||
|
*
|
||||||
|
* @param array $keys eg. array($level,$app,$location)
|
||||||
|
* @param mixed $data
|
||||||
|
* @param int $expiration =0
|
||||||
|
* @return boolean true on success, false on error, incl. key already exists in cache
|
||||||
|
*/
|
||||||
|
function add(array $keys,$data,$expiration=0)
|
||||||
|
{
|
||||||
|
return apcu_add(self::key($keys),$data,$expiration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores some data in the cache
|
||||||
|
*
|
||||||
|
* @param array $keys eg. array($level,$app,$location)
|
||||||
|
* @param mixed $data
|
||||||
|
* @param int $expiration =0
|
||||||
|
* @return boolean true on success, false on error
|
||||||
|
*/
|
||||||
|
function set(array $keys,$data,$expiration=0)
|
||||||
|
{
|
||||||
|
return apcu_store(self::key($keys),$data,$expiration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get some data from the cache
|
||||||
|
*
|
||||||
|
* @param array $keys eg. array($level,$app,$location)
|
||||||
|
* @return mixed data stored or NULL if not found in cache
|
||||||
|
*/
|
||||||
|
function get(array $keys)
|
||||||
|
{
|
||||||
|
$success = null;
|
||||||
|
$data = apcu_fetch($key=self::key($keys),$success);
|
||||||
|
|
||||||
|
if (!$success)
|
||||||
|
{
|
||||||
|
//error_log(__METHOD__."(".array2string($keys).") key='$key' NOT found!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//error_log(__METHOD__."(".array2string($keys).") key='$key' found ".bytes(serialize($data))." bytes).");
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete some data from the cache
|
||||||
|
*
|
||||||
|
* @param array $keys eg. array($level,$app,$location)
|
||||||
|
* @return boolean true on success, false on error (eg. $key not set)
|
||||||
|
*/
|
||||||
|
function delete(array $keys)
|
||||||
|
{
|
||||||
|
return apcu_delete(self::key($keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all data under given keys
|
||||||
|
*
|
||||||
|
* @param array $keys eg. array($level,$app,$location)
|
||||||
|
* @return boolean true on success, false on error (eg. $key not set)
|
||||||
|
*/
|
||||||
|
function flush(array $keys)
|
||||||
|
{
|
||||||
|
// APCu > 5 has APCUIterator
|
||||||
|
if (class_exists('APCUIterator'))
|
||||||
|
{
|
||||||
|
$iterator = new \APCUIterator($preg='/^'.preg_quote(self::key($keys).'/'));
|
||||||
|
}
|
||||||
|
// APC >= 3.1.1, but also seems to be missing if apc is disabled eg. for cli
|
||||||
|
elseif(class_exists('APCIterator'))
|
||||||
|
{
|
||||||
|
$iterator = new \APCIterator('user', $preg='/^'.preg_quote(self::key($keys).'/'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (function_exists('apcu_clear_cache')) apcu_clear_cache ();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach($iterator as $item)
|
||||||
|
{
|
||||||
|
//error_log(__METHOD__."(".array2string($keys).") preg='$preg': calling apcu_delete('$item[key]')");
|
||||||
|
apcu_delete($item['key']);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a single key from $keys
|
||||||
|
*
|
||||||
|
* @param array $keys
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function key(array $keys)
|
||||||
|
{
|
||||||
|
return implode('::',$keys);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user