maz*_*iak 58 php programming-languages
在使用PHP的DOM类(DOMNode,DOMEElement等)时,我注意到它们拥有真正的只读属性.例如,我可以读取DOMNode的$ nodeName属性,但我无法写入它(如果我做PHP抛出致命错误).
如何在PHP中创建自己的只读属性?
too*_*php 43
你可以这样做:
class Example {
private $__readOnly = 'hello world';
function __get($name) {
if($name === 'readOnly')
return $this->__readOnly;
user_error("Invalid property: " . __CLASS__ . "->$name");
}
function __set($name, $value) {
user_error("Can't set property: " . __CLASS__ . "->$name");
}
}
Run Code Online (Sandbox Code Playgroud)
只有在你真正需要的时候才使用它 - 它比普通的属性访问慢.对于PHP,最好采用仅使用setter方法从外部更改属性的策略.
Jso*_*owa 36
在属性声明期间,您只能初始化只读属性一次。
class Test {
public readonly string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
Run Code Online (Sandbox Code Playgroud)
--
class Test {
public function __construct(
public readonly string $prop,
) {}
}
Run Code Online (Sandbox Code Playgroud)
尝试修改 readonly 属性将导致以下错误:
Error: Cannot modify readonly property Test::$prop
Run Code Online (Sandbox Code Playgroud)
更新 PHP 8.2
从 PHP 8.2 开始,您可以将其定义为readonly整个类。
readonly class Test {
public string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 12
但是,仅使用__get()公开的私有属性对于枚举对象成员的函数是不可见的 - 例如json_encode().
我经常使用json_encode()将PHP对象传递给Javascript,因为它似乎是传递具有从数据库填充的大量数据的复杂结构的好方法.我必须在这些对象中使用公共属性,以便将这些数据填充到使用它的Javascript中,但这意味着这些属性必须是公共的(因此存在另一个程序员不在相同波长上的风险(或者可能)我自己经历了一个糟糕的夜晚)可能会直接修改它们.如果我将它们设为私有并使用__get()和__set(),则json_encode()不会看到它们.
拥有"只读"辅助功能关键字不是很好吗?
这是一种从外部呈现类的所有属性 read_only 的方法,继承的类具有写访问权限;-)。
class Test {
protected $foo;
protected $bar;
public function __construct($foo, $bar) {
$this->foo = $foo;
$this->bar = $bar;
}
/**
* All property accessible from outside but readonly
* if property does not exist return null
*
* @param string $name
*
* @return mixed|null
*/
public function __get ($name) {
return $this->$name ?? null;
}
/**
* __set trap, property not writeable
*
* @param string $name
* @param mixed $value
*
* @return mixed
*/
function __set ($name, $value) {
return $value;
}
}
Run Code Online (Sandbox Code Playgroud)
在 php7 中测试
小智 5
我看到你已经得到了答案,但对于那些仍在寻找的人:
只需将所有"readonly"变量声明为private或protected,并使用魔术方法__get(),如下所示:
/**
* This is used to fetch readonly variables, you can not read the registry
* instance reference through here.
*
* @param string $var
* @return bool|string|array
*/
public function __get($var)
{
return ($var != "instance" && isset($this->$var)) ? $this->$var : false;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我还保护了$ this-> instance变量,因为此方法将允许用户读取所有声明的变量.要阻止多个变量,请使用带有in_array()的数组.
| 归档时间: |
|
| 查看次数: |
40628 次 |
| 最近记录: |