2012-05-16 4 views
0

В основном моя настройка заключается в том, что у меня есть много объектов, которые я хочу создать. Какой тип объекта он будет зависеть от одной переменной, которая является типом. Поэтому изначально мне пришлось бы делать много операторов if, поэтому, чтобы сократить его, я создал массив, но я столкнулся с проблемой создания реального объекта через массив.Инициировать объект через массив

Вот что я имел первоначально:

if($object->type = 'text') 
{ 
    $object_new = new Text(); 
} elseif($object->type = 'image') { 
    $object_new = new Image(); 
} .... 

Но то, что я хотел сделать, это:

$all_objects = array('text'=> new Text(), 'image' => new Image(), ...); 
$object_new = $all_objects($object->type); 

Что бы сократить свой код на много, а также сделать его более эффективным.

+1

Вы пробовали? –

+1

Он должен работать, но вам нужно '$ all_objects [...]' вместо '()' ... – gahooa

ответ

2

Если нет дополнительных зависимостей для этих объектов, вы можете просто сделать

$className = $object->type; 
$instance = new $className; 

Если вам нужна более сложной логика создания, вы можете поместить код создания в Лямбдах и назвать тех пор, например,

$allTypes = array(
    'text' => function($string) { return new Text($string); }, 
    'Image' => function($path) { return new Image($path); } 
); 
$instance = call_user_func_array($allTypes[$object->type], array($argument1)); 

Или вы создаете объект Factory и поставить переключатель/случай в него:

class Factory 
{ 
    public function create($type) 
    { 
     switch ($type) 
     { 
      case 'text': 
       return new Text; 
      case 'image': 
       return Image($this->create('foo')); 
      case 'foo': 
       return new Foo; 
      default: 
       throw new Exception('No clue what to create'); 
     } 
    } 
} 

Также проверка Is there a call_user_func() equivalent to create a new class instance?

+0

Черт, вы можете просто просто '$ instance = new $ object-> type;'. –

+0

Нужно быть осторожным, используя это с * __ autoload * -ing и чувствительными к регистру файловыми системами. (по крайней мере, для первого метода;)) – Yoshi

0

Создание массив $all_objects вызовет больше проблем. Когда вы получаете элемент оттуда, это будет ссылка, поэтому каждый раз, когда вы обращаетесь к элементу, он будет таким же, как и в последний раз, когда вы обращались к нему. (Пример: http://codepad.org/Z4B7glk9)

Вместо попробовать что-то вроде этого (имена классов в PHP чувствительны к регистру):

$object_new = new $object->type(); 

DEMO: http://codepad.org/Hq09jkHz

0

Это может быть то, что вы ищете:

$types = array('image', 'text', 'link', 'somethingelse'); 
foreach ($types as $type) { 
    $$type = new ucfirst($type); 
} 

Это означает:

$image   = new Image; 
$text   = new Text; 
$link   = new Link; 
$somethingelse = new Somethingelse; 

Конечно, вы должны иметь изображение, Текст, Ссылка и Somethingelse классы.

+0

Я думаю, что он просто хочет сделать экземпляр класса с использованием строки в качестве имени. Я не думаю, что ему нужно делать примеры всех классов. –

Смежные вопросы