将变量$绑定到可呼叫对象字段的最短方法是什么?

发布于 2025-01-25 04:57:02 字数 1294 浏览 3 评论 0原文

我将$ this变量绑定到CLOSURE :: BIND() method(行12-13)到我的getName()getage()方法(第4和7行),以便在stdclass的情况下,可以参考自己的成员字段(第2-3行)。它有效,但我发现这有点乏味。

我可以在我的stdclass getName() and getage()中,可以参考stdclass的当前实例 方法(第4和7行)无调用CLOSURE :: bind()方法?或者,如果有的话,有什么解决方法吗?

PHP代码

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function() {
        var_dump($this->name);
    },
    'getAge' => function() {
        var_dump($this->age);
    },
];

$human->getName = Closure::bind($human->getName, $human);
$human->getAge = Closure::bind($human->getAge, $human);

print_r($human);

($human->getName)();
($human->getAge)();

样本输出

stdClass Object
(
    [name] => John Doe
    [age] => 25
    [getName] => Closure Object
        (
            [this] => stdClass Object
 *RECURSION*
        )

    [getAge] => Closure Object
        (
             [this] => stdClass Object
 *RECURSION*
        )

)
string(8) "John Doe"
int(25)

I bound the $this variable with Closure::bind() method (lines 12-13) to my getName() and getAge() methods (lines 4 and 7) so that they can refer to their own member fields (lines 2-3) in an instance of stdClass. It works, but I find this a bit tedious.

Is there any special variable or built-in function that I can refer to the current instance of stdClass inside my getName() and getAge() methods (lines 4 and 7) without calling Closure::bind() method? Or, is there any workaround to this, if any?

PHP Code

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function() {
        var_dump($this->name);
    },
    'getAge' => function() {
        var_dump($this->age);
    },
];

$human->getName = Closure::bind($human->getName, $human);
$human->getAge = Closure::bind($human->getAge, $human);

print_r($human);

($human->getName)();
($human->getAge)();

Sample Output:

stdClass Object
(
    [name] => John Doe
    [age] => 25
    [getName] => Closure Object
        (
            [this] => stdClass Object
 *RECURSION*
        )

    [getAge] => Closure Object
        (
             [this] => stdClass Object
 *RECURSION*
        )

)
string(8) "John Doe"
int(25)

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

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

发布评论

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

评论(2

白馒头 2025-02-01 04:57:02

首先:尽管有问题主体称其为这样,但getNamegetage不是方法。在PHP中,方法和字段生活在单独的名称空间中:方法总是在类上查找,而在实例上则查找字段。如果呼叫表达式看起来像$ human-> getName()$ human-> getage()而不是($ human-> getName) ()($ human-> getage)(),他们将查找相应的stdclass 方法,哪个当然不存在,所以他们会失败。

此外,一旦读取了字段值,就会丢弃其读取的对象,并且不再使用。获得的价值恰好是可召唤的没有什么区别。由于对象被丢弃,所以没有什么可以绑定$ this变量与闭合内部的$。这与JavaScript不同,该方法完全等于字段,它们共享一个单个名称空间,并调用一个函数,只是在调用函数的主体中以将对象绑定为对象。

我认为您实际想要实现的目标是最好通过匿名类

$human = new class {
    public $name = 'John Doe';
    public $age = 25;

    public function getName() {
        var_dump($this->name);
    }

    public function getAge() {
        var_dump($this->age);
    }
};

$human->getName();
$human->getAge();

这使getName and getage 实际方法,它接收适当的$ this this < /代码>绑定。

您甚至可以使您的匿名类成为stdclass的子类,尽管我没有看到任何特殊原因。

First of all: despite the question body calling them such, getName and getAge are not methods. In PHP, methods and fields live in separate namespaces: methods are always looked up on the class, whereas fields are looked up on the instance. If the call expressions looked like $human->getName() and $human->getAge() instead of ($human->getName)() and ($human->getAge)(), they would be looking up the corresponding stdClass methods, which of course don’t exist, so they would fail.

Furthermore, once a field value is read, the object where it was read from is discarded and not used any further; it makes no difference that the value obtained happens to be callable. Because the object is discarded, there is nothing to bind the $this variable to inside the closure. This is unlike JavaScript, where methods are exactly equivalent to fields, they share a single namespace, and invoking a function just looked up on an object binds that object as this within the invoked function’s body.

I think what you actually want to accomplish is best achieved with an anonymous class:

$human = new class {
    public $name = 'John Doe';
    public $age = 25;

    public function getName() {
        var_dump($this->name);
    }

    public function getAge() {
        var_dump($this->age);
    }
};

$human->getName();
$human->getAge();

This makes getName and getAge actually methods, which receive the appropriate $this binding.

You can even make your anonymous class a subclass of stdClass if you insist, though I see no particular reason why.

雄赳赳气昂昂 2025-02-01 04:57:02

我认为您应该为为什么要这样做一个更好的理由。也就是说,closure :: bind()确实有些乏味。您可以做些什么,但我怀疑您会喜欢的。它是这样的:

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function($object) {
        var_dump($object->name);
    },
    'getAge' => function($object) {
        var_dump($object->age);
    },
];

($human->getName)($human);
($human->getAge)($human);

请参阅: php小提琴

在这里您承认,在创建时,functions functions apen apen'当$ $ this是有意义的时,意识到它们是对象的一部分。因此,您以后将需要的对象作为参数提供,一切都很好。

同样,如果仅仅因为更容易理解,则创建正常类是可取的。请记住,您编写代码做某事,也是因为这是一种向自己和他人传达意图的方式。

我想到了另一种方法。也不是您想要的,而是有效的:

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function() {
        global $human;
        var_dump($human->name);
    },
    'getAge' => function() {
        global $human;
        var_dump($human->age);
    },
];

($human->getName)();
($human->getAge)();

请参阅: php fiddle

I think you should make a better case for why you would want to do this. That said, the Closure::bind() is indeed a bit tedious. There is something you can do, but I doubt you will like it. It goes like this:

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function($object) {
        var_dump($object->name);
    },
    'getAge' => function($object) {
        var_dump($object->age);
    },
];

($human->getName)($human);
($human->getAge)($human);

See: PHP fiddle

Here you admit that, at the time of creation, the functions aren't aware that they are part of an object, when $this would make sense. Therefore you supply the needed object later as an argument, and everything is fine.

Again, creating a normal class would be preferable, if only because it is easier to understand. Remember, you write code to do something, but also because it is a way to communicate your intent to yourself and others.

I thought of another way to do this. Also not what you want, but it kind of works:

$human = (object) [
    'name' => 'John Doe',
    'age'  => 25,
    'getName' => function() {
        global $human;
        var_dump($human->name);
    },
    'getAge' => function() {
        global $human;
        var_dump($human->age);
    },
];

($human->getName)();
($human->getAge)();

See: PHP fiddle

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