【问题标题】:PHP OOP: Unique ID property among all instances of classPHP OOP:类的所有实例中的唯一 ID 属性
【发布时间】:2014-03-13 11:31:13
【问题描述】:

我的问题很简单,但我似乎无法在网上找到任何答案。我可能会直接跳入代码:

class NewClas {
    public $id;

    public function __construct($id) {
        $this->id = $id;

        $this->checkVars();
    }

    public function checkVars() {
        if (empty($this->id)) {
            trigger_error('ID is a required parameter.');
        } elseif ($this->id WAS USED IN A PREVIOUS OBJECT) {
            trigger_error('ID "'.$this->id.'" was used already. Please insert a unique name.');
        }
    }

}

$object1 = new NewClass('id1');
$object2 = new NewClass('id2');
$object3 = new NewClass('id1'); // throws error, because id1 was already used

那么 - 是否可以在类的所有实例中检查属性值的唯一性?我刚刚开始使用 OOP,所以请放轻松。 :)

另外,我知道spl_object_hash,但我更喜欢将 ID 用作用户指定的可读字符串。

提前致谢!

【问题讨论】:

    标签: php oop properties unique-id


    【解决方案1】:

    这是可能的 - 如果您将存储使用过的 id 的静态注册表。那是关于:

    class NewClass
    {
        public $id;
        //here's your registry
        protected static $registry = array();
    
        public function __construct($id) 
        {
            $this->id = $id;
    
            $this->checkVars();
            //if not failed, add to registry:
            self::$registry[] = $id;
        }
    
        public function checkVars() 
        {
            if (empty($this->id)) 
            {
                trigger_error('ID is a required parameter.');
            }
            //checking if it's already used: 
            elseif (in_array($this->id, self::$registry)) 
            {
                trigger_error('ID "'.$this->id.'" was used already. Please insert a unique name.');
            }
        }
    
    }
    

    你可以查看这个demo

    【讨论】:

    • 是的,Alma,这正是我要找的东西!感谢您的宝贵时间,OOP 和 Stack Exchange 再次被证明很棒。 :)
    【解决方案2】:

    它不会抛出任何错误。您正在使用 else 块下的 trigger_error 触发错误。这就是您收到错误的原因。

    当你这样做时..

    $object3 = new NewClass('id1');
    

    id1 作为参数传递给构造函数,并设置为$id 公共变量。现在checkVars() 将被调用.. 这里$this->id 不会为空,所以它会转到else 块。

    这实际上是正确的代码..

    <?php
    
    class NewClass {
        public $id;
    
        public function __construct($id) {
            $this->id = $id;
    
            $this->checkVars();
        }
    
        public function checkVars() {
            if (empty($this->id)) {
                trigger_error('ID is a required parameter.');
            } else {
               // trigger_error('ID is already used.');
            }
        }
    
    }
    
    $object1 = new NewClass('id1');
    $object2 = new NewClass('id2');
    $object3 = new NewClass('id1'); 
    

    【讨论】:

    • 不知道这会有什么用处在所有实例中
    • 您好 Shankar,我没有收到任何错误,我只是在寻找一种方法来检查属性的“唯一性”。我的实际代码要困难得多,在这里我试图提出一个简化版本。不过谢谢! :)
    • @PetrCibulka,好像我误会了!
    【解决方案3】:

    这是上述答案的正确答案: 但为了尊重 SOLID OOP 设计原则,我建议将 id 设为私有并使用 getter 和 setter 来访问它。

    class NewClass
    {
        private $id;
        //here's your registry
        public static $registry = array(); //since is static you can make it public
    
        public function __construct($id) 
        {
            $this->id = $id;
    
            $this->checkVars();
            //if not failed, add to registry:
            self::$registry[] = $id;
        }
    
        public function checkVars() 
        {
            if (empty($this->id)) 
            {
                trigger_error('ID is a required parameter.');
            }
            //checking if it's already used: 
            else if (in_array($this->id, self::$registry)) 
            {
                trigger_error('ID "'.$this->id.'" was used already. Please insert a unique name.');
            }
        }
    

    【讨论】:

    • 为了尊重 SOLID 原则,您首先不会使用静态注册表,因为它实际上是全局状态。此外,Getter 和 Setter 通常会破坏对象封装并导致消耗代码做出决策,而对象作为信息专家应该做出决定。
    • 戈登,你会用什么?
    猜你喜欢
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2015-08-26
    • 2011-01-18
    • 1970-01-01
    • 2016-01-30
    相关资源
    最近更新 更多