2009-12-17 44 views
0

我不知道这是否是一个微不足道的问题,但在PHP类:在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。我写得很快,所以请忽略我在设置类或调用方法时所犯的任何错误!

编辑 如何使这些实例变量,我创建私人?

EDIT 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... 

} 

我可以把它放在一个关联数组,但我永远不能正确名称阵列有意义的事(即$用户>数据[“名”] ...丑陋)。无论哪种方式,你必须知道数据库中的内容,所以我不明白什么是它的混淆,特别是因为你可以只为变量转储对象。

+0

[您可以在PHP中动态创建实例属性?](http://stackoverflow.com/questions/829823/can-you-create-instance-properties-dynamically-in-php) – outis 2012-07-11 22:25:41

回答

5

是的,这将确实有效。自动创建的实例变量被公开显示。

+5

太棒了!那么让他们变得私密呢?这有可能吗? – Matt 2009-12-17 08:13:55

2

是的,就像你希望的那样工作。

+1

你知道我会如何使变量私人? – Matt 2009-12-17 08:18:44

+0

你不能那样做。我不明白你为什么要这样做。无论如何,最好的做法是声明你使用的所有变量。 – 2009-12-17 08:24:01

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()); 

会抛出关于 '酒吧' 是未知的异常,而

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

将返回true。

现在,你应该做这种类型的任务吗?答案是否定的。这不是很好的OOP设计。请记住,OOP是关于封装的。因此,如果bar正在描述该类的某些公共属性,请将其明确并在您的课程中声明为public $bar。如果它应该是私人声明为private $bar。更好的是,根本不使用公共属性,并使它们成为protected,并且只能通过getter和setters来访问它们。这将使界面更清晰和更清晰,因为它表达了对象实例应该可能进行的交互。

在您的代码中随时随地分配属性会使您的代码保持一个噩梦。试想一下,沿着某处富的人的lifecylce做到这一点:

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

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

现在,从看一下上面的类定义,也绝对没有办法,开发人员可以看到现在有修补成富猴子。这会使调试变得很痛苦,特别是如果这样的代码很频繁并且分布在多个文件中。

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 
?> 

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

+0

如果您只希望课程有权访问它。看到我上面的修订。如果我想要某人的信用卡号码 - 也许数据库可以检索它 - 但我将不得不打电话给getCreditCard()以获得它的一些加密版本,例如... – Matt 2009-12-17 20:19:50