PHP (as it is in C++)
是否可以在class method
class definition?
OUTSIDE
答案 0 :(得分:9)
不,从PHP 5.2开始。但是,您可以使用__call
魔术方法将调用转发给任意函数或方法。
class A {
public function __call($method, $args) {
if ($method == 'foo') {
return call_user_func_array('bar', $args);
}
}
}
function bar($x) {
echo $x;
}
$a = new A();
$a->foo('12345'); // will result in calling bar('12345')
在PHP 5.4中,支持 traits 。 Trait是一种方法的实现,无法将其实例化为独立对象。相反,trait可用于扩展具有包含实现的类。详细了解Traits here。
答案 1 :(得分:5)
是的,可以在定义PHP类后添加方法。您想使用classkit,这是一个“实验性”扩展程序。看来默认情况下没有启用此扩展,因此它取决于您是否可以编译自定义PHP二进制文件或加载PHP DLL(如果在Windows上)(例如Dreamhost允许自定义PHP二进制文件,并且它们很容易设置)。
<?php
class A { }
classkit_method_add('A', 'bar', '$message', 'echo $message;',
CLASSKIT_ACC_PUBLIC);
$a = new A();
$a->bar('Hello world!');
PHP手册中的示例:
<?php
class Example {
function foo() {
echo "foo!\n";
}
}
// create an Example object
$e = new Example();
// Add a new public method
classkit_method_add(
'Example',
'add',
'$num1, $num2',
'return $num1 + $num2;',
CLASSKIT_ACC_PUBLIC
);
// add 12 + 4
echo $e->add(12, 4);
答案 2 :(得分:3)
您可以覆盖__call or __callStatic以在运行时找到缺少的方法,但您必须组建自己的系统来查找和调用代码。例如,您可以加载“Delegate”类来处理方法调用。
这是一个例子 - 如果你试图调用$ foo-&gt; bar(),该类将尝试创建一个FooDelegate_bar类,并使用相同的参数调用它上面的bar()。如果您已设置类自动加载,则代理可以在单独的文件中生存,直到需要...
class Foo {
public function __call($method, $args) {
$delegate="FooDelegate_".$method;
if (class_exists($delegate))
{
$handler=new $delegate($this);
return call_user_func_array(array(&$handler, $method), $args);
}
}
}
答案 3 :(得分:1)
没有。
如果有帮助,您可以扩展以前声明的类。
答案 4 :(得分:1)
由于PHP 5.3支持闭包,您可以动态地将实例方法定义为包含闭包的变量:
$class->foo = function (&$self, $n) {
print "Current \$var: " . $self->var . "\n";
$self->var += $n;
print "New \$var: " .$self->var . "\n";
};
将$self
(您不能使用$this
外部对象上下文)作为参考(&
),您可以修改实例。
但是,当您尝试正常调用该函数时会出现问题:
$class->foo(2);
你得到一个致命的错误。由于语法原因,PHP认为foo
是$class
的方法。此外,您必须将实例作为第一个参数传递。
幸运的是,有一个特殊的函数可以通过名为call_user_func
的名称来调用函数:
call_user_func($class->foo, &$class, 2);
# => Current $var: 0
# => New $var: 2
请记住将&
放在实例变量之前。
如果你使用__call
魔术方法,那就更容易了:
class MyClass {
public function __call ($method, $arguments) {
if (isset($this->$method)) {
call_user_func_array($this->$method, array_merge(array(&$this), $arguments));
}
}
}
现在您可以致电$class->foo(2)
了。 magic __call
方法捕获对未知方法的调用,并调用$class->foo
变量中的闭包,其名称与被调用方法的名称相同。
当然,如果$class->var
是私有的,那么存储在$class->foo
变量中的闭包将无法访问它。
答案 5 :(得分:0)
不,不可能。如果在类构造之外定义函数/方法,它将成为全局函数。
答案 6 :(得分:0)
C ++也不能这样做。您是否将声明与de finition混合?
答案 7 :(得分:0)
不,正如大家所说,这不是严格可能的。
但是,您可以something like this在PHP中模拟mixin,或者在运行时向类添加方法,这与您将要获得的一样接近。基本上,它只是使用设计模式来实现相同的功能。 Zope 3做的类似于在Python中模拟mixins,另一种语言不直接支持它们。