想象一下,数组中的所有对象都没有您要查找的 ID。你的函数只会返回null
。例如一个空数组。
可以看到,返回null
并不代表函数不起作用。它完美地工作并且做了你指定的事情,只是不存在这样的对象。
然后由您决定如果发生这种情况该怎么做。正如您在问题中没有告诉的那样,除了为您提供一些选择之外,没有什么要补充的:
您可以检查函数是否返回null
,然后将其视为“未找到”的情况。
$result = $collection->getObjectById($id);
if (null === $result) {
# object not found
} else {
# object found
}
如果只应为现有对象调用函数,则可以在函数内抛出异常:
public function getObjectById($id) {
foreach ($this->_rootObject as $root) {
if ($id == $root->getId()) {
return $root;
}
}
throw new InvalidArgumentException(sprintf('Not a valid ID: %d', $id));
}
或者最后:
提供附加功能以首先检查现有 ID:
private function findById($id) {
foreach ($this->_rootObject as $object) {
if ($id == $object->getId()) {
return $object;
}
}
return null;
}
public function hasObjectById($id) {
return null !== $this->findById($id);
}
public function getObjectById($id) {
if (null !== $root = $this->findById($id)) {
return $root;
}
throw new InvalidArgumentException(sprintf('Not a valid ID: %d', $id));
}
此外,您可能有兴趣为自己创建一个名为封装您的需求的类,因此您不需要在“我管理根集合对象”对象中实现它,这不仅仅是间接的。这基本上是你自己的集合类。一个例子:
interface Identifiable {
public function getId();
}
/**
* Example Object Class
*/
class MyObject implements Identifiable {
private $id;
public function __construct($id) {
$this->id = (int) $id;
}
public function getId() {
return $this->id;
}
}
/**
* Example Collection
*/
class IdentifiableCollection implements Countable, IteratorAggregate
{
private $objects;
public function attach(Identifiable $object) {
$id = $object->getId();
$this->objects[$id] = $object;
}
public function count() {
return count($this->objects);
}
public function has($id) {
return isset($this->objects[$id]);
}
public function getById($id) {
if ($this->has($id)) {
return $this->objects[$id];
}
throw new InvalidArgumentException(sprintf("No object is identifiable for %d", $id));
}
public function getIterator() {
return new ArrayIterator($this->objects);
}
}
// create the collection
$collection = new IdentifiableCollection();
// fill the collection with some objects (ID 1 - 20)
foreach(range(1, 20) as $id) {
$collection->attach(new MyObject($id));
}
// test if an id exists and return object
$id = 2;
var_dump($collection->has($id), $collection->getById($id));
// iterate over the collection
foreach ($collection as $object) {
var_dump($object);
}
此集合类仅提供附加对象,而不是删除它们,但您可以根据需要对其进行扩展。如果您想重用现有功能,ArrayObject
也可以从现有类扩展。SplObjectStorage
在一个有点相关的问题的另一个答案中给出了一个例子: