PHP类可以动态声明其属性吗?

时间:2012-09-26 20:37:30

标签: php oop class if-statement attributes

通常当我写一个PHP类时,我做了类似的事情:

class MyClass () {
   public attribute1;
   public attribute2;
   public attribute3;
}

是否可以根据逻辑设置属性?

class MyClass () {

   public function __construct() {
      if (some condition) {
         public attribute1;
         attribute1 = 23;
      } else {
         public attribute1;
         attribute1 = 55;
         public attribute2;
         attribute2 = 11;        
      }
   }
}

6 个答案:

答案 0 :(得分:3)

像其他人说的那样,使用$this->param = 11;,但我不喜欢这个想法,因为我不喜欢我的课程中未声明的变量

在类定义中声明变量是为了提高可读性,您可以设置private,public和protected。在java中这是不允许的,因此应该在php中,它应该是错误

如果您不知道将使用哪些变量,使用魔术方法 _get() _set()

示例代码:

class MyClass {

    private $store = [];

    public function __get($name)
    {
        return isset($this->store[$name]) ? $this->store[$name] : null; # or output error
    }

    public function __set($name, $value)
    {
        $this->store[$name] = $value;
    }

    public function __construct()
    {
        if (rand(0,1)) {
            $this->attribute1 = 12;
        } else {
            $this->attribute2 = 21;
        }
    }

}

var_dump( (new MyClass)->attribute1 );
var_dump( (new MyClass)->attribute1 );
var_dump( (new MyClass)->attribute1 );

输出:

int(12)
NULL
int(12)

答案 1 :(得分:2)

是的,但你是这样做的:

class MyClass () { 

   public function __construct() { 
      if (some condition) { 
         $this->attribute1 = 23; 
      } else { 
         $this->attribute1 = 55; 
         $this->attribute2 = 11;         
      } 
   } 
} 

并且属性将始终公开。

答案 2 :(得分:2)

首次访问属性时会创建该属性。正如其他人所说,它不被视为一种好的做法,它被称为 monkey patching ,并且只能在动态语言中使用(即那些不涉及编译器的语言,至少在开发者方面)。 / p>

这不是一个好习惯,因为如果你不把你的字段放在一个集中的地方,自动生成工具将无法工作,代码助手可能无法正常工作,代码库的其他贡献者可能无法理解你的代码。

然而,总是是一种不好的做法。例如,CakePHP(MVC框架)使用以下技术来加速某些类的编写。当您像这样扩展Controller类时

class ThingsController extends AppController {

  var $components = array("Foo", "Bar", "Baz");

  function index() {
    $this->Foo($this->Bar->bar());
  }

}

基类构造函数检查$components变量以动态加载FooBarBaz类,并使它们在实例变量中自动可用,例如{在$this->Foo内{1}}。然而,这在文档中已明确说明,并且是在现代框架中彻底用于提供魔术变量的约定,即未在代码中直接声明的变量。这种用法可以节省打字,但代价是打破了上述工具的支持 - 更不用说新开发人员经常会遇到一些麻烦:P

答案 3 :(得分:1)

首次调用时会创建不存在的属性。

class MyClass () {

   public function __construct() {
      if (some condition) {
         $this->attribute1 = 23;
      } else {
         $this->attribute1 = 55;
         $this->attribute2 = 11;        
      }
   }
}

但这样做不是一个好习惯。这样,您将不得不在项目中搜索任何地方的属性声明。想想你的队友(如果有的话)或你未来的自我。您应该明确定义类具有的所有属性,否则您肯定会忘记定义它们的位置。

答案 4 :(得分:0)

是的,你不会在方法中使用public attribute1;'。您可以使用$this->attribute1 = 23;$this->attribute2 = 11;

答案 5 :(得分:0)

当然。

class MyClass () {
   public $attribute1;

   public function __construct($an_array = NULL) {
      if ($an_array) {
         $this->attribute1 = $an_array;  
      }
   }
}