Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中像在C#中一样获取和设置(私有)属性,而不使用getter setter魔术方法重载 总结_Php_Properties_Getter Setter_Setter_Getter - Fatal编程技术网

在PHP中像在C#中一样获取和设置(私有)属性,而不使用getter setter魔术方法重载 总结

在PHP中像在C#中一样获取和设置(私有)属性,而不使用getter setter魔术方法重载 总结,php,properties,getter-setter,setter,getter,Php,Properties,Getter Setter,Setter,Getter,代码示例: Class People { // private property. private $name; // other methods not shown for simplicity. } 直截了当。让我假设$name是私有的类成员(或者属性、变量、字段,可以随意调用)。在PHP中有什么方法可以做到这些: $someone = new People(); $someone->name = $value; $somevar = $someone-&g

代码示例:

Class People {
    // private property.
    private $name;

    // other methods not shown for simplicity.
}
直截了当。让我假设
$name
私有的类成员(或者属性、变量、字段,可以随意调用)。在PHP中有什么方法可以做到这些:

$someone = new People();
$someone->name = $value;
$somevar = $someone->name;
不使用使用
获取($name)
设置($name,$value)


背景 我需要检查分配的
$value
,因此我只需要一个如下的getter setter:

getName();
setName($value);
__get($value); 
__set($value, $name);
必须是一个getter setter魔法方法重载,如下所示:

getName();
setName($value);
__get($value); 
__set($value, $name);
也就是说,我只需要一个能手。但那不是我想要的。它只是感觉不象面向对象的,因为来自C++或C语言的静态类型语言的人可能会有和我一样的感觉。p> 有没有办法像在C#中一样在PHP中获取和设置私有属性,而不使用getter setter魔术方法重载


更新

为什么不使用魔法?
  • 网络上流传着这样的谣言:magic方法比显式getter-setter方法慢10倍,我还没有测试过它,但要记住这是一件好事。(计算出它没有那么慢,只是慢了2倍,请参见下面的基准测试结果)

  • 如果我使用magic方法,而不是像显式getter setter那样将每个属性拆分为不同的函数,那么我必须将所有内容填充到一个巨大的方法中。(这项要求可能由以下人员回答)

  • 性能开销基准测试 我对使用magic方法和显式getter setter之间的性能开销很好奇,因此我为这两种方法创建了自己的基准测试,希望它对阅读本文的任何人都有用

    有魔法方法和方法存在:

    (单击以查看代码)

    • 吸气剂消耗0.0004730224609375秒
    • 二传成本为0.0001430514746094秒
    使用显式getter setter:

    (单击以查看代码)

    • 吸气剂消耗0.00020718574523926秒
    • Setter的成本为7.9870223999023E-5秒(即0.00007xxx)

    这就是说,setter和getter与magic方法和method exists的成本都是显式getter setter的2倍。我认为将其用于中小型系统仍然是可以接受的

    > P>如果使用魔法属性似乎不正确,正如其他海报所指出的,你也可以考虑和。 或者在类本身上实现必要的getter和setter方法

    作为对您提出的语言特性问题的回应,我认为动态类型的语言与静态类型的语言是不同的。每种具有OOP的编程语言的实现方式都有所不同:

    但是,使用分别充当
    getName()
    setName($val)
    的动态代理的
    \uu get
    \uu set
    有什么错?比如:

    public function __get($name) { 
        if (method_exists($this, 'get'.$name)) { 
            $method = 'get' . $name; 
            return $this->$method(); 
        } else { 
            throw new OutOfBoundsException('Member is not gettable');
        }
    }
    
    这样你就不会把所有的东西都塞进一个怪物方法中,但你仍然可以使用
    $foo->bar='baz'带有私有/受保护成员变量的语法

    ReflectionClass is your salvation
    
    我知道现在对亨德拉来说已经太晚了,但我相信这对其他很多人都会有帮助

    在PHP核心中,我们有一个名为ReflectionClass的类,它可以操作对象范围内的所有内容,包括属性和方法的可见性

    在我看来,它是PHP中最好的类之一

    让我举一个例子:

    如果您有一个具有私有属性的对象,并且希望从外部对其进行修改

    $reflection = new ReflectionClass($objectOfYourClass);
    $prop = $reflection->getProperty("PrivatePropertyName");
    $prop->setAccessible(true);
    $prop->setValue($objectOfYourClass, "SOME VALUE");
    $varFoo = $prop->getValue();
    
    同样的事情,你可以做的方法第十八


    我希望我能帮忙

    不符合你的要求__get和#u set是实现C#式智能字段所必需的语言构造。我想这就是我从每个人那里听到的,只是好奇是否有一个真正的“魔法”方法不使用魔法方法。:)“方法不可获取”也许?;-)好主意。我甚至没有想到从magic方法代理显式getter setter。发现使用魔法方法的成本只有显式getter setter的2倍,不像传言说的慢10倍,谁在传播谣言?@Hendra:这是一个微优化,最多可以担心,因为它相当快,即使慢10倍。在旧版本的PHP中,速度可能较慢,但最近的版本要快得多……谢谢,我只是好奇是否有我不知道的技术或方法。顺便问一下,你发布的链接是什么,里面没有php,不是针对埃菲尔铁塔的吗?@Hendra Uzia:这是为了说明没有规范的OOP标准。特性依赖于特定的语言,将C++的OOP规则应用到PHP并不一定是一件好事。规则是基于某些假设的,在另一种语言中,这些规则往往无效。我明白了,只是C语言影响了很多语言,人们总是会根据自己熟悉的语言来比较语言,就像我一样。@Guillhermeferreira感谢您指出这一点。现在应该可以了“如果您有一个具有私有属性的对象,并且您想从外部修改它”-换句话说,如果您想违反对象实现者创建的契约。虽然
    ReflectionClass
    确实很有用,但考虑到它的这种用途。。。有疑问。“考虑这样的使用”-这样的使用正是它要做的,而且,-在PHP中像在C#中一样获取和设置(私有)属性,而不使用getter setter魔术方法重载-这正是问题的症结所在-你的观点是什么?是的,您可以编写这样的函数。用任何语言。PHP也不例外。您对这些功能有何评论?[OP已经说过“但那不是什么
    class conf_server
    {
    
    private $m_servidor="localhost";
    private $m_usuario = "luis";
    private $m_contrasena = "luis";
    private $m_basededatos = "database";
    
    public function getServer(){
        return $this->m_servidor;
    }
    public function setServer($server){
        $this->m_servidor=$server;
    }
    public function getUsuario(){
        return $this->m_usuario;
    }
    public function setUsuario($user){
        $this->m_usuario=$user;
    }
    public function getContrasena(){
        return $this->m_contrasena;
    }
    public function setContrasena($password){
        $this->m_contrasena=$password;
    }
    public function getBaseDatos(){
        return $this->m_basededatos;
    }
    public function setBaseDatos($database){
        $this->m_basededatos->$database;
    }
    }