Creación / escritura de archivos PHP dentro de destructor

Cuando se llama a file_put_contents() dentro de un destructor, hace que los archivos se escriban en SERVER_ROOT … (¡ SERVER_ROOT !) ¿Soluciones SERVER_ROOT ?

tldr:

Quiero almacenar en caché una matriz, que probablemente contenga instancias de clase serializadas. Me imaginé, por ahora, escribiría una clase que implemente el caché utilizando unserialize()/file_get_contents() y serialize()/file_put_contents() y luego ocultaría su funcionalidad detrás de una clase Cache más genérica. (No sé si el host de mi cliente tendrá memoria compartida o PEAR, etc.)

 filename = $filename; $this->load(); } function __destruct() { // Calling file_put_contents within a destructor causes files to be written in SERVER_ROOT... $this->flush(); } private function load() { if(!file_exists($this->filename)) { $this->data = array(); } else { $this->data = unserialize(file_get_contents($this->filename)); // todo } $this->dirty = false; } private function persist() { file_put_contents($this->filename, serialize($this->data)); $this->dirty = false; } public function get($key) { if(array_key_exists($key, $this->data)) { return $this->data[$key]; } else { return false; } } public function set($key, $value) { if(!array_key_exists($key, $this->data)) { $dirty = true; } else if($this->data[$key] !== $value) { $dirty = true; } if($dirty) { $this->dirty = true; $this->data[$key] = $value; } } public function flush() { if($this->dirty) { $this->persist(); } } } $cache = new CacheFile("cache"); var_dump( $cache->get("item") ); $cache->set("item", 42); //$cache->flush(); var_dump( $cache->get("item") ); ?> 

Ver la llamada a flush() en el destructor? Realmente no quiero tener la función public flush() porque es específica de la implementación.

Supongo que no ha especificado una ruta completa en $this->filename .

En algunas configuraciones de PHP, cuando se invocan destructores (en la fase de cierre de scripts), el directorio de trabajo puede cambiar. Las rutas relativas se resuelven en otra ubicación entonces.

Compare con la nota relacionada en el Manual de PHP :

Nota:

Los destructores llamados durante el cierre del script tienen encabezados HTTP ya enviados. El directorio de trabajo en la fase de cierre del script puede ser diferente con algunos SAPI (por ejemplo, Apache).

Si haces ese camino absoluto, funcionará como se espera.

Editar: A medida que actualiza su código, esta es una forma sencilla de asegurarse de tener la ruta absoluta:

 $cache = new CacheFile(realpath("cache")); 

O mucho mejor dentro del constructor:

 $this->filename = realpath($filename); 

Puede crear un identificador de archivo en load() que puede usar en __destruct() o flush() .

¿Estás usando una ruta relativa como $ filename? Me gustaría pasar en una ruta absoluta hacia donde desea el archivo. Si quieres que sea relativo a donde se encuentra tu script, podrías usar algo como:

 $filename = dirname($_SERVER['SCRIPT_FILENAME']) . PATH_SEPARATOR . $filename;