Я новичок в DI, использую прыщ.Использование: php 5.3.5 (wamp), а также пространства имен.Я рефакторинг кода, используя его, но возникли проблемы:
У меня есть мой контейнер, который выходит из Pimple, давайте назовем его PContainer.php:
class ReuseableContainer extends Pimple{
private function initOutterClass(){
$this['special_location_class'] = '\SpecialLocation';
$this['special_location'] = function($c){return new $c['special_location_class']($c['location_details'],$c['location']);};
}
private function initGlobalFunctions(){
$this['getGeneralDataFromArray'] = function($c){
// returning a function
return function($arr){
foreach ($arr as $key => $value){
// do something
$new_data = $c['general_data_type'];
$new_data->id = $value['id'];
$new_data->name = $value['name'];
}
}
}
public function __construct(){
$this['location_class'] = '\Location';
$this['location_details_class'] = '\LocationDetails';
$this['general_data_type_class'] = '\GeneralDataType';
// define some objects
$this['location'] = function ($c) {
return new $c['location_class']();
};
$this['location_details'] = function ($c) {
return new $c['location_details_class']();
};
$this['general_data_type'] = function ($c) {
return new $c['general_data_type_class']();
};
$this->initOutterClass();
$this->initGlobalFunctions();
}
}
global $container ;
$container = new Pimple();
// embed the SomeContainer container
$container['embed'] = $container->share(function () { return new ReuseableContainer(); });
Ok,Итак, я получил SpecialHelper.php, который содержит:
final class SpecialLocation{
public $name;
public $location;
public $picture;
public function __construct($location){
$this->location; // dependent on class: Location
}
}
final class SpecialUser{
private $id;
private $location;
public function __construct(\Location $location,$id=''){
$this->id = $id;
$this->location = $location; // $container['embed']['location'];
}
, и мы получили наш GeneralHelper.php, который содержит:
final class Location{
public $lat;
public $lng;
public function __construct($lat='',$lng=''){ $this->lat = $lat; $this->lng = $lng;}
}
final class LocationDetails{
public $id;
public $addresss;
public function __construct($id='',$address=''){$this->id = $id; $this->address = $address;}
}
class GeneralDataType{
public $id;
public $name;
public function getName(){ return $this->name;}
public function getId(){ return $this->id;}
}
, и у нас есть контроллер "Специальный класс", который выглядитчто-то вроде этого:
final class SpecialController{
public function foor($some_array){
$this->doSomething($some_array);
}
private function doSomething($ret_value){
// do something
$arr = array();
foreach($ret_value as $key => $value){
$something = $container['embed']['getGeneralDataFromArray']($value);
$special_location = $container['embed']['special_location'];
$arr[] = special_location;
}
return $arr;
}
}
Наконец, у нас есть наш главный "драйвер", main.php
require('PContainer.php');
....
...
$some_array = array(....);
$special_controller = new SpecialController();
$special_controller->foor($some_array);
Проблемы: 1) Мне пришлось добавить функцию initOutterClass внутри ReuseableContainer, чтобы отделить "Специальные "классы, как я мог бы отделить их лучше?создание нового "специального" 9контейнера или что-то?так как ВСЕ теперь сидит внутри контейнера .. то же самое относится к initGlobalFunctions ()
2) относительно SpecialHelper.php: у меня есть SpecialLocation, одно из его свойств является классом \ Location, я положил егов конструкторе, но если у меня есть 20 свойств объекта, которые являются зависимыми, я должен поместить их все в качестве параметров INPUT для конструктора ??То же самое относится и к классу SpecialUser, у него есть $ location, который, если бы я мог, сделал бы $this->location = $container['embed']['location'];
вместо $this->location = $location;
, что привело бы к зависимости от DI!: /
3) Мне пришлось создать SpecialHelper.php в другом файле, несмотря на желание поместить его в «контроллер специального класса», просто чтобы не было никаких неизвестных (из-за необходимостипорядок операторов)
4) Самое главное: о контроллере "Специальный класс", как мне решить метод doSomething?я должен создать объект "Special Location" внутри цикла, но я получаю, что $ container не распознан (несмотря на то, что он глобален, вероятно, по области видимости), но более того, он действительно зависим!и это частная функция, я не хочу передавать контейнер в КАЖДЫЙ класс, который я буду использовать с этого момента, это не IoC, верно?
Любая помощь оценивается ... я пытаюсьчтобы понять лучшие практики ..
Спасибо