PHP tiene métodos mágicos:
__get($property)
vamos a implementar el acceso de un $ propiedad sobre un objeto
__set($property, $value)
vamos a implementar la asignación de un $ propiedad sobre un objeto
PHP puede serializar variables:
serialize($variable)
devuelve una representación de cadena de la variable
unserialize($string)
retorna una variable de una cadena
PHP puede manejar archivos, con una gestión de acceso concurrente:
fopen($file, 'c+')
abre un archivo con opciones de bloqueo de asesoramiento habilitado (le permiten usar rebaño)
flock($descriptor, LOCK_SH)
toma un bloqueo compartido (para lectura)
flock($descriptor, LOCK_EX)
toma un correo Bloqueo xclusivo (para escritura)
Por lo tanto, la forma más fácil de compartir un objeto entre aplicaciones es crear una clase que implemente y use todos esos elementos para guardar y restaurar al instante todos sus datos en un archivo.
Una simple aplicación de esa clase podría ser:
class Synchro
{
private $_file;
public function __construct($file)
{
$this->_file = $file;
}
public function __get($property)
{
// File does not exist
if (!is_file($this->_file))
{
return null;
}
// Check if file is readable
if ((is_file($this->_file)) && (!is_readable($this->_file)))
{
throw new Exception(sprintf("File '%s' is not readable.", $this->_file));
}
// Open file with advisory lock option enabled for reading and writting
if (($fd = fopen($this->_file, 'c+')) === false)
{
throw new Exception(sprintf("Can't open '%s' file.", $this->_file));
}
// Request a lock for reading (hangs until lock is granted successfully)
if (flock($fd, LOCK_SH) === false)
{
throw new Exception(sprintf("Can't lock '%s' file for reading.", $this->_file));
}
// A hand-made file_get_contents
$contents = '';
while (($read = fread($fd, 32 * 1024)) !== '')
{
$contents .= $read;
}
// Release shared lock and close file
flock($fd, LOCK_UN);
fclose($fd);
// Restore shared data object and return requested property
$object = json_decode($contents);
if (property_exists($object, $property))
{
return $object->{$property};
}
return null;
}
public function __set($property, $value)
{
// Check if directory is writable if file does not exist
if ((!is_file($this->_file)) && (!is_writable(dirname($this->_file))))
{
throw new Exception(sprintf("Directory '%s' does not exist or is not writable.", dirname($this->_file)));
}
// Check if file is writable if it exists
if ((is_file($this->_file)) && (!is_writable($this->_file)))
{
throw new Exception(sprintf("File '%s' is not writable.", $this->_file));
}
// Open file with advisory lock option enabled for reading and writting
if (($fd = fopen($this->_file, 'c+')) === false)
{
throw new Exception(sprintf("Can't open '%s' file.", $this->_file));
}
// Request a lock for writting (hangs until lock is granted successfully)
if (flock($fd, LOCK_EX) === false)
{
throw new Exception(sprintf("Can't lock '%s' file for writing.", $this->_file));
}
// A hand-made file_get_contents
$contents = '';
while (($read = fread($fd, 32 * 1024)) !== '')
{
$contents .= $read;
}
// Restore shared data object and set value for desired property
if (empty($contents))
{
$object = new stdClass();
}
else
{
$object = json_decode($contents);
}
$object->{$property} = $value;
// Go back at the beginning of file
rewind($fd);
// Truncate file
ftruncate($fd, strlen($contents));
// Save shared data object to the file
fwrite($fd, json_encode($object));
// Release exclusive lock and close file
flock($fd, LOCK_UN);
fclose($fd);
return $value;
}
}
Ahora, puede utilizar esta clase como stdClass
, pero con una ruta de archivo en la construcción.
$obj = new Synchro("/tmp/test.sync");
$obj->hello = 'world';
// ... and in another process...
echo $obj->hello;
Este ejemplo es, por supuesto, muy simple, se toma cuidado sobre el acceso simultáneo a un archivo, pero no a una variable, en una mejor aplicación que va a utilizar un bloqueo de exclusión mutua similar.
Acabo de empujar esta clase (después de completarla) en github, puedes encontrarla en here.
es su gama tan grande? –
Sí. ¿Puedes agregar un poco más de contexto? ¿Qué hay de almacenar los datos en una base de datos y recuperar solo los bits que necesita en el script actual? –
esto generalmente se resuelve almacenando los datos en una base de datos y obteniendo solo lo que se necesita. –