开发者

How to add methods dynamically

I'm trying to add methods dynamically from external 开发者_StackOverflow社区files. Right now I have __call method in my class so when i call the method I want, __call includes it for me; the problem is I want to call loaded function by using my class, and I don't want loaded function outside of the class;

Class myClass
{
    function__call($name, $args)
    {
        require_once($name.".php");
    }
}

echoA.php:

function echoA()
{
    echo("A");
}

then i want to use it like:

$myClass = new myClass();
$myClass->echoA();

Any advice will be appreciated.


Is this what you need?

$methodOne = function ()
{
    echo "I am  doing one.".PHP_EOL;
};

$methodTwo = function ()
{
    echo "I am doing two.".PHP_EOL;
};

class Composite
{
    function addMethod($name, $method)
    {
        $this->{$name} = $method;
    }

    public function __call($name, $arguments)
    {
        return call_user_func($this->{$name}, $arguments);
    }
}


$one = new Composite();
$one -> addMethod("method1", $methodOne);
$one -> method1();
$one -> addMethod("method2", $methodTwo);
$one -> method2();


You cannot dynamically add methods to a class at runtime, period.*
PHP simply isn't a very duck-punchable language.

* Without ugly hacks.


You can dynamically add attributes and methods providing it is done through the constructor in the same way you can pass a function as argument of another function.

class Example {
    function __construct($f)
    {
       $this->action=$f;
    }
}

function fun() {
   echo "hello\n";
}

$ex1 = new class('fun');

You can not call directlry $ex1->action(), it must be assigned to a variable and then you can call this variable like a function.


if i read the manual right, the __call get called insted of the function, if the function dosn't exist so you probely need to call it after you created it

Class myClass
{
    function __call($name, $args)
    {
        require_once($name.".php");
        $this->$name($args);
    }
}


You can create an attribute in your class : methods=[]
and use create_function for create lambda function.
Stock it in the methods attribute, at index of the name of method you want.
use :

function __call($method, $arguments)
{
   if(method_exists($this, $method))
      $this->$method($arguments);
   else
      $this->methods[$method]($arguments);
}

to find and call good method.


What you are referring to is called Overloading. Read all about it in the PHP Manual


/**
 * @method Talk hello(string $name)
 * @method Talk goodbye(string $name)
 */
class Talk {
    private $methods = [];
    
    public function __construct(array $methods) {
        $this->methods = $methods;
    }
    
    public function __call(string $method, array $arguments): Talk {
        if ($func = $this->methods[$method] ?? false) {
            $func(...$arguments);
            
            return $this;
        }
        
        throw new \RuntimeException(sprintf('Missing %s method.'));
    }
}

$howdy = new Talk([
    'hello' => function(string $name) {
        echo sprintf('Hello %s!%s', $name, PHP_EOL);
    },
    'goodbye' => function(string $name) {
        echo sprintf('Goodbye %s!%s', $name, PHP_EOL);
    },
]);

$howdy
    ->hello('Jim')
    ->goodbye('Joe');

https://3v4l.org/iIhph


You can do both adding methods and properties dynamically.

Properties:

class XXX
{
    public function __construct($array1)
    {
        foreach ($array1 as $item) {
            $this->$item = "PropValue for property : " . $item;
        }
    }
}

$a1 = array("prop1", "prop2", "prop3", "prop4");
$class1 = new XXX($a1);
echo $class1->prop1 . PHP_EOL;
echo $class1->prop2 . PHP_EOL;
echo $class1->prop3 . PHP_EOL;
echo $class1->prop4 . PHP_EOL;

Methods:

//using anounymous function
$method1 = function () {
    echo "this can be in an include file and read inline." . PHP_EOL;
};

class class1
{
    //build the new method from the constructor, not required to do it here by it is simpler.
    public function __construct($functionName, $body)
    {
        $this->{$functionName} = $body;
    }

    public function __call($functionName, $arguments)
    {
        return call_user_func($this->{$functionName}, $arguments);
    }
}

//pass the new  method name and the refernce to the anounymous function
$myObjectWithNewMethod = new class1("method1", $method1);
$myObjectWithNewMethod->method1();


I've worked up the following code example and a helper method which works with __call which may prove useful. https://github.com/permanenttourist/helpers/tree/master/PHP/php_append_methods

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜