0

如果我有一个类(如下所示)并且在一个函数中我设置了一个变量(如下:$this->example)但我没有在类的顶部声明变量(例如 var $example;)我在哪里以及如何使用这个变量?我尝试直接在另一个函数中使用它,但它没有用(我想我可能犯了一个错误,但在我在类的顶部声明它之后它就起作用了)

我在 Symfony 中看到了这一点,用于设置您可以在视图中使用的变量,并且我在 Phorms 中遇到了它以举几个例子。

抱歉,如果这很明显,我只想了解如何使用这些变量,包括获取变量的名称(例如 $this->example,我的意思是“示例”)。

class ExampleClass{
  var $another_var;
  function __construct($data){
    $this->example = $data;
    $this->another_var = $data;
  }

  function exampleFunction(){
    $test = $this->example; //this doesnt work
    $another_test = $this->another_var; //this obviously does
  }
}

任何帮助将非常感激

问候

卢克

编辑:(来自我对 DrColossus 的回复)

我希望能够在一个函数中设置任何变量名称,并在另一个函数中获取任何具有该名称的变量。例如,在 Symfony 中,我可以在动作类函数中设置 $this->completly_random_name = $x,然后在视图中我可以使用 $completly_random_name。symfony 不可能在父类的顶部设置所有可能的变量名组合。

4

4 回答 4

11

Skipping the talk of how you normally shouldn't do this, you can accomplish what you want using PHP's magic __get and __set functions.

class MyClass {
  // add one member var that holds all the data
  private $myMagicData = array();

  private $another_var;

  function __construct($data){
    $this->example = $data; // this will auto-call the __set function
    $this->another_var = $data; // this won't, since $this->another_var was declared above
  }

  function __get($name) {
    return array_key_exists($name, $this->myMagicData) ? $this->myMagicData[$name] : null;
  }

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

  function exampleFunction(){
    $test = $this->example; // this will auto-call the __get function
    $another_test = $this->another_var; // this won't
  }
}

Documentation on these and other magic functions.


Why you shouldn't do this.

In my opinion, using the magic __get and __set functions promotes poor programming practice. Let me demonstrate using a famous example: If a glass is half-filled, is the glass half-full or half-empty? The correct answer from a programmer's point of view is that the glass is too large. What I mean by this is, when you add the magic functions as demonstrated above, you can just keep on assigning variables and it won't care, but are they necessary?

Over time, your code will change and you might no longer need old variables that were previously assigned. Normally, you would just remove the variable declaration, meaning your class will now consume less (unneeded) memory. If you forgot to remove one of the old assignments, you'll find out soon enough. With the magic function functionality, how are you going to keep track of which variables you need, and which you don't?

Remember that code should be written primarily for humans to read, and only secondarily for machines to execute. If a second person were to join you and he wonders what variables he has access to in the view, he would either have to go through the code assigning the variables, or print_r($this->myMagicData), rather than just looking at the section of the class where the variables are declared.

And, of course, there is also the overhead of the magic functions getting called, which may or may not be a concern depending on the situation.

So, to summarize, manually declaring the variables you need helps:

  1. Keep track of what data you are and aren't using
  2. Makes your code easier to read for both you and others
  3. Performs faster

Hope this helps!

于 2010-06-24T09:38:36.943 回答
2
class ExampleClass{
  private $another_var;
  private $example;

  public function __construct($data){
    $this->example = $data;
    $this->another_var = $data;
  }

  public function getExample() {
    return $this->example;
  }

  public function setExample($example) {
    $this->example = $example;
  }

  public function exampleFunction()
    $test = $this->example; //now that you have a private $example, this will work
    $another_test = $this->another_var; //this obviously does
  }
}

使用公共的 Getter/Setter 来访问私有变量。

编辑 Aistina 比我快,他的示例展示了如何访问/检索任何变量名称。

于 2010-06-24T09:22:20.807 回答
0

我不是这方面的专家,但我的 OO 条件思维告诉我,无论使用什么语言都不定义类成员变量是不好的做法。

也许您提到的框架在子类中使用这种模式,其中成员在超类中定义?

对于第二个问题:你应该看看php的反射类 反射帮助你找出一个类的结构(构造函数、方法、属性)。

于 2010-06-24T09:24:18.163 回答
0

默认情况下,类属性被定义为公共的,但你不应该这样做。您应该定义私有/受保护的属性并定义 getter/setter 方法以从类外部使用它们。以后维护起来容易得多。。

于 2010-06-24T09:18:24.777 回答