PHP OOP很多setter,getters

时间:2012-06-23 07:24:31

标签: php oop getter-setter

我需要创建约。 5-7个班级,每个班级都会包含很多成员(让我们说每个班级将包含20个成员)。我可以使用公共访问创建它们,例如:

class A {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    ...
}

我首选的方法是将这些成员设为私有,并为每个属性创建get / set方法。即。

class A {
    private $myPropertyOne = '';
    private $myPropertyTwo = '';

    public function getMyPropertyOne() {
            return $this->myPropertyOne;
    }

    public function setMyPropertyOne($myPropertyOne) {
            $this->myPropertyOne = $myPropertyOne;
    }

    public function getMyPropertyTwo() {
            return $this->myPropertyTwo;
    }

    public function setMyPropertyTwo($myPropertyTwo) {
            $this->myPropertyTwo = $myPropertyTwo;
    }
}

但考虑到一个类将有20个属性,我将除此之外还添加40个方法。我在这里关注的是如何减慢脚本速度以及需要更多内存(请记住我将有几个这样的类)。

另一个解决方案可能是使用魔术函数__set,__但我不想这样做,因为开发IDE中的代码完成不会建议对我来说至关重要的属性。

如果这是一个编译语言(比如C ++),我就不会有问题,并且会使用getter,setter的解决方案但是因为PHP是解释语言,所以我对我的脚本感兴趣使用更少的RAM并且速度快尽可能。

在此先感谢,对此问题的任何想法都将不胜感激!


我的意见

谢谢大家的回答,我只想分享我的意见,以防有人寻找这个问题的答案。

我不能完全同意那些说你不应该关心性能的人,因为这是优化者的任务,我认为这是重要的因素(至少对我而言),当我们处理像PHP这样的解释语言时我们将永远不得不考虑内存和速度(这一切都让我想起了我为DOS开发系统应用程序的时候,呵呵:)你总是受限于CPU和CPU总内存不足,所以如果可以的话你会很开心保存一个额外的字节),在PHP开发中你有相同的图片,无论你添加多少服务器,用户的数量总是会更高,所以你总是要决定是否要遵循经典/安全/正确的方法或者避免这种情况,并获得速度或记忆的一些增益。

所以....我认为这里最好的方法是对所有成员使用公共访问,并避免所有属性的getter / setter,并使用带有get / set方法的私有访问,这些属性需要数据验证或初始化之前将设置一个值。

例如:

class B {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    private $myPropertyThree = array();


    public function getMyPropertyThree() {
        return $this->myPropertyThree;
    }

    public function setMyPropertyThree($val) {
        if(!is_array($val)) {
            return;
        }

        $this->myPropertyThree = $val;
    }
}

感谢您花时间在我的问题上!

6 个答案:

答案 0 :(得分:5)

简单测试显示实例占用相同数量的内存,不受类中方法数量的影响:

没有方法的类:

class Test1 { }

有20种方法的类:

class Test2 {

    function test1() { return true; }
    function test2() { return true; }
    function test3() { return true; }
    function test4() { return true; }
    function test5() { return true; }
    function test6() { return true; }
    function test7() { return true; }
    function test8() { return true; }
    function test9() { return true; }
    function test10() { return true; }
    function test11() { return true; }
    function test12() { return true; }
    function test13() { return true; }
    function test14() { return true; }
    function test15() { return true; }
    function test16() { return true; }
    function test17() { return true; }
    function test18() { return true; }
    function test19() { return true; }
    function test20() { return true; }

}

测试循环,两个测试都相同:

$test = array();
$base = memory_get_usage();
for ($i = 0; $i < 10000; $i++) {
    $test[] = new ClassToBeTested();
}
$used = memory_get_usage() - $base;
print("used: $used\n");

类Test1(无方法)的结果:

used: 3157408

Test2类的结果(20种方法):

used: 3157408

我在两个单独的脚本中运行它,因为在一个脚本中运行两个测试显然暴露了一些PHP内部分配,第二个测试比第一个测试消耗更少的内存,无论哪个是第一个或第二个。< / p>

虽然您确实需要为实际的类定义占用更多内存,但显然这个成本每个类只发生一次,而不是每个实例。您不必担心内存使用情况。

答案 1 :(得分:5)

  

但考虑一个班级将有20个属性

拥有这么多属性通常是错误信息的指标。检查是否可以将其中的一些分组为自己的类。

  

除此之外我还会添加40种方法。

完全没有。除非这些类是哑数据结构,否则你不希望它们上有任何Getter和Setter因为它们打破了封装。将方法放在公共API中,用它告诉对象做事。

  

我在这里关注的是如何减慢脚本速度以及需要更多内存(请记住我将有几个这样的类)。

这不是问题。

  

另一个解决方案可能是使用魔术函数__set,__但我不想这样做,因为开发IDE中的代码完成不会建议对我来说至关重要的属性。

现代IDE可以在魔术方法上自动完成。

但是,如果您已经关注微观级别的性能,那么您不需要魔术方法,因为这些方法肯定更慢。

除此之外,Magic Methods不能替代getter和setter,而是在调用不可访问的属性或方法时触发的错误处理程序。

此外,魔术方法并不明显,难以阅读API。

答案 2 :(得分:0)

请记住,我的代码认为属性的名称已经用小写声明...

  <?php

    class Modelo {
        var $attr1 = "default";
        var $attr2 = 0;


        public function __call($name, $arguments)
        {
            if (method_exists($this, ($method = $name))){
                return $this->$method();
            }
            else{       
                $attribute = split("get",$name);
                if(count($attribute)==2){
                    $attribute = strtolower($attribute[1]);
                    if(isset($this->$attribute)){
                        return ($this->$attribute);
                    }
                }else{
                    $attribute = split("set",$name);
                    if(count($attribute)==2){
                        $attribute = strtolower($attribute[1]);
                        if(isset($this->$attribute) && count($arguments)==1){
                            $this->$attribute=$arguments[0];
                        }else{
                            die("$name number of arguments error: ".join($arguments,","));
                        }
                    }else{
                        die("$name doesn't exist!");
                    }               
                }           
            }
        }


    }

    echo "<pre>";
    $m = new Modelo();
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );
    echo "setAttr1\n";
    $m->setAttr1("by set method");
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );

    ?>

答案 3 :(得分:0)

如前所述,你的班级应该有这么多属性,这很奇怪。但是,它有时(尽管很少)会发生。但通常情况下,这些属性应该有一种链接:所以你可以将它们存储在一个hashmap而不是一个属性中。然后你只需要一个方法作为吸气剂。

现在,它肯定会消耗更多资源,这是真的。至于自动完成,使用常量:你只需输入类似:

 $my_class->getFromHashMap($parameter)

在输入参数时,您将使用存储在类中的常量:此处,自动完成应该能够帮助您。

答案 4 :(得分:0)

要使通过魔术方法实现的类的属性由IDE高亮显示,只需使用@property PHPDoc @property标记,如下所示:

<?php
/**
* @property int id Blog post ID
* @property string title Blog post Title
*/
class Post {

}

有关PHPDoc的更多信息'@property here:http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html

至于其他受质疑的问题 - Karoly Horvath的评论完全涵盖了那些PHP OOP a lot of setters, getters

答案 5 :(得分:0)

你可以试试这个:

特质get_set {

public function set($what, $value)
{
    $this->{$what} = $value;
}

public function get($what)
{
    return $this->{$what};
}

}

它适用于公共变量和受保护变量。您可以添加if(!isset($ this-&gt; {$ what})error()