【问题标题】:Don't allow to dynamically create public properties不允许动态创建公共属性
【发布时间】:2017-08-10 04:55:43
【问题描述】:

让我们从简单的 PHP 代码开始:

<?php

class Test 
{
}

$test = new Test();
$test->x = 20;
echo $test->x;

这里的问题是这段代码没有任何问题(在 PHP 7.1 中测试过,可能在某些以前的版本中它也没有任何问题)。

我在这里看到的问题是,当使用这样的代码时,很容易编写很难分析并且可能包含一些隐藏错误的代码。

问题:有什么方法不允许为对象动态创建属性,尤其是在类之外?

对于这样的自定义类,可以使用的解决方案是创建自定义 __set 方法,该方法将创建未声明的属性,如下所示:

public function __set($property, $value)
{
    if (!property_exists($this, $property)) {
        throw new Exception("Property {$property} does not exit");

    }
    $this->$property = $value;
}

但它显然不能解决受保护/私有属性的问题 - property_exists 也会为受保护和私有属性返回 true(需要为此使用反射)。

【问题讨论】:

  • __set() 在将数据写入不可访问的属性时运行。 __get() 用于从不可访问的属性中读取数据。魔术方法不能替代 getter 和 setter。它们只允许您处理会导致错误的方法调用或属性访问。因此,还有更多与错误处理相关的内容。另请注意,它们比使用正确的 getter 和 setter 或直接方法调用要慢得多。

标签: php oop php-7


【解决方案1】:
<?php
ini_set("display_errors", 1);
class Test 
{
    protected $name="ss";
    public function __set($property, $value)
    {
        //Checked for undefined properties
        if(!isset(get_object_vars($this)[$property]))
        {
             throw new Exception("Property {$property} does not exit");            
        }
        //Checking for public properties
        $prop = new ReflectionProperty($this, "name");
        if(!$prop->isPublic())
        {
            throw new Exception("Property {$property} does not exit");            
        }
        //Checking for non-existing properties
        if (!property_exists($this, $property)) 
        {
            throw new Exception("Property {$property} does not exit");
        }
        $this->$property = $value;
    }
}

$test = new Test();
$test->x = 20;
echo $test->x;

【讨论】:

  • 这只是有问题的错字,问题不在于这个。
  • @MarcinNabiałek The question: is there any way to don't allow to dynamically create properties for objects especially outside of the class? 你已经在你的问题中写了这个。
  • 是的,但这是我展示的代码。它不能解决我提到的其他问题,如果是简单问题的相当复杂的解决方案,不是吗?
  • @SahilGulati,OP 正在展示他想要阻止的东西。所以当然它是工作代码,当有人试图在之前未声明的对象上设置属性时,他想抛出异常或其他东西。 (我觉得这叫密封?)
  • @MarcinNabiałek 我已经更新了我的帖子。我认为反射可以成为检查属性类型并防止它在类外更新的选项。
猜你喜欢
  • 1970-01-01
  • 2013-11-30
  • 2020-05-19
  • 2014-11-24
  • 2013-08-20
  • 1970-01-01
  • 2014-05-23
  • 1970-01-01
相关资源
最近更新 更多