Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1244162
cache.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Nov 20, 10:43 PM
Size
13 KB
Mime Type
text/x-php
Expires
Sat, Nov 22, 10:43 PM (1 d, 6 h)
Engine
blob
Format
Raw Data
Handle
809432
Attached To
rINP In-Portal
cache.php
View Options
<?php
/**
* @version $Id: cache.php 14331 2011-05-20 10:11:45Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined
(
'FULL_PATH'
)
or
die
(
'restricted access!'
);
/**
* Manager of all implemented caching handlers
*
*/
class
kCache
extends
kBase
{
/**
* Object of cache handler
*
* @var FakeCacheHandler
*/
var
$_handler
=
null
;
/**
* Part of what we retrieve will be stored locally (per script run) not to bother memcache a lot
*
* @var Array
*/
var
$_localStorage
=
Array
();
/**
* What type of caching is being used
*
* @var int
*/
var
$cachingType
=
CACHING_TYPE_NONE
;
/**
* Cache usage statistics (per script run)
*
* @var Array
*/
var
$statistics
=
Array
();
/**
* Debug cache usage
*
* @var bool
*/
var
$debugCache
=
false
;
/**
* Displays cache usage statistics
*
* @var bool
*/
var
$displayCacheStatistics
=
false
;
/**
* Site key name
* Prepended to each cached key name
*
* @var string
*/
var
$siteKeyName
=
''
;
/**
* Site key value
* Prepended to each cached key name
*
* @var string
*/
var
$siteKeyValue
=
null
;
function
kCache
()
{
parent
::
kBase
();
$this
->
siteKeyName
=
'site_serial:'
.
crc32
(
SQL_TYPE
.
'://'
.
SQL_USER
.
':'
.
SQL_PASS
.
'@'
.
SQL_SERVER
.
':'
.
TABLE_PREFIX
.
':'
.
SQL_DB
);
// get cache handler class to use
if
(
array_key_exists
(
'CacheHandler'
,
$GLOBALS
[
'vars'
])
&&
$GLOBALS
[
'vars'
][
'CacheHandler'
])
{
// for advanced users, who want to save one SQL on each page load
$handler_class
=
$GLOBALS
[
'vars'
][
'CacheHandler'
]
.
'CacheHandler'
;
}
else
{
$handler_class
=
$this
->
Application
->
ConfigValue
(
'CacheHandler'
)
.
'CacheHandler'
;
}
// defined cache handler doen't exist -> use default
if
(!
class_exists
(
$handler_class
))
{
$handler_class
=
'FakeCacheHandler'
;
}
$handler
=
new
$handler_class
();
if
(!
$handler
->
isWorking
())
{
// defined cache handler is not working -> use default
trigger_error
(
'Failed to initialize "<strong>'
.
$handler_class
.
'</strong>" caching handler.'
,
E_USER_WARNING
);
$handler
=
new
FakeCacheHandler
();
}
elseif
(
$this
->
Application
->
isDebugMode
()
&&
(
$handler
->
cachingType
==
CACHING_TYPE_MEMORY
))
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Memory Caching: "<strong>'
.
$handler_class
.
'</strong>"'
);
}
$this
->
_handler
=&
$handler
;
$this
->
cachingType
=
$handler
->
cachingType
;
$this
->
debugCache
=
$handler
->
cachingType
==
CACHING_TYPE_MEMORY
&&
$this
->
Application
->
isDebugMode
();
$this
->
displayCacheStatistics
=
defined
(
'DBG_CACHE'
)
&&
DBG_CACHE
&&
$this
->
Application
->
isDebugMode
();
}
/**
* Returns caching type of current storage engine
*
* @return int
*/
function
getCachingType
()
{
return
$this
->
cachingType
;
}
/**
* Stores value to cache
*
* @param string $name
* @param mixed $value
* @param int $expires cache record expiration time in seconds
*/
function
setCache
(
$name
,
$value
,
$expiration
)
{
$name
=
$this
->
prepareKeyName
(
$name
);
$this
->
_localStorage
[
$name
]
=
$value
;
return
$this
->
_handler
->
set
(
$name
,
$value
,
$expiration
);
}
/**
* Returns value from cache
*
* @param string $name
* @param bool $store_locally store data locally after retrieved
* @param bool $replace_serials
* @return mixed
*/
function
getCache
(
$name
,
$store_locally
=
true
,
$replace_serials
=
true
)
{
$name
=
$this
->
prepareKeyName
(
$name
,
$replace_serials
);
if
(
$store_locally
)
{
if
(
array_key_exists
(
$name
,
$this
->
_localStorage
))
{
if
(
$this
->
displayCacheStatistics
)
{
$this
->
setStatistics
(
$name
,
$this
->
_localStorage
[
$name
]);
}
return
$this
->
_localStorage
[
$name
];
}
}
$res
=
$this
->
_handler
->
get
(
$name
);
if
(
$replace_serials
&&
$this
->
debugCache
)
{
// don't display subsequent serial cache retrievals (ones, that are part of keys)
if
(
is_array
(
$res
))
{
$this
->
Application
->
Debugger
->
appendHTML
(
'Restoring key "'
.
$name
.
'". Type: '
.
gettype
(
$res
)
.
'.'
);
}
else
{
$res_display
=
strip_tags
(
$res
);
if
(
strlen
(
$res_display
)
>
200
)
{
$res_display
=
substr
(
$res_display
,
0
,
50
)
.
' ...'
;
}
$this
->
Application
->
Debugger
->
appendHTML
(
'Restoring key "'
.
$name
.
'" resulted ['
.
$res_display
.
']'
);
}
}
if
(
$store_locally
&&
(
$res
!==
false
))
{
$this
->
_localStorage
[
$name
]
=
$res
;
if
(
$this
->
displayCacheStatistics
)
{
$this
->
setStatistics
(
$name
,
$res
);
}
}
return
$res
;
}
/**
* Deletes value from cache
*
* @param string $name
* @return mixed
*/
function
delete
(
$name
)
{
$name
=
$this
->
prepareKeyName
(
$name
);
unset
(
$this
->
_localStorage
[
$name
]);
return
$this
->
_handler
->
delete
(
$name
);
}
/**
* Reset's all memory cache at once
*/
function
reset
()
{
// don't check for enabled, because we maybe need to reset cache anyway
if
(
$this
->
cachingType
==
CACHING_TYPE_TEMPORARY
)
{
return
;
}
$site_key
=
$this
->
_cachePrefix
(
true
);
$this
->
_handler
->
set
(
$site_key
,
$this
->
_handler
->
get
(
$site_key
)
+
1
);
}
/**
* Replaces serials and adds unique site prefix to cache variable name
*
* @param string $name
* @param bool $replace_serials
* @return string
*/
function
prepareKeyName
(
$name
,
$replace_serials
=
true
)
{
// replace serials in key name
if
(
$replace_serials
&&
preg_match_all
(
'/
\[
%(.*?)%
\]
/'
,
$name
,
$regs
))
{
// [%LangSerial%] - prefix-wide serial in case of any change in "lang" prefix
// [%LangIDSerial:5%] - one id-wide serial in case of data, associated with given id was changed
// [%CiIDSerial:ItemResourceId:5%] - foreign key-based serial in case of data, associated with given foreign key was changed
foreach
(
$regs
[
1
]
as
$serial_name
)
{
$name
=
str_replace
(
'[%'
.
$serial_name
.
'%]'
,
'['
.
$serial_name
.
'='
.
$this
->
getCache
(
$serial_name
,
true
,
false
)
.
']'
,
$name
);
}
}
if
(
$this
->
cachingType
==
CACHING_TYPE_TEMPORARY
)
{
return
$name
;
}
// add site-wide prefix to key
return
$this
->
_cachePrefix
()
.
$name
;
}
/**
* Returns site-wide caching prefix
*
* @param bool $only_site_key_name
* @return string
*/
function
_cachePrefix
(
$only_site_key_name
=
false
)
{
if
(
$only_site_key_name
)
{
return
$this
->
siteKeyName
;
}
if
(
!
isset
(
$this
->
siteKeyValue
)
)
{
$this
->
siteKeyValue
=
$this
->
_handler
->
get
(
$this
->
siteKeyName
);
if
(!
$this
->
siteKeyValue
)
{
$this
->
siteKeyValue
=
1
;
$this
->
_handler
->
set
(
$this
->
siteKeyName
,
$this
->
siteKeyValue
);
}
}
return
"{$this->siteKeyName}:{$this->siteKeyValue}:"
;
}
function
setStatistics
(
$name
,
$found
)
{
if
(
strpos
(
$name
,
']:'
)
!==
false
)
{
list
(
$cache_name
,
$name
)
=
explode
(
']:'
,
$name
,
2
);
}
else
{
$cache_name
=
'-'
;
}
if
(!
array_key_exists
(
$cache_name
,
$this
->
statistics
))
{
$this
->
statistics
[
$cache_name
]
=
Array
();
}
if
(!
array_key_exists
(
$name
,
$this
->
statistics
[
$cache_name
]))
{
$this
->
statistics
[
$cache_name
][
$name
]
=
Array
();
}
$status_key
=
$found
?
'found'
:
'not_found'
;
if
(!
isset
(
$this
->
statistics
[
$cache_name
][
$name
][
$status_key
]))
{
$this
->
statistics
[
$cache_name
][
$name
][
$status_key
]
=
0
;
}
$this
->
statistics
[
$cache_name
][
$name
][
$status_key
]++;
}
/**
* Returns storage size in bytes
*
* @return int
*/
function
getStorageSize
()
{
return
strlen
(
serialize
(
$this
->
_localStorage
)
);
}
function
printStatistics
()
{
$cache_size
=
$this
->
getStorageSize
();
$this
->
Application
->
Debugger
->
appendHTML
(
'<strong>Cache Size:</strong> '
.
formatSize
(
$cache_size
)
.
' ('
.
$cache_size
.
')'
);
foreach
(
$this
->
statistics
as
$cache_name
=>
$cache_data
)
{
foreach
(
$cache_data
as
$key
=>
$value
)
{
if
(!
array_key_exists
(
'found'
,
$value
)
||
$value
[
'found'
]
==
1
)
{
// remove cached records, that were used only 1 or 2 times
unset
(
$this
->
statistics
[
$cache_name
][
$key
]);
}
}
}
print_pre
(
$this
->
statistics
,
'Cache Statistics:'
);
}
}
class
FakeCacheHandler
{
var
$cachingType
=
CACHING_TYPE_TEMPORARY
;
function
FakeCacheHandler
()
{
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function
get
(
$name
)
{
return
false
;
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function
set
(
$name
,
$value
,
$expiration
=
0
)
{
return
true
;
}
/**
* Deletes key from cach
*
* @param string $name
* @return bool
*/
function
delete
(
$name
)
{
return
true
;
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function
isWorking
()
{
return
true
;
}
}
class
MemcacheCacheHandler
{
var
$_enabled
=
false
;
/**
* Memcache connection
*
* @var Memcache
*/
var
$_handler
=
null
;
var
$cachingType
=
CACHING_TYPE_MEMORY
;
function
MemcacheCacheHandler
()
{
if
(
array_key_exists
(
'MemcacheServers'
,
$GLOBALS
[
'vars'
]))
{
// for advanced users, who want to save one SQL on each page load
$memcached_servers
=
$GLOBALS
[
'vars'
][
'MemcacheServers'
];
}
else
{
$application
=&
kApplication
::
Instance
();
$memcached_servers
=
$application
->
ConfigValue
(
'MemcacheServers'
);
}
if
(
$memcached_servers
&&
class_exists
(
'Memcache'
))
{
$this
->
_enabled
=
true
;
$this
->
_handler
=
new
Memcache
();
$servers
=
explode
(
';'
,
$memcached_servers
);
foreach
(
$servers
as
$server
)
{
if
(
preg_match
(
'/(.*):([
\d
]+)$/'
,
$server
,
$regs
)
)
{
// "hostname:port" OR "unix:///path/to/socket:0"
$server
=
$regs
[
1
];
$port
=
$regs
[
2
];
}
else
{
$port
=
11211
;
}
$this
->
_handler
->
addServer
(
$server
,
$port
);
}
// verify, that memcache server is working
if
(!
$this
->
_handler
->
set
(
'test'
,
1
))
{
$this
->
_enabled
=
false
;
}
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function
get
(
$name
)
{
return
$this
->
_handler
->
get
(
$name
);
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function
set
(
$name
,
$value
,
$expiration
=
0
)
{
// 0 - don't use compression
return
$this
->
_handler
->
set
(
$name
,
$value
,
0
,
$expiration
);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function
delete
(
$name
)
{
return
$this
->
_handler
->
delete
(
$name
,
0
);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function
isWorking
()
{
return
$this
->
_enabled
;
}
}
class
ApcCacheHandler
{
var
$_enabled
=
false
;
var
$cachingType
=
CACHING_TYPE_MEMORY
;
function
ApcCacheHandler
()
{
$this
->
_enabled
=
function_exists
(
'apc_fetch'
);
// verify, that apc is working
if
(
$this
->
_enabled
&&
!
$this
->
set
(
'test'
,
1
))
{
$this
->
_enabled
=
false
;
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function
get
(
$name
)
{
return
apc_fetch
(
$name
);
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function
set
(
$name
,
$value
,
$expiration
=
0
)
{
return
apc_store
(
$name
,
$value
,
$expiration
);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function
delete
(
$name
)
{
return
apc_delete
(
$name
);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function
isWorking
()
{
return
$this
->
_enabled
;
}
}
class
XCacheCacheHandler
{
var
$_enabled
=
false
;
var
$cachingType
=
CACHING_TYPE_MEMORY
;
function
XCacheCacheHandler
()
{
$this
->
_enabled
=
function_exists
(
'xcache_get'
);
// verify, that xcache is working
if
(
$this
->
_enabled
&&
!
$this
->
set
(
'test'
,
1
))
{
$this
->
_enabled
=
false
;
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function
get
(
$name
)
{
return
xcache_isset
(
$name
)
?
xcache_get
(
$name
)
:
false
;
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function
set
(
$name
,
$value
,
$expiration
=
0
)
{
return
xcache_set
(
$name
,
$value
,
$expiration
);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function
delete
(
$name
)
{
return
xcache_unset
(
$name
);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function
isWorking
()
{
return
$this
->
_enabled
;
}
}
Event Timeline
Log In to Comment