为什么这个方法调用要用引号和花括号括起来?

问题描述 投票:0回答:3

你能告诉我 PHP 语法是什么样的吗:

echo Html::{'div.my-class#my-id'}('This is element content')

来自 https://github.com/decodelabs/tagged 库。

我的意思是我知道它的作用,但我不明白所使用的语法及其工作原理:)(紧接在作用域运算符之后的大括号)。看起来他们正在使用大括号来“生成”要调用的函数的名称,但另一方面,它包含诸如“.”之类的字符。和“#”以及变量参数(“my-class”、“my-id”)。我很困惑。

php syntax static-methods method-call method-names
3个回答
1
投票

让我们从第一原理重构这个

  1. 您可以使用
    {value}
    放置动态方法/属性名称

即如果你有

class Dog {
    public string $name = 'doggy';
    public function walk() {
    }
}

你可以做

$dog = new Dog();
$dog->walk(); 
$dog->{'walk'}(); // equivalent 

echo $dog->name;
echo $dog->{'name'};

因为你可以这样做,并且

'walk'
和名称都是值,它们也可以来自变量

$attribute = 'name';
$dog->{$attribute};
  1. PHP 有一些神奇的方法来处理未定义的方法/属性,完整列表在那里 https://www.php.net/manual/en/language.oop5.overloading.php

例如,每当您调用名称未定义的静态方法时,都会调用

__callStatic()

像这样

class Html
{
    static public function __callStatic($name, $arguments)
    {
        // Note: value of $name is case sensitive.
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "\n";
    }
    
};

Html::iDontExist();

将输出

Calling object method 'iDontExist' 

  1. 现在如果我们混合 1 和 2 就可以了
Html::{"Hello world"};

会输出

Calling object method 'Hello World' 

结论

  1. 使用
    {}
    语法,您可以拥有不遵循正常约定的方法(即它们可以有空格、表情符号、特殊字符等)
  2. 使用像
    __callStatic
    这样的重载魔法方法,你可以拥有以前不存在的方法

因此,通过组合 1 和 2,您的库允许一个方法本身已经成为一个参数,并且处理该名称的所有逻辑都将在

__callSatic

所以如果某个东西是定义的静态方法,那么这与做

Html::something('div.my-class#my-id', 'This is element content' )
是一样的


1
投票

我认为有一个名为

HTML
的类,它动态调用静态方法来输出一些 HTML。

在下面的示例中,我动态调用一个方法,该方法以简单的方式执行相同的操作。我还传递一个参数来生成附加文本。

<?php

class myClass {

    protected function foo($string) {
        echo 'foo says: ' . $string;
    }
    
    protected function bar($string) {
        echo 'bar says: ' . $string;
    }

    public function hello($method, $string)
    {
        return $this->{$method}($string);
    }

    // static methods
    protected static function baz($string) {
        echo 'baz says: ' . $string;
    }
    
    public static function staticHello($method, $string)
    {
        return self::{$method}($string);
    }

}

$class = new MyClass;

// dynamically call the `foo` method and pass a string
$class->hello('foo', 'this is my foo string');

// outputs
// foo says: this is my foo string.

$class->hello('bar', 'this is my bar string');

// outputs
// bar says: this is my bar string.

// static
$class::staticHello('baz', 'this is my baz string');

// outputs
// baz says: this is my baz string

0
投票

以下代码没有回答问题,但显示了一个工作示例:

class weird_php_magic
{
    public static function __callStatic(
        string $method,
        array $args
    ): string|Stringable|null {
        return static::convert($method, ...$args);
    }
    
    public static function convert(
        string $name,
        mixed $content,
        ?array $options = [],
        ?callable $setup = null
    ): string|Stringable|null {
        // parse $name in some way to determine the function you want to call
        
        // $contents contains the arguments that can be sent to that function
        
        // just dump the contents of $name and $content to see if it worked or not
        var_dump($name);
        var_dump($content);
        
        return null;
    }
}

weird_php_magic::{'this does not exist'}('nor this');

输出

string(19) "this does not exist"
string(8) "nor this"

我用 PHP 8.2 测试了这段代码。一旦

convert()
函数有了名称和文本,就可以相当简单地解析详细信息并(例如)将 HTML 元素添加到 DOM 或操作现有元素。

© www.soinside.com 2019 - 2024. All rights reserved.