【问题标题】:SplObjectStorage doesn't work with String, what to do?SplObjectStorage 不适用于 String,怎么办?
【发布时间】:2010-12-02 20:53:30
【问题描述】:

有人建议使用 SplObjectStorage 来跟踪一组独特的事物。很好,但它不适用于字符串。错误提示“SplObjectStorage::attach() 期望参数 1 是对象,第 59 行的 fback.php 中给出的字符串”

有什么想法吗?

【问题讨论】:

    标签: php spl


    【解决方案1】:

    SplObjectStorage 顾名思义:用于存储对象的存储类。与其他一些编程语言相比,strings 不是 PHP 中的对象,它们是字符串 ;-)。因此,将字符串存储在 SplObjectStorage 中是没有意义的 - 即使您将字符串包装在 stdClass 类的对象中。

    存储唯一字符串集合的最佳方法是使用数组(作为哈希表),字符串作为键和值(如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

    $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())到 能够识别对象实例。正如我上面所说:字符串根本不是对象,因此它没有实例哈希。可以通过比较字符串值来检查字符串的唯一性 - 当两个字符串包含相同的字节集时,它们是相等的。

    【讨论】:

      【解决方案2】:

      这是一个对象存储。字符串是标量。所以使用SplString

      【讨论】:

        【解决方案3】:

        将字符串包装在 stdClass 中?

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

        但是,以这种方式创建的每个对象仍然是唯一的,即使字符串相同。

        如果您需要担心重复的字符串,也许您应该使用哈希(关联数组)来跟踪它们?

        【讨论】:

        • 您能否提供一些示例代码来说明如何存储一组唯一字符串然后对其进行迭代?为什么php这么难??
        • 你不能把它们存储在一个数组中吗?好像你把事情复杂化了一点;)
        【解决方案4】:
        $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】:

          或者也许只是使用 __toString() 方法将您的字符串实例化为一个对象 - 这样您就可以同时拥有它们 - 对象和将其用作字符串的能力(var_dump,echo)..

          【讨论】:

            猜你喜欢
            • 2014-10-01
            • 1970-01-01
            • 2022-10-14
            • 1970-01-01
            • 2012-09-12
            • 1970-01-01
            • 2014-04-21
            • 1970-01-01
            相关资源
            最近更新 更多