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

I wanted to add functions to class, those functions are in separate file(s), those functions contain ($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);

my goal is to add regular functions (not anonymous functions) to the class or to assign those function(s) to a var which can be passed to the class!

Can this be achieved ?

You must have to understand the oops concepts here.

$this refers to your current class / object. So all functions inside a class will be able to access $this ( Current Object ).

But the function declared out side of class can not use $this of that object. (Are you clear up to here.)

But anyways nothing is impossible.

You can achieve your goal in at-least 2 ways.

2) You can use trait to implement multiple inheritance.

it will be like this

trait commonFunctions
{

    function add($a, $b)
    {
        $this->result = $a + $b;

        return $this;
    }
}

class myClass
{

    use commonFunctions;

    public function myClassFunction()
    {
        // 
    }
}

2 ) Or you can follow below code. Source 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(), "
";
$cl = $cl->bindTo($ob2);
echo $cl(), "
";

Here __call will be called when undeclared method is being called. So you can dynamically append methods to class by this way.

Of course you can polyfill your object in javascript like way. But keep in mind you need to use Reflection to bind this to closure.

<?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);

No, you can't add a function to a class like this. You can extend your class with other class having this function add(). This way inherited class will have parent's function add().

It is possible, but their are limits. When calling undefined methods on an object, PHP checks if there is a magic method named __call:

public mixed __call ( string $name , array $arguments )

This function then receives the function name, and the list of arguments. For your construction you could use

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);
}

There is just one problem, namely you cannot use $this within your anonymous functions. In python this problem got solved by passing the instance as the first argument (which is usually called self). We can build something similar by adding the instance to the argument list:

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);
}

Now you could do something like

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);

If you have already some function which does not have $instance as a first argument, you could wrap it

function my_cool_existing_function($bla) {
   echo $bla.$bla;
}
$class->add_function('super_bork', function($instance, $bla) {
   return my_cool_existing_function($bla);
});