PHP:将未声明的类属性的默认可见性更改为protected / private

时间:2017-06-24 00:39:21

标签: php class oop scope visibility

在PHP中,未声明的类属性/变量将默认为" public"可视性。

是否有办法(对于某些类,但不是全部)将默认可见性更改为" protected" (或私人)?

我知道将它们全部正常宣布是一种好习惯。但是在这种情况下,我有很多层的模型类来自SQL视图,有很多列。我希望这些默认为" protected" (以防止我的前端开发人员在没有HTML转义的情况下使用原始值),以及" public"需要访问,我将这样声明。即看到它与安全相关,我想"将公众列入白名单"而不是" blacklist protected / private"。

3 个答案:

答案 0 :(得分:2)

如果您需要这种级别的可见性控制,您必须声明一个类。直接问你的问题,不,没有办法动态设置可见性。

尽管文档没有到stdClass对象类型的特定会话,但使用(object)转换的任何数组都将是stdClass对象,其中非数字索引作为公共属性添加。 http://php.net/manual/en/language.types.object.php#language.types.object.casting

一般的解决方案是你有一个具有protected属性的类,它将是数组,并且它将保存这些值。您必须编写一个访问方法,期望索引并返回原始值或转义值。

答案 1 :(得分:1)

你必须使用Reflection来完成你的要求。

<?php
class MyClass {
     private $myProperty = true;
}

$class = new ReflectionClass("MyClass");
$property = $class->getProperty("myProperty");
$property->setAccessible(true);

$obj = new MyClass();
echo $property->getValue($obj); // Works
echo $obj->myProperty; // Doesn't work (error)
?>

请参阅PHP手册了解ReflectionProperty::setAccessible

在这种情况下,你可能不得不使用魔术方法。这些方面的东西。

class Person {

    private $properties = [
        'first_name' => ['visibility'=>'public','value'=>null]
        'last_name' => ['visibility'=>'public','value'=>null],
        'income' => ['visibility'=>'private','value'=>null]
    ];

    function __get($name) {
        if (array_key_exists($name, $this->properties) && $this->properties[$name]['visibility'] == 'public')
            return $this->properties[$name];
    }

    function __set($name, $value) {
        if (array_key_exists($name, $this->properties) && $this->properties[$name]['visibility'] == 'public')
            $this->properties[$name] = $value);
    }
}

答案 2 :(得分:0)

没有。没有。

但是你的类实际上不应该使用未定义的属性。在大多数情况下,这将代表您的代码中存在“问题”(如果不是一个完整的“错误”)。

至于你的实际问题:我个人在data mappers中使用这样的代码:

public function applyValues($instance, array $parameters)
{
    foreach ($parameters as $key => $value) {
        $method = 'set' . str_replace('_', '', $key);
        if (method_exists($instance, $method)) {
            $instance->{$method}($value);
        }
    }
}

由于PHP中的方法名称不区分大小写,因此此方法适用于SQL的camelCaseunder_score命名约定。

这种方法基本上可以作为“白名单”使用。如果在域对象中定义了setter,则将应用该值。如果没有,那么它将被忽略。而且,如果您正在使用Twig(您可能应该使用),那么<p>{{ entity.content }}</p>将尝试呼叫$entity->getContent()