声明和调用名称中带有句点的PHP对象函数
我正在使用一个返回不同值的API,我想动态地告诉我的类运行一个同名函数(这样我就不需要一个巨大的声明和调用名称中带有句点的PHP对象函数,php,oop,Php,Oop,我正在使用一个返回不同值的API,我想动态地告诉我的类运行一个同名函数(这样我就不需要一个巨大的开关或if/else混乱) 如何声明对象方法song.pause 如何使用对象方法song.pause 这可能是一个错误,那么有更好的方法吗?我想到的另一种方法是总是调用str_replace('.',''.',$type)并设置不带句点的函数。想法 例如: <?php class MyClass { ... ... $type = "song.pause"; // Th
开关
或if/else
混乱)
song.pause
song.pause
str_replace('.',''.',$type)
并设置不带句点的函数。想法<?php
class MyClass {
...
...
$type = "song.pause"; // This value is returned from another API I can't control
if (property_exists('MyClass', $type)) {
$success = $this->{$type}(); // ???
} else {
header("HTTP/1.1 400 Invalid type: $type);
exit;
}
public function 'song.pause'() { // obviously incorrect :)
???
}
不幸的是,您通常要求的是不受支持。从:
函数名遵循与PHP中其他标签相同的规则。有效的
函数名以字母或下划线开头,后跟任意
字母、数字或下划线的数量。作为正则表达式,
可以这样表达:[a-zA-Z\ux7F-\xff][a-zA-Z0-9\ux7F-\xff]*
这也适用于类方法
在本次演练中,您可以按照自己建议的方式进行:
$type = 'song.pause';
$type = str_replace('.', '_', $type);
$this->{$type}(); // will call song_pause()
或使用:
显示:
song.pause // < the method
Array // < arguments
(
[0] => 1
[1] => 2
[2] => 3
)
song.pause/<
数组/<参数
(
[0] => 1
[1] => 2
[2] => 3
)
然而,我完全同意“长”且真正透明的方式。@HAL9000是正确的:您想要的东西不受支持。一个潜在的解决办法是:
定义处理程序:
$typeHandlers = array();
$typeHandlers['song.pause'] = function () {
echo 'Pause!'; // or whatever...
};
调用相应的处理程序:
$typeHandlers[$type]();
返回<代码>歌曲。暂停<代码>,概念上<代码>歌曲<代码>应该是类名,<代码>暂停<代码>应该是方法,考虑这种可能性:
class MyClass {
protected $classes = array();
function processResponse($response) {
// $response example is "song.pause"
list($class, $method) = explode('.', $response);
if(!class_exists($class)) {
// Class doesn't exist
die("Class name {$class} doesn't exist! Exiting...");
}
// Instantiate class
$this->classes[$class] = new $class();
if(!method_exists($this->classes[$class], $method)) {
// Method doesn't exist within specified class
die("Method name {$method} doesn't exist within {$class}. Exiting...");
}
// Call method
$result = $this->classes[$class]->{$method}();
return $result;
}
}
您的逻辑实现如下所示:
class song {
public function pause() {
return 'foobar';
}
}
好吧,我也这么认为。谢谢看起来我必须要有创意。+1但是在$this->classes
中保留对象的副本有什么意义(特别是因为它被覆盖了)?纯粹是为了不需要为每个子类名定义属性-而是将它们保留在数组中。如果要为每个可能的子级定义它,那么它和$this->{$class}
之间没有区别。
class song {
public function pause() {
return 'foobar';
}
}