2009-10-01 10 views
7

Ktoś zasugerował, aby używać SplObjectStorage do śledzenia zestawu unikatowych rzeczy. Świetnie, z tym wyjątkiem, że nie działa z ciągami. Błąd mówi, że "SplObjectStorage :: attach() oczekuje, że parametr 1 będzie obiektem, łańcuch podany w fback.php na linii 59"SplObjectStorage nie działa z ciągiem, co robić?

Jakieś pomysły?

Odpowiedz

8

Zgodnie z nazwą: SplObjectStorage: klasa pamięci do przechowywania obiektów. W przeciwieństwie do niektórych innych języków programowania strings nie są obiektami w PHP, są one, no, łańcuchami ;-). Dlatego nie ma sensu przechowywanie ciągów w kodzie SplObjectStorage - nawet jeśli zawijasz ciągi znaków w obiekcie klasy stdClass.

Najlepszy sposób przechowywania kolekcji unikatowych łańcuchów si do użycia tablic (jako hashtables) z ciągiem znaków jako kluczem oraz wartością (zgodnie z sugestią Ian Selby).

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

Można jednak owinąć tej funkcji w niestandardowej klasy:

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

    // ... 
} 

Przy okazji san symulować zachowanie SplObjectStorage dla PHP < 5.3.0 i uzyskać lepsze zrozumienie tego, co robi.

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

SplObjectStorage przechowuje unikalny mieszania w każdym przypadku (jak spl_object_hash()) do stanie zidentyfikować przykłady obiektów. Jak już wspomniałem powyżej: ciąg znaków nie jest wcale obiektem, dlatego nie ma wartości skrótu instancji.Unikalność łańcuchów można sprawdzić, porównując wartości łańcuchowe - dwa łańcuchy są równe, jeśli zawierają ten sam zestaw bajtów.

1

Owiń ciąg w stdClass?

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

Jednak każdy obiekt utworzony w ten sposób będzie nadal unikatowy, nawet jeśli ciągi są identyczne.

Jeśli chcesz się martwić duplikowaniem ciągów znaków, być może powinieneś używać zamiast tego tablicy mieszającej (tablicy asocjacyjnej)?

+0

można zapewnić pewną próbkę kod, w jaki sposób przechowywać zestaw unikatowych ciągów, a następnie iterować nad nimi? Dlaczego jest tak trudno w php? – erotsppa

+2

Nie możesz po prostu zapisać ich w tablicy? Wygląda na to, że trochę komplikujesz;) –

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

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

Jeśli chciał zapewnić niepowtarzalność ciągów w tablicy można zrobić kilka rzeczy ... po pierwsze byłoby po prostu użyć array_unique(). Że albo można utworzyć tablicę asocjacyjną z łańcuchów jak klucze, jak również wartości:

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

Jeśli chcesz być obiektowego na ten temat, można zrobić coś takiego:

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 
} 

Następnie w kodzie można zrobić rzeczy jak:

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

I iteracyjne w ten sam sposób:

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

SplObjectStorage służy do śledzenia wyjątkowych wystąpień obiektów, a poza tym, że nie działa z ciągami, jest nieco przesadzone z tego, co próbujesz osiągnąć (moim zdaniem).

Nadzieję, że pomaga!

5

To jest obiekt przechowywany w obiekcie Object. Ciąg jest skalarem . Więc używaj SplString.

0

A może po prostu instancję swój ciąg jako obiekt z __toString) metoda (- w ten sposób można mieć ich obu - obiekt i możliwość wykorzystania go jako ciąg znaków (var_dump, echo) ..

Powiązane problemy