2009-10-01 5 views
7

Jemand hat vorgeschlagen, SplObjectStorage zu verwenden, um eine Reihe einzigartiger Dinge zu verfolgen. Großartig, außer dass es nicht mit Strings funktioniert. Ein Fehler sagt "SplObjectStorage :: attach() erwartet Parameter 1 als Objekt, String in fback.php in Zeile 59 gegeben"SplObjectStorage funktioniert nicht mit String, was zu tun ist?

Irgendwelche Ideen?

Antwort

8

Die SplObjectStorage ist, was der Name sagt: eine Speicherklasse zum Speichern von Objekten. Im Gegensatz zu einigen anderen Programmiersprachen sind strings keine Objekte in PHP, sie sind, naja, Strings ;-). Es macht daher keinen Sinn, Strings in einem SplObjectStorage zu speichern - selbst wenn Sie Ihre Strings in ein Objekt der Klasse stdClass einbinden.

Die beste Methode zum Speichern einer Sammlung eindeutiger Zeichenfolgen ist die Verwendung von Arrays (als Hashtabellen) mit der Zeichenfolge als Schlüssel sowie dem Wert (wie von Ian Selby vorgeschlagen).

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

Sie könnten jedoch diese Funktionalität in einer benutzerdefinierten Klasse wickeln:

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; 
    } 

    // ... 
} 

Durch die Art und Weise Sie san das Verhalten von SplObjectStorage für PHP < 5.3.0 simulieren und ein besseres Verständnis von dem, was es zu bekommen tut.

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

SplObjectStorage speichert einen eindeutigen Hash für jede Instanz (wie spl_object_hash()) zu können Objektinstanzen identifizieren. Wie ich oben sagte: Ein String ist überhaupt kein Objekt, daher hat er keinen Instanz-Hash.Die Eindeutigkeit einer Zeichenkette kann überprüft werden, indem die Zeichenkettenwerte verglichen werden - zwei Zeichenketten sind gleich, wenn sie die gleiche Menge von Bytes enthalten.

1

Wickeln Sie die Zeichenfolge in eine StdClass?

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

Jedes auf diese Weise erstellte Objekt wäre jedoch immer noch eindeutig, auch wenn die Strings identisch sind.

Wenn Sie sich Gedanken über doppelte Strings machen müssen, sollten Sie vielleicht stattdessen einen Hash (assoziatives Array) verwenden, um sie zu verfolgen?

+0

Können Sie einige Beispiele liefern Code, wie man eine Menge eindeutiger Strings speichert und dann über sie iteriert? Warum ist es so schwer in PHP? – erotsppa

+2

Könnten Sie sie nicht einfach in einem Array speichern? Sieht so aus, als ob du die Dinge ein wenig verkomplizierst;) –

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

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

Wenn Sie Einzigartigkeit von Strings in dem Array um sicherzustellen, wollen Sie ein paar Dinge tun könnten ... würde zunächst einfach zu bedienen sein array_unique(). Das, oder Sie können ein assoziatives Array mit den Strings als Schlüssel sowie die Werte schaffen:

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

Wenn Sie wollten objektorientiert, darüber sein, man könnte so etwas wie:

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 
} 

in Ihrem Code Dann können Sie tun Sachen wie:

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

Und iterieren die gleiche Art und Weise:

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

SplObjectStorage ist zum Verfolgen von eindeutigen Instanzen von Objekten, und außerhalb von nicht mit Zeichenfolgen arbeiten, ist es ein bisschen zu viel für das, was Sie versuchen zu erreichen (meiner Meinung nach).

Hoffe, dass hilft!

5

Es ist ein Objekt Storage. Ein String ist ein Skalar. Verwenden Sie also SplString.

0

oder vielleicht auch nur die Zeichenfolge als ein Objekt mit __toString() Methode instanziiert - auf diese Weise Sie beide haben kann - Objekt und die Fähigkeit, es zu benutzen als string (var_dump, Echo) ..