我想在类中添加函数,这些函数在单独的文件中,这些函数包含($ this)。
class myClass {
private $myFunctions=array(); // will contain two keys (title, function_object)
private $var;
public function __construct() {
$this->var = 'Hello world';
}
public function add_function($title, $func) {
$this->myFunctions[$title] = $func;
}
}
function add($x, $y) {
echo $this->var;
return $x + $y;
}
$class = new myClass;
$class->add_function('add', 'add()');
echo $class->add(1,2);
我的目标是将常规函数(不是匿名函数)添加到类中,或者将这些函数分配给可以传递给类的var!
这可以实现吗?
答案 0 :(得分:3)
你必须要了解oops概念。
$ this指的是您当前的类/对象。因此,类中的所有函数都可以访问$ this(当前对象)。
但是声明在类的一侧的函数不能使用该对象的$ this。 (你清楚到这里。)
但无论如何没有什么是不可能的。
您至少可以通过两种方式实现目标。
2)您可以使用trait实现多重继承。
就像这样
trait commonFunctions
{
function add($a, $b)
{
$this->result = $a + $b;
return $this;
}
}
class myClass
{
use commonFunctions;
public function myClassFunction()
{
//
}
}
2)或者您可以按照以下代码进行操作。来源php.net
<?php
class A {
function __construct($val) {
$this->val = $val;
}
function getClosure() {
//returns closure bound to this object and scope
return function() { return $this->val; };
}
}
$ob1 = new A(1);
$ob2 = new A(2);
$cl = $ob1->getClosure();
echo $cl(), "\n";
$cl = $cl->bindTo($ob2);
echo $cl(), "\n";
在调用未声明的方法时,将调用__call。因此,您可以通过这种方式动态地将方法附加到类。
当然你可以用javascript方式填充你的对象。但请记住,您需要使用Reflection将其绑定到闭包。
<?php
class A {
private $dynamic_functions=[];
public function __call($method, $args=[])
{
if(isset($this->dynamic_functions[$method]) && $this->dynamic_functions[$method] instanceof \Closure)
{
$cl = $this->dynamic_functions[$method]->bindTo($this);
return call_user_func_array($cl, $args);
}
else
{
die("Wrong method, Not yet polyfilled.");
}
}
public function __set($property, $value)
{
$this->dynamic_functions[$property] = $value;
}
}
$a = new A;
$a->sum = function($a,$b){
// var_dump($this); will give you current instance of A
return $a+$b;
};
echo $a->sum(5, 3);
答案 1 :(得分:2)
这是可能的,但它们是有限的。在对象上调用未定义的方法时,PHP会检查是否存在名为__call
的{{3}}:
public mixed __call ( string $name , array $arguments )
此函数接收函数名称和参数列表。对于您的建筑,您可以使用
public function __call($name, $args) {
// invokes the function with all arguments:
// e.g: function_name($arg[0], $arg[1], ...)
return call_user_func_array($this->myFunctions[$name], $args);
}
只有一个问题,即你不能在你的匿名函数中使用$ this。在python中,通过将实例作为第一个参数(通常称为self
)传递来解决此问题。我们可以通过将实例添加到参数列表来构建类似的东西:
public function __call($name, $args) {
// we add the instance at the beginning of the argument list
array_unshift($args, $this);
return call_user_func_array($this->myFunctions[$name], $args);
}
现在你可以做点什么了
function bork($instance, $a, $b) {
return $a*$b;
}
$class = new myClass;
$class->add_function('derp', 'bork');
$class->add_function('add', function($instance, $x, $y) {
echo $instance->var;
return $x + $y;
});
echo $class->derp(1,2);
echo $class->add(35,34534);
如果你已经有一些没有$instance
作为第一个参数的函数,你可以把它包起来
function my_cool_existing_function($bla) {
echo $bla.$bla;
}
$class->add_function('super_bork', function($instance, $bla) {
return my_cool_existing_function($bla);
});
答案 2 :(得分:0)
不,你不能在这样的类中添加一个函数。您可以使用具有此函数add()的其他类扩展您的类。这种方式继承的类将具有父函数add()。