像 C# 中那样处理 PHP 属性(getter & setter)
Handling PHP properties like those in C# (getter & setter)
我一直在做一些研究,想知道在 PHP class 中使用属性是否可以像 C# 一样完成,我发现这些问题有一些很好的答案和指示,但并没有真正帮助我:
- Should I use C#-like property handling in PHP?
- Get and set (private) property in PHP as in C# without using getter setter magic method overloading
虽然,正如我所说,这些给出了很好的答案,但我仍然不能对这些下定决心,例如,我希望能够做一些事情,例如:
class Foo
{
public $bar
{
get { return $this->bar; }
set { $this->bar = value; }
}
}
可是我做不到!
在 PHP 的约束下,最好的方法是什么?
我能想到的是这样的:
class user
{
private static $link;
private static $init;
private function __construct ()
{
global $link;
static::$link = $link;
}
public static function __INIT__ ()
{
return static::$init = (null === static::$init ? new self() : static::$init);
}
public static $username;
public function username( $value = '' )
{
if ( $value == '' || empty ( $value ) || !$value )
return static::$username;
else
static::$username = $value;
}
}
这就是 PHP 魔术方法的用途。它们允许您通过中介方法动态设置属性。在这里,让我给你举个例子:
abstract class GetterSetterExample
{
public function __get($name)
{
$method = sprintf('get%s', ucfirst($name));
if (!method_exists($this, $method)) {
throw new Exception();
}
return $this->$method();
}
public function __set($name, $v)
{
$method = sprintf('set%s', ucfirst($name));
if (!method_exists($this, $method)) {
throw new Exception();
}
$this->$method($v);
}
}
class Cat extends GetterSetterExample
{
protected $furColor;
protected function getFurColor()
{
return $this->furColor;
}
protected function setFurColor($v)
{
$this->furColor = $v;
}
}
$cat = new Cat();
$cat->furColor = 'black';
是啊...我也很害怕。
这就是为什么大多数人都满足于使用 Cat
中的方法,但是 public。显然有关于添加 "real" getter 和 setter 的讨论,但是那些出于可读性、语义和原则方面的考虑而讨厌它们的人之间似乎存在很多冲突...
也许你需要考虑是否真的有必要。只是一个shorthand写getter和setters.
private String _name;
public String Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
与以下功能完全相同:
private $_name;
public function getName()
{
return $_name;
}
public function setName($name)
{
$_name = $name;
}
只有调用上的区别:
C# : Object.Name = "This is my Name";
PHP : Object->setName ("This is my Name");
如果您真的更喜欢 C# 语法(在我看来这只是一种习惯),我认为 Flosculus 的答案是唯一的选择。如果您了解代码的作用,它并没有那么复杂。
供参考:
__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.
在此示例中,furColor
是不可访问的,因为它是一个受保护的变量。
那么这里发生了什么 $cat->furColor = 'black
。
- furColor 无法访问,因此魔法方法 __set 正在调用。
- 它在
GetterSetterExample
中创建一个名为 setFurColor
的 setter 并检查它是否存在。
- 是的,它确实存在,因为
Cat
实现了它。
调用 setFurColor
并设置变量。
在最后,此代码的作用与上面示例中的一般 getter 和 setters 完全相同。它只是一个 'workaround' 来模拟 C# 的属性。
那么回到我对这个答案的第一个问题,有必要吗?在我看来不是。 PHP 不支持属性,因此您尝试模拟它的原因没有明确的含义。
一般 getter 和 setters 是可行的方法,如我的示例所示,它做的事情完全相同。
魔术方法很慢,如果你想以类型安全的方式做到这一点,祝你好运。 Flosculus 的示例代码并不复杂,但这种方法可能会变得(不必要的)复杂。
我一直在做一些研究,想知道在 PHP class 中使用属性是否可以像 C# 一样完成,我发现这些问题有一些很好的答案和指示,但并没有真正帮助我:
- Should I use C#-like property handling in PHP?
- Get and set (private) property in PHP as in C# without using getter setter magic method overloading
虽然,正如我所说,这些给出了很好的答案,但我仍然不能对这些下定决心,例如,我希望能够做一些事情,例如:
class Foo
{
public $bar
{
get { return $this->bar; }
set { $this->bar = value; }
}
}
可是我做不到!
在 PHP 的约束下,最好的方法是什么?
我能想到的是这样的:
class user
{
private static $link;
private static $init;
private function __construct ()
{
global $link;
static::$link = $link;
}
public static function __INIT__ ()
{
return static::$init = (null === static::$init ? new self() : static::$init);
}
public static $username;
public function username( $value = '' )
{
if ( $value == '' || empty ( $value ) || !$value )
return static::$username;
else
static::$username = $value;
}
}
这就是 PHP 魔术方法的用途。它们允许您通过中介方法动态设置属性。在这里,让我给你举个例子:
abstract class GetterSetterExample
{
public function __get($name)
{
$method = sprintf('get%s', ucfirst($name));
if (!method_exists($this, $method)) {
throw new Exception();
}
return $this->$method();
}
public function __set($name, $v)
{
$method = sprintf('set%s', ucfirst($name));
if (!method_exists($this, $method)) {
throw new Exception();
}
$this->$method($v);
}
}
class Cat extends GetterSetterExample
{
protected $furColor;
protected function getFurColor()
{
return $this->furColor;
}
protected function setFurColor($v)
{
$this->furColor = $v;
}
}
$cat = new Cat();
$cat->furColor = 'black';
是啊...我也很害怕。
这就是为什么大多数人都满足于使用 Cat
中的方法,但是 public。显然有关于添加 "real" getter 和 setter 的讨论,但是那些出于可读性、语义和原则方面的考虑而讨厌它们的人之间似乎存在很多冲突...
也许你需要考虑是否真的有必要。只是一个shorthand写getter和setters.
private String _name;
public String Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
与以下功能完全相同:
private $_name;
public function getName()
{
return $_name;
}
public function setName($name)
{
$_name = $name;
}
只有调用上的区别:
C# : Object.Name = "This is my Name";
PHP : Object->setName ("This is my Name");
如果您真的更喜欢 C# 语法(在我看来这只是一种习惯),我认为 Flosculus 的答案是唯一的选择。如果您了解代码的作用,它并没有那么复杂。 供参考:
__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.
在此示例中,furColor
是不可访问的,因为它是一个受保护的变量。
那么这里发生了什么 $cat->furColor = 'black
。
- furColor 无法访问,因此魔法方法 __set 正在调用。
- 它在
GetterSetterExample
中创建一个名为setFurColor
的 setter 并检查它是否存在。 - 是的,它确实存在,因为
Cat
实现了它。
调用 setFurColor
并设置变量。
在最后,此代码的作用与上面示例中的一般 getter 和 setters 完全相同。它只是一个 'workaround' 来模拟 C# 的属性。 那么回到我对这个答案的第一个问题,有必要吗?在我看来不是。 PHP 不支持属性,因此您尝试模拟它的原因没有明确的含义。 一般 getter 和 setters 是可行的方法,如我的示例所示,它做的事情完全相同。 魔术方法很慢,如果你想以类型安全的方式做到这一点,祝你好运。 Flosculus 的示例代码并不复杂,但这种方法可能会变得(不必要的)复杂。