Добавить динамический метод к классу

StalkerClasses

Новичок
Нашел в 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);
?>

Можно ли как-то сделать тоже самое только без "classkit_method_add"
 

Valick

Новичок
StalkerClasses, тебе не просо так задают наводящие вопросы. Правильно заданный вопрос - это уже 50% ответа. А у тебя иногда вопросы вообще не имеют отношения ни к программированию ни к РНР, хотя тебе кажется, что "всё норм". Для того что бы было красиво есть делегирование, стратегия, композиция, фасад и еще куча шаблонов проектирования. Для того, что бы знать какой шаблон применять в конкретной ситуации надо читать книги, ну или хотя бы отвечать на наводящие вопросы.
 

Yoskaldyr

"Спамер"
Партнер клуба
Подкину на вентилятор:
Смотри в сторону кложур (а именно Closure::bindTo плюс присваивание кложуры какой либо паременной класса). Будет почти то что ты хочешь.
 

Adelf

Administrator
Команда форума
да пиши на Котлине или СиШарп. Там такие вещи на раз-два.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
зачем котлин?
JavaScript:
myclass.prototype.foo: function () {};
и пусть первым бросит камень тот, кто так не писал )))
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а мне, кажется, наоборот - чувак учится, не получается - продолжает, ему пишут неприятное - он все равно продолжает, разбирается, не то что звезды ютьюба
 
Последнее редактирование:

StalkerClasses

Новичок
Не совсем пойму как мне это поможет.

Я бы хотел в 1 класс добавить 1 метод. Даже скорее переписать 1 метод "initArguments()".
Есть вариант создать класс и наследоваться от класса из коробки.
Есть вариант подключать трейт.

Но я бы хотел обойтись без трейта и без моего класса...
PHP:
<?php

class HelloWorldViewHelper extends \CMS\AbstractViewHelper
{
    // Вот эту функцию я хочу перевести на переменную $CMS
    public function initArguments()
    {
        $this->addArg('imgWidth','int','req',640);
        $this->addArg('imgHeight','int','req',320);
    }
 
    // На вот эту...
    $CMS = [
        'thisIs' => 'ViewHelper',
        'name' => 'Helper name',
        'description' => 'Helper description',
        'args' => [
            'imgWidth' => [
                'int',
                'req',
                640
            ]
        ]
    ]
 
    public function render()
    {
        return 'Hello world:' . $this->imgWidth;
    }
}
 
?>
Для виджетов я сделал такой подход. Спасибо: WMix за spl_autoload_register...
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@AmdY я не вижу в фразе "звезды youtube" перехода на личности, это сравнение по теме разговора,
упоминать Минск больше не буду, а ссылка на фразу "к звезде надо приходить подготовленным" здесь по делу - лучше вот такие вопросы
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
@AmdY я не вижу в фразе "звезды youtube" перехода на личности, это сравнение по теме разговора,
упоминать Минск больше не буду, а ссылка на фразу "к звезде надо приходить подготовленным" здесь по делу - лучше вот такие вопросы
Просто Антон вёл себя максимально корректно и уважительно, исправлял недочёты и благодарил тебя. Не понимаю чего ты на него взъелся? Это Серафим бросился в схватку.

Автору мы уже много раз объясняли про композицию и делегирование. Я ссылку давал на примеры. А он всё одно своё лепит через трейты, кодогенерацию, теперь вот класскит. С каждым вопросом все хуже и хуже, как верно заметил Фанат.
 

WMix

герр M:)ller
Партнер клуба
Для виджетов я сделал такой подход. Спасибо за spl_autoload_register...
обычно используют composer и по PSR пишут

Я бы хотел в 1 класс добавить 1 метод. Даже скорее переписать 1 метод "initArguments()".
PHP:
class HelloWorldViewHelper {
  
    private $imgWidth;
  
    public function render(){
        return 'Hello world:' . $this->imgWidth;
    }
}

$hw = new HelloWorldViewHelper;

// Вот эту функцию я хочу перевести
$initWidth = function(int $imgWidth){
    $this->imgWidth = $imgWidth;
};

$initWidth->call($hw, 640);
echo $hw->render();
можно слегка закрутить

PHP:
class HelloWorldViewHelper {
   
    private $imgWidth;
   
    public function render(){
        return 'Hello world:' . $this->imgWidth;
    }
}


function method_add(callable $m, $obj, $name){
    return new class($m, $obj, $name){
        private $obj;
        private $m;
        private $name;
       
        public function __construct(callable $m, $obj, $name){
            $this->obj = $obj;
            $this->m = $m;
            $this->name=$name;
        }
       
        public function __call($name, $args){
            if($name === $this->name){
                return $this->m->call($this->obj, ...$args);
            }
            return $this->obj->$name(...$args);
        }
    };
}

$hw = new HelloWorldViewHelper;

$hwProxy = method_add(function(int $imgWidth){
    $this->imgWidth = $imgWidth;
}, $hw, 'initWidth');

$hwProxy->initWidth(640);
$hwProxy->render();
или проще так
PHP:
class HelloWorldViewHelper {
    
    private $imgWidth;
    
    public function render(){
        return 'Hello world:' . $this->imgWidth;
    }
}

class Proxy{

    private $obj;
    private $methods;
    
    public function __construct($obj){
        $this->obj = $obj;
    }
    
    public function addMethod($name, callable $method){
        $this->methods[$name] = $method;
    }
    
    
    public function __call($name, $args){       
        if(array_key_exists($name, $this->methods)){
            return $this->methods[$name]->call($this->obj, ...$args);
        }
        return $this->obj->$name(...$args);
    }
}

$proxy = new Proxy(new HelloWorldViewHelper);

$proxy->addMethod('initWidth', function(int $imgWidth){
    $this->imgWidth = $imgWidth;
});

$proxy->initWidth(640);
echo $proxy->render();
боюсь только ты классами думать умеешь, и ты просто хочешь но не можешь влезть посредине инициализации в чужой обработке
 
Последнее редактирование:
Сверху