затраты на лямбду равны затратам на работу с именем класса из строки

Вурдалак

Продвинутый новичок
grigori, так неясно о чём ты ведёшь речь: ну, бери Pimple, добавь этот сахар, что ещё?
 
  • Like
Реакции: AmdY

grigori

( ͡° ͜ʖ ͡°)
Команда форума
grigori, так неясно о чём ты ведёшь речь: ну, бери Pimple, добавь этот сахар, что ещё?
объясни пожалуйста
либо дописать зависимости контроллера в конфиге и инжектить по-нормальному.

Ну это если хочется автокомплита.
что такое по-нормальному?
 

hell0w0rd

Продвинутый новичок
Вурдалак
ну не совсем, аннотации - это то, чего в php нет, но костыльно существует.
Зависимость так и так будет, ее не может не быть. Инжектить прямо в метод - ок для простых проектов, где контроллер не дергает несколько своих методов, в которые не хочется передавать те же зависимости, а вместо этого дергать $this->foo.
Есть еще кстати вариант, я так делал с silex. У него есть трейты, которые решают большинство задач, а так как там приложение - большой контейнер, все дергается через $this['foo'];
Я в классе контроллера сделал ArrayAccess на $this->app завязанный и таким образом при добавлении трейтов дергались зависимости из контейнера.

class FooController
{
use TwigTrait;
use MonologTrait;
}
Таким образом добавлялись функции render, log и тд)
 

Вурдалак

Продвинутый новичок
что такое по-нормальному?
По-нормальному — это явно. Все эти
PHP:
/** @[USER=4683]var[/USER] $foo Bar */
$foo = $this->container->get('bar');
и @property — это же костыли. Я стараюсь их избегать. Если приходится их юзать — значит что-то не то.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Зависимость так и так будет, ее не может не быть.
Может. Через конструктор или метод. Ни о каких контейнерах класс не знает.

Инжектить прямо в метод - ок для простых проектов, где контроллер не дергает несколько своих методов, в которые не хочется передавать те же зависимости, а вместо этого дергать $this->foo.
Под методом подразумевается setter, а не action. Работа с action — это уже не забота DIC.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вурдалак явно - это инъекция в конструктор или в сеттер.
Но тут другой вопрос: я не хочу всегда инъектить объект, если он нужен только в 1м action-е из множества в моем контроллере.
Делать под него отдельный контроллер? Неинтересно. Lazy load здесь справляется лучше. Как ты решаешь это?
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
grigori, как вариант можно юзать parent service, сделать два разных инстанса: для обычных action'ов со стандартными зависимостями и для исключительного случая сделать наследника с инъекцией недостающего сервиса. В роутере, соответственно, указать нужный.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а, вон ты о чем
mail_manager:
abstract: true
calls:
- [setMailer, ["@my_mailer"]]
newsletter_manager:
class: "%newsletter_manager.class%"
parent: mail_manager
вот этот новый компилируемый язык поверх PHP мне и не нравится :)

"нормальным" я это решение не считаю: проблема зависимости классов решается через написание этой зависимости на другом языке программирования
да, он компактнее, но гетерогенность значительно повышает цену владения и порог вхождения
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Да какая разница какой формат, можно и так:
PHP:
<?php

$container['foo'] = function (Container $c) {
	return new Foo(...);	
};

$container['controller.foo'] = function (Container $c) {
	return new Controller($c['a'], $c['b']);	
};

$container['controller.bar'] = function (Container $c) {
	return $c['controller.foo']->setFoo($c['foo']);	
};
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вурдалак да, надо такое в yii сделать :)
у них (авторов yii) проект маленький, зависимости не нужны, и, соответственно, нельзя прописать зависимость для контроллера, а ведь такая явная инъекция через сеттер - очень даже хорошая штука
 

WMix

герр M:)ller
Партнер клуба
PHP:
/**
вспомнился мне Минималистичный dependency injection container 
ну да че и говорить, fixxxer'у и grigori'ю посвещается 
*/
include 'phpclub.ru/talk/threads/74634/';

// разширим его на конфигурацию
class MyInj extends Injector{
    public function setConfig($cfg){
        foreach( $cfg as $key => $val ){
            $this->$key = function() use ($val,$cfg) {
                $params = array();
                if(isset($val['params'])){
                    foreach( $val['params'] as $parameter){
                        if(isset($cfg[$parameter])){
                            $params[] = $this->$parameter;
                        }
                        else{
                            $params[] = $parameter;
                        }
                    }
                }
                $reflect  = new ReflectionClass( $val['class'] );
                return $reflect->newInstanceArgs( $params );
            };
        }
    }
}
PHP:
class Dependency {}
class Service {
    public function __construct(Dependency $dependency, $flag) {
        $this->dependency = $dependency;
        $this->flag = $flag;
    }
}
Код:
;di.conf.ini

[service]
class = Service
params[] = dependency
params[] = 1

[dependency]
class = Dependency
PHP:
$inj = new MyInj;

$inj->setConfig( parse_ini_file('di.conf.ini',true));
print_r( $inj->service );
ну теперь масив di.conf.ini хоть ямлом хоть джейсоном писать можно (если не ошибся конечно :))
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
А зачем инжектить в класс контроллера, а не метод, как это делается в symfony/silex? Только если я не ошибаюсь в symfony можно еще этот подход и закешировать.
То есть пишите
PHP:
public function blaBlaAction(Request $request, Connection $connect, $id, $name)
{
}
И controllerResolver сам разруливать что и куда инжектить. В принципе это дело можно даже не кешировать, рефлексия медленная, но не для вызова одной функции
А ты не в курсе можно ли это сделать из коробки без создания кастомного ParamConverter'а? Потому что инжектить в сам action в случае, если сервис нужен только ему, предпочтительней, да.
 

Sam Dark

Новичок
По идее, можно реализовать в том же Yii 1.1 перекрыв YiiBase::createComponent.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Ага, еще я думаю про регистрацию зависимостей с автоматической инъекцией, как бы это сделать.
Репозиторий yii::app() - это, конечно, хорошо и удобно, пока количество компонентов не подошло к 20 и main.php не стал простыней
 
Последнее редактирование:
Сверху