Seems to be no (easy) way at the to know how old a value fetched is and to check whether it is out of date.
I've made these wrappers so that you can fetch and store values based on a udt returned from get_last_modified_date() which should return a udt of when your data was last changed, and hence needs junking out of the cache.
<?php
function apc_fetch_udt($key){
$g = apc_fetch($key);
if ($g){
list($udt,$val) = $g;
if (get_last_modified_date()<$udt) {
$val = unserialize($val);
return $val;
} else {
apc_delete($key);
}
}
}
function apc_store_udt($key,$g){
$udt = time();
$g = serialize($g);
$apc = array($udt,$g);
apc_store($key, $apc);
}
?>
apc_store
(PECL apc >= 3.0.0)
apc_store — Guardar una variable en caché en el almacén de datos
Descripción
Guarda una variable en caché en el almacén de datos.
Nota: A diferencia de otros mecanismos de PHP, las variables almacenadas al usar apc_store() persistirán entre peticiones (hasta que el valor sea eliminado de la caché).
Parámetros
-
key -
Almacena la variable usando este nombre. Las claves (
keys) son únicas en la caché, por lo que almacenar un segundo valor con la misma clave dada porkeysobrescribirá el valor original. -
var -
La variable a almacenar
-
ttl -
Time To Live (Tiempo de Vida); almacena
varen la caché durantettlsegundos. Después de que pasettl, la variable almacenada será expurgada de la caché (en la siguiente solicitud). Si no se proporcionattl(o sittles 0), el valor persistirá hasta que sea eliminado de la caché manualmente, o si no dejará de existir (al limpiar, reiniciar, etc.). -
values -
Nombres en clave, variables en valor.
Valores devueltos
Devuelve TRUE en caso de éxito o FALSE en caso de error.
La segunda sintaxis devuelve un array con claves de errores.
Ejemplos
Ejemplo #1 Un ejemplo de apc_store()
<?php
$bar = 'BAR';
apc_store('foo', $bar);
var_dump(apc_fetch('foo'));
?>
El resultado del ejemplo sería:
string(3) "BAR"
Ver también
- apc_add() - Poner una nueva variable en caché en el almacén de datos
- apc_fetch() - Traer una variable almacenada desde la caché
- apc_delete() - Elimina una variable almacenada de la caché
Note APC version 3.1.3 there is a bug (http://pecl.php.net/bugs/bug.php?id=16814) that will display a cache slam averted warning for all writes to a cache var that exists. Slam checking can be disabled by setting apc.slam_defense = 0.
if you want to store array of objects in apc use ArrayObject wrapper (PHP5).
<?php
$objs = array();
$objs[] = new TestClass();
$objs[] = new TestClass();
$objs[] = new TestClass();
//Doesn't work
apc_store('objs',$objs,60);
$tmp = apc_fetch('objs');
print_r($tmp);
//Works
apc_store('objs',new ArrayObject($objs),60);
$tmp = apc_fetch('objs');
print_r($tmp->getArrayCopy());
?>
When specifying a ttl (Time-To-Live), you are allowed to use negative values. This causes a stored entry to be invalidated immediately, but note that it will not physically be removed until you read (eg. apc_fetch or apc_exists) it:
<?php
apc_store('testKey', 'testValue', -1); // ... or any negative integer.
// at this point, the key exists physically but is already technically invalidated by the ttl.
$test = apc_fetch('testKey'); // $test equals false.
// at this point, the key no longer exists physically.
?>
Although you could mimic apc_delete with a negative TTL (like when dealing with cookies), note that the difference is that apc_delete actually physically removes the entry.
This example comes in handy when you want to unit-test a class that uses APC. It's faster to use a negative TTL than a positive in combination with a sleep call to test whether the cache entry has actually been deleted. Other than that I can't think of any situations in which you could use this example, but I'm simply pointing out that doing this will not generate Exceptions or errors.
Don't save empty arrays and empty values. Sometimes, you can get wrong apc_exists($someKey) result, that this key doesn't exists.
Note that caching resources is not possible; even if the apc cache doesn't seems to call the serialize / unserialize functions, that doesn't means that resources can be cached!
Small non-working example:
<?php
// Setter code
$r = fopen( '/tmp/test.txt', 'r' );
var_dump( $r );
apc_store( 'test', $r );
?>
<?php
// Getter code
$d = apc_fetch( 'test' );
var_dump( $d );
echo fread( $d, 1024 );
?>
var_dump( $d ) returns Resource #n of type (Unknown). The resource is still here, but unavailable.
It might be interesting to note that storing an object in the cache does not serialize the object, i.e. does not call the __sleep()/__wakeup() or serialize()/unserialize() methods.
Note that the TTL only takes effect when you attempt to access the variable again (at least in my version). That is, just issuing a new request to a page won't clear outdated items -- you have to call apc_fetch on that specific item.
If you call apc_info after the TTL of an item it will still be listed.
This is important if you are expecting items to be cleared to conserve memory.
Note that since APC 3.0.15 or 3.0.16, the time-to-live-feature does not work within the same request (see http://pecl.php.net/bugs/bug.php?id=13331).
be sure that setting FALSE values can be wrong returned from fetch since fetch return FALSE on errors
use apc_store() if you want to find out if the result of apc_delete(), apc_fetch(), apc_add(), ..... is REALLY FALSE or you have a problem with APC.
<?php
if (!apc_fetch('key')) {
if (!apc_store('apc_check', 1, -1)) {
// you have a problem with APC
}
else {
// apc works but variable isn´t set
}
}
?>
It should be noted that apc_store appears to only store one level deep. So if you have an array of arrays, and you store it. When you pull it back out with apc_fetch it will only have the top level row of keys with nulls as the values of each key.
Solution to this, is to serialize the data before storing it in the cache and unserialize it while retrieving from the cache.
