2009-10-01 3 views
7

Кто-то предложил e использовать SplObjectStorage для отслеживания множества уникальных вещей. Отлично, за исключением того, что он не работает со строками. Ошибка говорит: «SplObjectStorage :: attach() ожидает, что параметр 1 будет объектом, строка указана в файле fback.php в строке 59«SplObjectStorage не работает со строкой, что делать?

Любые идеи?

ответ

8

SplObjectStorage - это то, что его название говорит: класс хранения для хранения объектов. В отличие от некоторых других языков программирования strings не являются объектами в PHP, они, ну, строки ;-). Поэтому нет смысла хранить строки в SplObjectStorage - даже если вы оберните свои строки в объект класса stdClass.

Лучший способ хранения коллекции уникальных строк si для использования массивов (как hashtables) со строкой в ​​качестве ключа, а также значения (как предложено Ian Selby).

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

Вы могли бы, однако обернуть эту функцию в пользовательский класс:

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

    // ... 
} 

Кстати, вы Сан - имитировать поведение SplObjectStorage для PHP < 5.3.0 и получить лучшее понимание того, что делает.

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

SplObjectStorage хранит уникальный хэш для каждого экземпляра (например, spl_object_hash()) в быть в состоянии идентифицировать экземпляры объектов. Как я сказал выше: строка не является объектом вообще, поэтому она не имеет хеша экземпляра.Уникальность строки может быть проверена путем сравнения строковых значений - две строки равны, если они содержат один и тот же набор байтов.

1

Обернуть строку в stdClass?

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

Однако каждый объект, созданный таким образом, по-прежнему будет уникальным, даже если строки идентичны.

Если вам нужно беспокоиться о повторяющихся строках, возможно, вы должны использовать хеш (ассоциативный массив), чтобы отслеживать их?

+0

Можете ли вы предоставить несколько образцов код о том, как хранить набор уникальных строк, а затем перебирать их? Почему это так сложно в php? – erotsppa

+2

Не могли бы вы просто сохранить их в массиве? Похоже, вы немного усложняете вещи;) –

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

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

Если вы хотите, чтобы обеспечить уникальность строк в массиве вы могли бы сделать пару вещей ... первый будет просто использовать array_unique(). Это, или вы можете создать ассоциативный массив со строками в качестве ключей, а также значения:

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

Если вы хотите быть объектно-ориентированный об этом, вы могли бы сделать что-то вроде:

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 
} 

Затем, в вашем коде вы можете делать такие вещи, как:

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

И итерацию таким же образом:

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

SplObjectStorage предназначен для отслеживания уникальных экземпляров объектов, а кроме того, что он не работает со строками, это немного избыточно для того, что вы пытаетесь выполнить (на мой взгляд).

Надеюсь, что это поможет!

5

Это Объект Хранение. Строка представляет собой скаляр . Поэтому используйте SplString.

0

Или Может просто создать экземпляр строку в качестве объекта с __toString() метод - таким образом, вы можете иметь оба - объект и возможность использовать его в качестве строки (var_dump, эхо) ..

Смежные вопросы