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

Mat*_*att 0 php class

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

我的课:

class MyClass {
   public $var1;
   public $var2;

    constructor() { ... }

    public method1 () {

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


    }
}
Run Code Online (Sandbox Code Playgroud)

主要:

$test = new MyClass();
$test->method1();
echo $test->var3; // Would return "test"
Run Code Online (Sandbox Code Playgroud)

这有用吗?我怎么能让这个工作?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...

}
Run Code Online (Sandbox Code Playgroud)

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

Gor*_*don 6

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

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

$foo = new Foo;
echo $foo->bar; // outputs 'baz'
Run Code Online (Sandbox Code Playgroud)

var_dump($foo);
Run Code Online (Sandbox Code Playgroud)

object(Foo)#1 (1) {
    ["bar"] => string(3) "baz"
}
Run Code Online (Sandbox Code Playgroud)

$r = new ReflectionObject($foo);
$p = $r->getProperty('bar');
var_dump($p->isPublic());
Run Code Online (Sandbox Code Playgroud)

将抛出关于'bar'未知的异常,而

$r = new ReflectionObject($foo);
$p = $r->getProperties();
var_dump($p[0]->isPublic());
Run Code Online (Sandbox Code Playgroud)

将返回真实.

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

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

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

echo $foo->monkey; // outputs 'ugh'
Run Code Online (Sandbox Code Playgroud)

现在,通过查看上面的类定义,绝对没有办法,开发人员可以看到现在有一​​只猴子修补了Foo.这将使调试成为一种痛苦,特别是如果像这样的代码频繁并分布在多个文件中.


DMI*_*DMI 5

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

  • 大!然后把它们变成私人的......那可能吗? (5认同)