在课堂上添加常规非反义函数

时间:2017-05-15 18:34:16

标签: php

我想在类中添加函数,这些函数在单独的文件中,这些函数包含($ 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!

这可以实现吗?

3 个答案:

答案 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()。