PHP stdClass() 和 __get() 魔术方法

发布于 2024-08-14 07:08:11 字数 660 浏览 1 评论 0原文

以以下代码为例:

class xpto
{
    public function __get($key)
    {
        return $key;
    }
}

function xpto()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new xpto();
    }

    return $instance;
}

echo xpto()->haha; // returns "haha"

现在,我尝试归档相同的结果,但不必编写 xpto 类。我的猜测是我应该写这样的东西:

function xpto()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new stdClass();
    }

    return $instance;
}

echo xpto()->haha; // doesn't work - obviously

现在,是否可以将 __get() 魔术功能添加到 stdClass 对象?我想不是,但我不确定。

Take the following code as an example:

class xpto
{
    public function __get($key)
    {
        return $key;
    }
}

function xpto()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new xpto();
    }

    return $instance;
}

echo xpto()->haha; // returns "haha"

Now, I'm trying to archive the same result but without have to write the xpto class. My guess is I should have to write something like this:

function xpto()
{
    static $instance = null;

    if (is_null($instance) === true)
    {
        $instance = new stdClass();
    }

    return $instance;
}

echo xpto()->haha; // doesn't work - obviously

Now, is it possible to add __get() magic functionality to the stdClass object? I guess not, but I'm not sure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡離愁欲言轉身 2024-08-21 07:08:11

不,这是不可能的。您不能向 stdClass 添加任何内容。此外,与 Java 不同,Java 中每个对象都是 Object 的直接或间接子类,而 PHP 中的情况并非如此。

class A {};

$a = new A();

var_dump($a instanceof stdClass); // will return false

你真正想达到什么目的?你的问题听起来有点像“我想关上车门,但没有车”:-)。

No, it is not possible. You cannot add anything to stdClass. Also, unlike Java, where every object is a direct or indirect subclass of Object, this is not the case in PHP.

class A {};

$a = new A();

var_dump($a instanceof stdClass); // will return false

What are you really trying to achieve? Your question sounds a bit like "I want to close the door of my car, but without having a car" :-).

箹锭⒈辈孓 2024-08-21 07:08:11

OP看起来他们正在尝试使用全局范围内的函数来实现单例模式,这可能不是正确的方法,但无论如何,关于Cassy的回答,“你不能向stdClass添加任何内容” - 这不是真的。

您可以简单地通过为 stdClass 赋值来向它们添加属性:

$obj = new stdClass();
$obj->myProp = 'Hello Property';  // Adds the public property 'myProp'
echo $obj->myProp;

但是,我认为您需要 PHP 5.3+ 才能添加方法(匿名函数/闭包),在这种情况下您可能可以执行类似的操作下列。不过,我没有尝试过这个。但如果这确实有效,你能用神奇的 __get() 方法做同样的事情吗?

更新: 正如评论中所指出的,你不能以这种方式动态添加方法。分配一个匿名函数(PHP 5.3+)就可以做到这一点,并且简单分配一个函数(严格来说是一个闭包对象) 公共财产。

$obj = new stdClass();
$obj->myMethod = function($name) {echo 'Hello '.$name;};

// Fatal error: Call to undefined method stdClass::myMethod()
//$obj->myMethod('World');

$m = $obj->myMethod;
$m('World');  // Output: Hello World

call_user_func($obj->myMethod,'Foo');  // Output: Hello Foo

The OP looks like they are trying to achieve a singleton pattern using a function in the global scope which is probably not the correct way to go, but anyway, regarding Cassy's answer, "You cannot add anything to stdClass" - this is not true.

You can add properties to the stdClass simply by assigning a value to them:

$obj = new stdClass();
$obj->myProp = 'Hello Property';  // Adds the public property 'myProp'
echo $obj->myProp;

However, I think you need PHP 5.3+ in order to add methods (anonymous functions / closures), in which case you might be able to do something like the following. However, I've not tried this. But if this does work, can you do the same with the magic __get() method?

UPDATE: As noted in the comments, you cannot dynamically add methods in this way. Assigning an anonymous function (PHP 5.3+) does just that and simply assigns a function (strictly a closure object) to a public property.

$obj = new stdClass();
$obj->myMethod = function($name) {echo 'Hello '.$name;};

// Fatal error: Call to undefined method stdClass::myMethod()
//$obj->myMethod('World');

$m = $obj->myMethod;
$m('World');  // Output: Hello World

call_user_func($obj->myMethod,'Foo');  // Output: Hello Foo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文