SplObjectStorage не работает со строкой, что делать?

StackOverflow https://stackoverflow.com/questions/1501726

  •  19-09-2019
  •  | 
  •  

Вопрос

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

Есть какие-нибудь идеи?

Это было полезно?

Решение

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

Лучший способ сохранить коллекцию уникальных строк - использовать массивы (в виде хэш-таблиц) со строкой в качестве ключа, а также значения (как предложено Иэн Селби).

$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()), чтобы иметь возможность идентифицировать экземпляры объектов.Как я уже говорил выше:строка вообще не является объектом, поэтому у нее нет хэша экземпляра.Уникальность строки можно проверить, сравнив строковые значения - две строки равны, когда они содержат один и тот же набор байтов.

Другие советы

Это Объект Хранилище.Строка – это скаляр.Так что используйте SplString.

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

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

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

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

$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 предназначен для отслеживания уникальных экземпляров объектов, и, помимо работы со строками, это немного излишне для того, чего вы пытаетесь достичь (на мой взгляд).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top