我有一个包含类名的字符串,我希望获得一个常量并从该类调用一个(静态)方法。
<?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();
都不起作用。
在问我尝试了什么之前;我试过很多东西,基本上都忘了。
做到这一点的最佳方法是什么?提前谢谢。
要访问常量,请使用constant()
:
constant( $this->myClass.'::CONSTANT' );
请注意:如果您使用的是名称空间,则需要专门将您的名称空间添加到字符串中,即使您从同一名称空间调用constant()
也是如此!
对于通话,您必须使用call_user_func()
:
call_user_func( array( $this->myclass, 'method' ) );
但是:这一切都不是很有效,所以您可能需要重新审视对象层次结构设计。可能有一种更好的方法来实现所需的结果,使用继承等。
在php7中,您可以使用以下代码
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;");
您可以通过设置临时变量来实现。不是最优雅的方式,但它很有效。
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
)
使用call_user_func
调用静态方法:
call_user_func(array($className, $methodName), $parameter);
定义为抽象的类不能实例化,并且任何包含至少一个抽象方法的类也必须是抽象的。定义为抽象的方法只需声明方法的签名——它们不能定义实现。
从抽象类继承时,父类声明中标记为抽象的所有方法都必须由子类定义;此外,这些方法必须定义为具有相同(或限制较少)的可见性。例如,如果抽象方法被定义为protected,则函数实现必须被定义为protected或public,而不是private。此外,方法的签名必须匹配,即类型提示和所需参数的数量必须相同。这也适用于PHP 5.4中的构造函数。5.4之前的构造函数签名可能有所不同。提到http://php.net/manual/en/language.oop5.abstract.php
这可能与主题无关,但在搜索我自己的问题时,我发现公认的答案为我指明了正确的方向,所以我想分享我的问题&解决方案,以防其他人可能陷入类似的困境。
我正在使用PDO类,并从ini配置文件中构建一些错误选项。我需要它们在形式为PDO::OPTION_KEY => PDO::OPTION_VALUE
的关联数组中,但它当然失败了,因为我试图只使用PDO::$key => PDO::$value
构建数组。
解决方案(灵感来自公认的答案):
$config['options'] += [constant('PDO::'.$key) => constant('PDO::'.$option)];
如果您将类名和Scope Resolution运算符连接为一个字符串和变量,并通过常量函数获得结果字符串的常数值,那么一切都会起作用(更多信息)。谢谢你,我希望这能帮助其他人!