0

我来自.Net 背景,我正试图将我的大脑围绕我习惯但在 PHP 中的编程模式。

我有一个具有关联数组属性的类。我想将一些但不是全部的关联数组键“提升”到类级属性。在 C# 中,我通常会这样做:

//C# Code
class MyClass{
    private Dictionary<string, string> attributes = new Dictionary<string,string>();

    //Get/Set the ID from the private store
    public string ID{
        get { return (attributes.ContainsKey("ID") ? attributes["ID"] : "n/a"); }
        set { attributes.Add("ID", value); }
    }
}

这允许我的对象控制缺失属性的默认值。在 PHP 中,我找不到任何直接执行此操作的方法。我的第一个解决方法是只使用函数:

//PHP Code
class MyClass{
  private $attributes = array();

  //Get the ID    
  public function getID(){
    return (array_key_exists('ID', $this->attributes) ? $this->attributes['ID'] : 'n/a');
  }
  //Set the ID
  public function setID($value){
    $this->attributes['ID'] = $value;
  }
}

尽管调用语法略有不同,并且每个属性都有两种方法,但这仍然有效。此外,使用这些对象的代码当前正在检查对象变量,因此找不到函数。

然后我开始沿着对象本身的魔法方法路径,__set只是__getswitch case传入的对象上$name设置/获取我的局部变量。不幸的是,如果您直接修改底层数组,则不会调用这些方法。

所以我的问题是,在 PHP 中是否有可能有一个在使用之前不会计算的类级属性/变量?

4

2 回答 2

2

PHP 没有属性,因为 C# 程序员会理解这个概念,因此您必须使用方法作为 getter 和 setter,但原理完全相同。

class MyClass {
    private $attributes = array ();

    public function getSomeAttribute () {
        if (!array_key_exists ('SomeAttribute', $this -> attributes)) {
            // Do whatever you need to calculate the value of SomeAttribute here
            $this -> attributes ['SomeAttribute'] = 42;
        }
        return $this -> attributes ['SomeAttribute'];
    }
    // or if you just want a predictable result returned when the value isn't set yet
    public function getSomeAttribute () {
        return array_key_exists ('SomeAttribute', $this -> attributes)?
            $this -> attributes ['SomeAttribute']:
            'n/a';
    }

    public function setSomeAttribute ($value) {
        $this -> attributes ['SomeAttribute'] = $value;
    }
}

您的实现基本上得到了正确的基本想法,但这确实意味着很多“样板”代码。从理论上讲,您可以使用 __get 和 __set 避免很多这种情况,但我强烈建议您不要这样做,因为它们会导致大量的混乱和令人讨厌的逻辑纠结,例如“如果在类中设置值而不是从外面?” 您遇到的问题。

于 2013-10-29T22:29:07.693 回答
0

在 PHP 中你可以这样做:

<?php
class MyClassWithoutParams{
    function test(){
      return $this->greeting . " " . $this->subject;
    }
}

$class = new MyClassWithoutParams();
$class->greeting = "Hello";
$class->subject = "world";

echo $class->greeting . " " . $class->subject . "<br />"; //Hello World
echo $class->test(). "<br />"; //Hello World
?>

您无需定义任何属性、getter 或 setter 即可使用属性。当然,这样做更好,因为它使代码更易于阅读,并允许 eclipse(或任何 IDE)的自动完成功能来理解您正在寻找的内容 - 但如果您只是在寻找最懒惰的方式来实现实体,这也可以。

一种更常见的方法是使用关联数组而不是类 - 但在数组上您不能定义方法。

<?php
$array = new array();

$array["greeting"] = "Hello";
$array["subject"] = "World";

echo $array["greeting"] . " " . $array["subject"]; //Output: Hello World
?>
于 2013-10-29T23:00:46.780 回答