2009-10-01 10 views
7

Alguien ha sugerido usar e SplObjectStorage para realizar un seguimiento de un conjunto de cosas únicas. Genial, excepto que no funciona con cadenas. Un error dice "SplObjectStorage :: attach() espera que el parámetro 1 sea objeto, cadena dada en fback.php en la línea 59"SplObjectStorage no funciona con String, ¿qué hacer?

¿Alguna idea?

Respuesta

8

SplObjectStorage es lo que su nombre indica: una clase de almacenamiento para almacenar objetos. En contraste con algunos otros lenguajes de programación strings no son objetos en PHP, son, bueno, cadenas ;-). Por lo tanto, no tiene sentido almacenar cadenas en un SplObjectStorage, incluso si ajusta sus cadenas en un objeto de la clase stdClass.

La mejor manera de almacenar una colección de cadenas únicas es usar matrices (como tablas) con la cadena como clave y el valor (según lo sugerido por Ian Selby).

$myStrings = array(); 
$myStrings['string1'] = 'string1'; 
$myStrings['string2'] = 'string2'; 
// ... 

Se puede envolver sin embargo esta funcionalidad en una clase personalizada:

class UniqueStringStorage // perhaps implement Iterator 
{ 
    protected $_strings = array(); 

    public function add($string) 
    { 
     if (!array_key_exists($string, $this->_strings)) { 
      $this->_strings[$string] = $string; 
     } else { 
      //.. handle error condition "adding same string twice", e.g. throw exception 
     } 
     return $this; 
    } 

    public function toArray() 
    { 
     return $this->_strings; 
    } 

    // ... 
} 

Por cierto que san simular el comportamiento de SplObjectStorage para PHP 5.3.0 y < para obtener una mejor comprensión de lo que hace.

$ob1 = new stdClass(); 
$id1 = spl_object_hash($ob1); 
$ob2 = new stdClass(); 
$id2 = spl_object_hash($ob2); 
$objects = array(
    $id1 => $ob1, 
    $id2 => $ob2 
); 

SplObjectStorage almacena un hash único para cada instancia (como spl_object_hash()) para sean capaces de identificar instancias de objeto. Como dije antes: una cadena no es un objeto en absoluto, por lo tanto, no tiene un hash de instancia.La singularidad de una cadena se puede comprobar comparando los valores de cadena: dos cadenas son iguales cuando contienen el mismo conjunto de bytes.

1

¿Envolver la cadena en un stdClass?

$dummy_object = new stdClass(); 
$dummy_object->string = $whatever_string_needs_to_be_tracked; 
$splobjectstorage->attach($dummy_object); 

Sin embargo, cada objeto creado de esta manera seguiría siendo único, incluso si las cadenas son idénticas.

Si necesita preocuparse por cadenas duplicadas, ¿quizás debería usar un hash (matriz asociativa) para rastrearlas?

+0

¿Puede dar algunos ejemplos código sobre cómo almacenar un conjunto de cadenas únicas y luego iterar sobre ellas? ¿Por qué es tan difícil en php? – erotsppa

+2

¿No podría simplemente almacenarlos en una matriz? Parece que estás complicando un poco las cosas;) –

0
$myStrings = array(); 
$myStrings[] = 'string1'; 
$myStrings[] = 'string2'; 
... 

foreach ($myStrings as $string) 
{ 
    // do stuff with your string here... 
} 

Si quería garantizar la singularidad de las cadenas de la matriz que podría hacer un par de cosas ... primero sería utilizar simplemente array_unique(). Eso, o que podría crear una matriz asociativa con las cadenas como claves, así como los valores:

$myStrings = array(); 
$myStrings['string1'] = 'string1'; 
... 

Si querías ser de esta orientado a objetos, que podría hacer algo como:

class StringStore 
{ 
    public static $strings = array(); 

    // helper functions, etc. You could also make the above protected static and write public functions that add things to the array or whatever 
} 

Luego, en el código que puede hacer cosas como:

StringStore::$strings[] = 'string1'; 
... 

Y repetir la misma manera:

foreach (StringStore::$strings as $string) 
{ 
    // whatever 
} 

SplObjectStorage es para el seguimiento de instancias únicas de Objetos, y fuera de no trabajar con cadenas, es un poco exagerado para lo que estás tratando de lograr (en mi opinión).

Espero que ayude!

5

Es un Objeto Almacenamiento. Una cadena es escalar. Por lo tanto, use SplString.

0

o tal vez sólo instancia su cadena como un) método (objeto con __toString - de esa manera se les puede tener ambas cosas - objeto y capacidad de utilizarla como cadena (var_dump, eco) ..

Cuestiones relacionadas