【问题标题】:Access class constant and static method from string从字符串访问类常量和静态方法
【发布时间】:2012-03-11 22:34:34
【问题描述】:

我有一个包含类名的字符串,我希望获取一个常量并从该类调用一个(静态)方法。

<?php
$myclass = 'b'; // My class I wish to use

$x = new x($myclass); // Create an instance of x
$response = $x->runMethod(); // Call "runMethod" which calls my desired method

// This is my class I use to access the other classes
class x {
    private $myclass = NULL;

    public function __construct ( $myclass ) {
        if(is_string($myclass)) {
            // Assuming the input has a valid class name
            $this->myclass = $myclass;
        }
    }

    public function runMethod() {
        // Get the selected constant here
        print $this->myclass::CONSTANT;

        // Call the selected method here
        return $this->myclass::method('input string');
    }
}


// These are my class(es) I want to access
abstract class a {
    const CONSTANT = 'this is my constant';

    public static function method ( $str ) {
        return $str;
    }
}

class b extends a {
    const CONSTANT = 'this is my new constant';

    public static function method ( $str ) {
        return 'this is my method, and this is my string: '. $str;
    }
}
?>

正如我所料(或多或少),使用$variable::CONSTANT$variable::method(); 不起作用。

在问我尝试过什么之前;我已经尝试了很多我基本上都忘记了的东西。

最好的方法是什么?提前致谢。

【问题讨论】:

    标签: php string class methods static


    【解决方案1】:

    要访问常量,请使用constant()

    constant( $this->myClass.'::CONSTANT' );
    

    注意:如果您正在使用命名空间,即使您从同一个命名空间调用constant(),也需要专门将命名空间添加到字符串中!

    对于通话,您必须使用call_user_func()

    call_user_func( array( $this->myclass, 'method' ) );
    

    但是:这一切都不是很有效,因此您可能需要重新审视一下您的对象层次结构设计。使用继承等可能有更好的方法来实现所需的结果。

    【讨论】:

    • self::CONSTANT 呢?
    【解决方案2】:

    你可以通过设置一个临时变量来实现。不是最优雅的方式,但它确实有效。

    public function runMethod() {
        // Temporary variable
        $myclass = $this->myclass;
        // Get the selected constant here
        print $myclass::CONSTANT;
    
        // Call the selected method here
        return $myclass::method('input string');
    }
    

    我想这与:: 的模糊性有关,至少错误消息暗示的是什么(PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM

    【讨论】:

    • 我只是想写出完全相同的答案。我认为这将是最“理智”的版本。虽然用继承完全重写会好得多。
    【解决方案3】:

    使用call_user_func调用静态方法:

    call_user_func(array($className, $methodName), $parameter);
    

    【讨论】:

      【解决方案4】:

      定义为抽象的类不能被实例化,任何包含至少一个抽象方法的类也必须是抽象的。定义为抽象的方法只是声明方法的签名——它们不能定义实现。

      从抽象类继承时,所有在父类声明中标记为抽象的方法都必须由子类定义;此外,这些方法必须定义为具有相同(或较少限制)的可见性。例如,如果抽象方法定义为受保护,则函数实现必须定义为受保护或公共,但不能定义为私有。此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。这也适用于 PHP 5.4 以后的构造函数。在 5.4 之前的构造函数签名可能不同。 参考http://php.net/manual/en/language.oop5.abstract.php

      【讨论】:

        【解决方案5】:

        在 php 7 中你可以使用这个代码

        echo 'my class name'::$b;
        

        #Uncomment this lines if you're the input($className and $constName) is safe.
        $reg = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/';
        if(preg_match($reg,$className) !== 1 || preg_match($reg,$constName) !== 1)
            throw new \Exception('Oh, is it an attack?');
        $value = eval("return $className::$constName;");
        

        【讨论】:

        • 虽然这个答案可能会解决 OP 的问题,但建议您清楚地解释这是如何实现解决方案的。简单地发布仅代码的答案可能对 OP 和未来的用户没有帮助。请详细说明。
        • 解决方案很明确!因为问题的标题是从字符串访问类常量和静态方法
        • 这对我不起作用,我使用的是 7.4.21。编辑:我使用return 而不是echo
        • @FabianoLothor 请参阅sandbox.onlinephpfunctions.com/code/…
        • @ThinkBig 谢谢,请看我的意思:sandbox.onlinephpfunctions.com/code/…
        【解决方案6】:

        这可能与主题无关,但是在搜索我自己的问题时,我发现接受的答案为我指明了正确的方向,所以我想分享我的问题和解决方案,以防其他人可能陷入困境类似的时尚。

        我正在使用 PDO 类,并且正在从一个 ini 配置文件构建一些错误选项。我需要它们在一个关联数组中,格式为:PDO::OPTION_KEY =&gt; PDO::OPTION_VALUE,但它当然失败了,因为我试图仅使用 PDO::$key =&gt; PDO::$value 构建数组。

        解决方案(灵感来自已接受的答案):

        $config['options'] += [constant('PDO::'.$key) => constant('PDO::'.$option)];
        

        如果您将类名和Scope Resolution Operator 连接为带有变量的字符串并通过常量函数(更多here)获取结果字符串的常量值,则一切正常。 谢谢你,我希望这对其他人有帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-22
          • 2012-06-29
          • 2012-02-04
          • 2015-02-18
          • 1970-01-01
          • 2011-07-31
          • 2015-03-19
          相关资源
          最近更新 更多