这是处理PHP类中的getter/setter的合理方法吗? [英] Is this a reasonable way to handle getters/setters in a PHP class?

查看:85
本文介绍了这是处理PHP类中的getter/setter的合理方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将尝试使用此问题的格式进行尝试,并且我非常乐意就更好的处理方式提出建议.

I'm going to try something with the format of this question and I'm very open to suggestions about a better way to handle it.

我不想只是在问题中转储一堆代码,所以我已经将该类的代码发布在了refactormycode上.

I didn't want to just dump a bunch of code in the question so I've posted the code for the class on refactormycode.

轻松实现基类类属性处理

base class for easy class property handling

我的想法是,人们可以在此处发布代码段,也可以在refactormycode上进行更改,然后将链接发布回其重构.我将投票并接受一个基于此的答案(假设有明显的获胜者").

My thought was that people can either post code snippets here or make changes on refactormycode and post links back to their refactorings. I'll make upvotes and accept an answer (assuming there's a clear "winner") based on that.

无论如何,要继续讲授课程本身:

At any rate, on to the class itself:

我看到了很多关于getter/setter类方法的争论,最好是直接访问简单的属性变量,还是每个类都定义了显式的get/set方法,等等.我喜欢使用显式方法的想法,以防您以后需要添加更多逻辑.然后,您不必修改任何使用该类的代码.但是我讨厌有一百万个看起来像这样的函数:

I see a lot of debate about getter/setter class methods and is it better to just access simple property variables directly or should every class have explicit get/set methods defined, blah blah blah. I like the idea of having explicit methods in case you have to add more logic later. Then you don't have to modify any code that uses the class. However I hate having a million functions that look like this:

public function getFirstName()
{
   return $this->firstName;
}
public function setFirstName($firstName)
{
   return $this->firstName;
}

现在,我确定我不是第一个这样做的人(我希望有人可以向我建议一种更好的方法).

Now I'm sure I'm not the first person to do this (I'm hoping that there's a better way of doing it that someone can suggest to me).

基本上,PropertyHandler类具有__call magic方法.然后,通过__call传入的任何以"get"或"set"开头的方法都将路由到将值设置或检索到关联数组中的函数.数组中的键是获取或设置后调用方法的名称.因此,如果进入__call的方法是"getFirstName",则数组键是"FirstName".

Basically, the PropertyHandler class has a __call magic method. Any methods that come through __call that start with "get" or "set" are then routed to functions that set or retrieve values into an associative array. The key into the array is the name of the calling method after getting or setting. So, if the method coming into __call is "getFirstName", the array key is "FirstName".

我喜欢使用__call,因为它会自动处理子类已经定义了"getFirstName"方法的情况.我的印象(也许是错误的)是__get& __set魔术方法不能做到这一点.

I liked using __call because it will automatically take care of the case where the subclass already has a "getFirstName" method defined. My impression (and I may be wrong) is that the __get & __set magic methods don't do that.

这是一个工作原理的例子:

So here's an example of how it would work:

class PropTest extends PropertyHandler
{
    public function __construct()
    {
        parent::__construct();
    }
}

$props = new PropTest();

$props->setFirstName("Mark");
echo $props->getFirstName();

请注意,PropTest实际上没有"setFirstName"或"getFirstName"方法,PropertyHandler也没有.所有要做的就是操纵数组值.

Notice that PropTest doesn't actually have "setFirstName" or "getFirstName" methods and neither does PropertyHandler. All that's doing is manipulating array values.

另一种情况是您的子类已经在扩展其他内容.由于在PHP中不能具有真正的多重继承,因此可以使子类具有一个PropertyHandler实例作为私有变量.您必须再添加一个函数,但是事情的表现却完全相同.

The other case would be where your subclass is already extending something else. Since you can't have true multiple inheritances in PHP, you can make your subclass have a PropertyHandler instance as a private variable. You have to add one more function but then things behave in exactly the same way.

class PropTest2
{
    private $props;

    public function __construct()
    {
        $this->props = new PropertyHandler();
    }

    public function __call($method, $arguments)
    {
        return $this->props->__call($method, $arguments);
    }
}

$props2 = new PropTest2();

$props2->setFirstName('Mark');
echo $props2->getFirstName();

请注意子类如何具有__call方法,该方法仅将所有内容传递给PropertyHandler __call方法.

Notice how the subclass has a __call method that just passes everything along to the PropertyHandler __call method.

反对以这种方式处理getter和setter的另一个很好的论据是,它真的很难记录.

Another good argument against handling getters and setters this way is that it makes it really hard to document.

实际上,由于没有待记录的显式方法不存在,因此基本上不可能使用任何类型的文档生成工具.

In fact, it's basically impossible to use any sort of document generation tool since the explicit methods to be don't documented don't exist.

我现在已经几乎放弃了这种方法.这是一个有趣的学习练习,但我认为它牺牲了太多的清晰度.

I've pretty much abandoned this approach for now. It was an interesting learning exercise but I think it sacrifices too much clarity.

推荐答案

我的操作方式如下:

class test {
    protected $x='';
    protected $y='';

    function set_y ($y) {
        print "specific function set_y\n";
        $this->y = $y;
    }

    function __call($function , $args) {
        print "generic function $function\n";
        list ($name , $var ) = split ('_' , $function );
        if ($name == 'get' && isset($this->$var)) {
            return $this->$var;
        }
        if ($name == 'set' && isset($this->$var)) {
            $this->$var= $args[0];
            return;
        }
        trigger_error ("Fatal error: Call to undefined method test::$function()");
    }
}

$p = new test();
$p->set_x(20);
$p->set_y(30);
print $p->get_x();
print $p->get_y();

$p->set_z(40);

将输出(为了清楚起见添加了换行符)

Which will output (line breaks added for clarity)

generic function set_x
specific function set_y

generic function get_x
20
generic function get_y
30

generic function set_z
Notice: Fatal error: Call to undefined method set_z() in [...] on line 16

这篇关于这是处理PHP类中的getter/setter的合理方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆