在PHP类中动态创建实例变量

时间:2009-12-17 08:07:28

标签: php class

我不确定这是一个微不足道的问题,但是在PHP类中:

MyClass的:

class MyClass {
   public $var1;
   public $var2;

    constructor() { ... }

    public method1 () {

    // Dynamically create an instance variable
         $this->var3 = "test"; // Public....?


    }
}

主要

$test = new MyClass();
$test->method1();
echo $test->var3; // Would return "test"

这有用吗?我怎么能让这个工作? PS。我写的很快,所以请忽略我在设置课程或调用方法时所犯的任何错误!

修改 如何创建我创建私有的实例变量?

编辑2 感谢大家的回应 - 每个人都是对的 - 我应该自己测试一下,但是第二天早上我参加了考试,并且在学习的过程中有了这个想法,我想检查一下是否有效。人们一直在暗示其糟糕的OOP - 也许它确实允许一些优雅的代码。让我解释一下,看看你是否仍然这么认为。这就是我想出的:

//PHP User Model: 

class User {
    constructor() { ... }

    public static find($uid) {
         $db->connect(); // Connect to the database

         $sql = "SELECT STATEMENT ...WHERE id=$uid LIMIT 1;";
         $result = $db->query($sql); // Returns an associative array

         $user = new User();

         foreach ($result as $key=>$value)
            $user->$$key = $value; //Creates a public variable of the key and sets it to value

         $db->disconnect();
    }
}

//PHP Controller:

function findUser($id) {

    $User = User::find($id);

    echo $User->name;
    echo $User->phone;
    //etc...

}

我可以把它放在一个关联数组中,但是我永远无法正确地命名那个有意义的数组(即$ user-> data ['name'] ......丑陋。)无论哪种方式,你都要知道是什么在数据库中,所以我真的不明白它的混淆是什么论点,特别是因为你可以只使用var转储对象进行调试。

5 个答案:

答案 0 :(得分:6)

为什么不编写代码并自己查看?

<?php
class Foo
{
    public function __construct()
    {
        $this->bar = 'baz';
    }
}

$foo = new Foo;
echo $foo->bar; // outputs 'baz'

var_dump($foo);

给出

object(Foo)#1 (1) {
    ["bar"] => string(3) "baz"
}

$r = new ReflectionObject($foo);
$p = $r->getProperty('bar');
var_dump($p->isPublic());

会抛出一个关于'bar'未知的异常,而

$r = new ReflectionObject($foo);
$p = $r->getProperties();
var_dump($p[0]->isPublic());

将返回true。

现在,你应该做这种类型的任务吗?答案是否定的。这不是好的OOP设计。请记住,OOP是关于封装的。因此,如果bar描述了类的某些公共属性,请将其显式化并在类中将其声明为public $bar。如果它应该是私有的,则将其声明为private $bar。更好的是,根本不要使用公共属性并使它们protected并仅通过getter和setter提供对它们的访问。这将使界面更清晰,更清晰,因为它传达了对象实例可能的交互。

在您的代码中随时随地分配属性将使维护代码成为一场噩梦。想象一下,在Foo的生命周期的某个地方有人这样做:

$foo = new Foo;
$foo->monkey = 'ugh';

echo $foo->monkey; // outputs 'ugh'

现在,从上面的类定义来看,绝对没有办法,开发人员可以看到现在有一​​只猴子修补了Foo。这将使调试变得很麻烦,特别是如果像这样的代码频繁并分布在多个文件中。

答案 1 :(得分:5)

是的,确实会奏效。自动创建的实例变量具有公共可见性。

答案 2 :(得分:2)

是的,这是你希望/期望的。

答案 3 :(得分:2)

我想动态制作私有变量,你可以使用php魔术函数来模拟这个,例如

<强> MyClass的

<?php
class MyClass {
    public $var1;
    public $var2;
    private $data = array();

    public function __get($key) {
        // for clarity you could throw an exception if isset($this->data[$key]) 
        // returns false as it is entirely possible for null to be a valid return value
        return isset($this->data[$key]) ? return $this->data[$key] : null;
    }

    public function __set($key, $value) {
        $this->data[$key] = $value;
    }
}
?>

主要

<?php
$test = new MyClass();
$test->myVar = 'myVar is technically private, i suppose';
echo $this->myVar; // 'myVar is technically private
?>

虽然这些动态创建的变量在技术上是私有的,但它们实际上是公共可访问的...我无法想象想要动态创建私有实例变量的目的。我会质疑你的设计。

答案 4 :(得分:1)

你试过吗?

有可能但你可能会遇到严格的错误。如果你动态地需要创建这些变量,那么你可能做错了。

你应该把它改成一个函数:

function var($no) { .. }

或使用__get(http://ca.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members