2013-02-14 1 views
3

Я хотел бы иметь массив/объект-подобную коллекцию, в которой элементы являются объектами определенного класса (или производными от него). В Java я хотел бы сделать что-то вроде следующего:Коллекция объектов определенного класса в PHP

private List<FooClass> FooClassBag = new ArrayList<FooClass>(); 

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

Единственный способ сделать это, я могу думать сейчас, чтобы создать класс, реализующий Countable, IteratorAggregate, ArrayAccess ... и принуждать способ добавить элементы только одного класса, но это лучший способ сделать это?

+0

Не беспокойтесь об этом. PHP не обеспечивает очень простой способ сделать это, но вы можете реализовать свой собственный класс списка, который принимает только классы определенного типа. –

+0

Вы хотите сделать общее программирование в php? Забудьте об этом ... – mpm

+2

Расширить SPLObjectStorage и реализовать собственный метод attach(), который проверяет объект? –

ответ

5

Вот возможная реализация, но я бы никогда не использовал такую ​​структуру.

<?php 
class TypedList implements \ArrayAccess, \IteratorAggregate { 
    private $type; 

    private $container = array(); 

    public function __construct($type) { 
     $this->type = $type; 
    } 

    public function offsetExists($offset) { 
     return isset($this->container[$offset]); 
    } 

    public function offsetUnset($offset) { 
     unset($this->container[$offset]); 
    } 

    public function offsetGet($offset) { 
     return $this->container[$offset]; 
    } 

    public function offsetSet($offset, $value) { 
     if (!is_a($value, $this->type)) { 
      throw new \UnexpectedValueException(); 
     } 
     if (is_null($offset)) { 
      $this->container[] = $value; 
     } else { 
      $this->container[$offset] = $value; 
     } 
    } 

    public function getIterator() { 
     return new \ArrayIterator($this->container); 
    } 
} 

class MyClass { 
    private $value; 

    public function __construct($value) { 
     $this->value = $value; 
    } 

    public function __toString() { 
     return $this->value; 
    } 
} 
class MySubClass extends MyClass {} 

$class_list = new TypedList('MyClass'); 
$class_list[] = new MyClass('foo'); 
$class_list[] = new MySubClass('bar'); 
try { 
    $class_list[] = 'baz'; 
} catch (\UnexpectedValueException $e) { 

} 
foreach ($class_list as $value) { 
    echo $value . PHP_EOL; 
} 
+0

Несмотря на то, что предлагаемая структура работает хорошо, почему бы вам не использовать ее? –

+4

@ DiegoAgulló Нет смысла пытаться создавать статически типизированные структуры данных на динамически типизированном языке. И также нет смысла делать PHP понятным. –

+0

Хахаха, хороший момент! Спасибо, что объяснили это. –

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