代码之家  ›  专栏  ›  技术社区  ›  Irwin

我应该在PHP中使用类C的属性处理吗?

  •  2
  • Irwin  · 技术社区  · 15 年前

    嘿,社区, 我在这里看到: http://www.mustap.com/phpzone_post_203_setter-and-getter 使用的参数 C常见的一种属性处理方式,即: 如果在C中,您可以定义这样的类:

    public class Person 
    {
        private string _name;
        public string Name
        {
            get{ return _name; }
            set{ _name = value; }
        }
    }
    

    那么,为什么在PHP中这样定义类似的属性是明智的或不明智的:

    public class Person
    {
        private var $name;    
    
        public function Name() 
        {
            if(func_num_args() == 0) {    return $this->name;  } 
            else {$this->name = func_get_arg(0);  }
        }
    }
    
    5 回复  |  直到 7 年前
        1
  •  6
  •   Ocelot20    15 年前

    在我看来,这在PHP中并不干净。就像你试图把C方式塞进PHP,因为你认为这是C的一个好特性。

    我认为它是:在php中,你正在制作一个 功能 因为做了两件完全不同的事情,这是没有意义的。同时,在C中,它是单的 财产 它被设计成一个单一的访问点,用于设置/检索对象。

        2
  •  4
  •   CaffGeek    15 年前

    你违反了 Single Responsibility Principle 一个函数既是getter又是setter。

    在C中,它只是语法上的糖分,被转换成getter和setter,就像您应该用PHP编写它一样。

    事实上,在C中,您可以通过编写进一步简化它。

    public string Name { get; set; }
    

    编译器将生成一个私有的支持字段,并为您生成getter和setter函数。

        3
  •  2
  •   NikiC    15 年前

    如果需要对要设置的值进行一些附加检查,您可能需要定义 getFoo setFoo 方法或更好的使用 property overloading . 后者将给用户带来原生属性获取/设置的感觉。(后者是您在C中所做的。每个类只有一个方法,不多。)

        4
  •  2
  •   RobertPitt    15 年前

    这是明智的,例如:

    class Settings
    {
        private $data = array();
    
        public function __call($key,$arguments = array())
        {
            return !count($arguments)) ? $this->data[$key] : $this->data[$key] = $arguments[0];
        }
    }
    

    然后做

    $Settings = new Settings();
    $Settings->name('hello');
    $Settings->foo('bar');
    

    现在,它创建了一个 无限的 准备使用的匿名函数的数量,通常使用2种方法构造, __get __set 通过这种方式,可以定义方法和变量的分离,示例如下

    class Settings
    {
        private $data = array();
    
        public function __set($key,$val)
        {
            $this->data[$key] = $val;
        }
        public function __get($key)
        {
            return $this->data[$key];
        }
    }
    

    这样可以设置变量,如下所示:

    $Settings->foo = 'bar';
    

    但是您可以进一步创建一个变量注册表系统:

    所以基本上你可以把上面的课从 Settings VariableStorage 并执行以下操作:

    class User extends VariableStorage{}
    class Profile extends VariableStorage{}
    

    像这样使用:

    $Profile = new Profile('Robert','Pitt',USER_PRIV_ADMIN);
    $Profile->id = 56;
    $Profile->userdata = $Database->GetUserData($Profile); //Reads $Profile->id
    

    因此,您只需定义一次方法,只要您将继承结构构建成一个好的设计,它就可以非常好地工作。

        5
  •  0
  •   Jeff Tillwick    7 年前

    我个人在PHP中使用了类似的模式。我觉得它很干净而且相当有用。

    private $name;
    public function name($name = null)
    {
        if ($name === null) return $this->name;
        $this->name = $name;
    }
    

    您甚至可以这样做来强制某种类型的安全性:

    private $name;
    public function name(string $name = null)
    {
        if ($name === null) return $this->name;
        $this->name = $name;
    }
    

    您还可以强制设置/获取引用而不是副本:

    private $name;
    public function &name(string &$name = null)
    {
        if ($name === null) return $this->name;
        $this->name = &$name;
    }
    

    这是完全有效的PHP,非常好地模拟了C。

    此外, Single Responsibility Principle 国家:

    单一责任原则是一种计算机程序设计原则,它规定每个模块或类对软件提供的功能的一个单独部分负有责任,并且该责任应完全由类封装。

    因此,这并没有打破单一责任原则,因为这只是一个用于获取/设置类成员变量的类方法。

    唯一的缺点是,在类的实例上,您必须调用函数来获取/设置成员变量,而不是真正的属性。您可以将这个设计模式与php的get和set混合使用,但这只会增加开销。