Home » Php » php – SplObjectStorage doesn't work with String, what to do?

php – SplObjectStorage doesn't work with String, what to do?

Posted by: admin July 12, 2020 Leave a comment

Questions:

Someone has suggested to e to use SplObjectStorage to keep track of a set of unique things. Great, except it doesn’t work with strings. An error says ” SplObjectStorage::attach() expects parameter 1 to be object, string given in fback.php on line 59″

Any ideas?

How to&Answers:

The SplObjectStorage is what its name says: a storage class for storing objects. In contrast to some other programming languages strings are not objects in PHP, they are, well, strings ;-). It therefore makes no sense to store strings in a SplObjectStorage – even if you wrap your strings in an object of class stdClass.

The best way to store a collection of unique strings si to use arrays (as hashtables) with the string as the key as well as the value (as suggested by Ian Selby).

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

You could however wrap this functionality into a custom class:

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

    // ... 
}

By the way you san simulate the behavior of SplObjectStorage for PHP < 5.3.0 and to get a better understanding of what it does.

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

SplObjectStorage stores a unique hash for each instance (like spl_object_hash()) to
be able to identify object instances. As I said above: a string is not an object at all, it therefore does not have an instance hash. A string’s uniqueness can be checked by comparing the string values – two strings are equal when they contain the same set of bytes.

Answer:

It’s an Object Storage. A string is a scalar. So use SplString.

Answer:

Wrap the string in a stdClass?

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

However, every object created this way would still be unique, even if the strings are identical.

If you need to worry about duplicate strings, perhaps you should be using a hash (associative array) to track them instead?

Answer:

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

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

If you wanted to ensure uniqueness of strings in the array you could do a couple of things… first would be to simply use array_unique(). That, or you could create an associative array with the strings as keys as well as the values:

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

If you wanted to be object-oriented about this, you could do something like:

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
}

Then, in your code you can do stuff like:

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

And iterate the same way:

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

SplObjectStorage is for tracking unique instances of Objects, and outside of not working with strings, it’s a bit overkill for what you’re trying to accomplish (in my opinion).

Hope that helps!

Answer:

Or Maybe just instantiate your string as an object with __toString() method – that way you can have them both – object and ability to use it as string (var_dump, echo)..