从arraycollection中获取对象

时间:2012-09-29 21:10:56

标签: php symfony doctrine-orm

我有一个问题是通过ID从对象的数组集合中获取对象。

以下是我的代码:

protected $_rootLocation;

public function __construct(Location $rootLocation)
{
    $this->_rootLocation= $rootLocation;

    var_dump($this->_rootLocation);
}

public function getLocationById($id)
{
    $value = null;
    foreach($this->_rootLocationas $root)
      {
            if ($id == $root->getId())
            {
                $value = $root;
                break;
            }
       }

    return $value;
}

然后函数返回“NULL”,所以它不起作用......

修改

我喜欢这样:

    $manager = new LocationManager($rootLocation);

    echo "<pre>";
    var_dump($manager->getLocationById('291'));
    echo "</pre>";

2 个答案:

答案 0 :(得分:1)

您的函数返回null,因为找不到该对象!

这取决于myClasse对象的实现,这必须实现iterator接口,并且getId()方法必须在每次迭代时返回有效的Id。

答案 1 :(得分:0)

想象一下,阵列中的所有对象都没有您正在寻找的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);
}

此集合类仅提供附加对象,而不是删除它们,但您可以根据需要进行扩展。如果要重用现有功能,还可以从现有类(ArrayObjectSplObjectStorage进行扩展。在一个有点相关的问题的另一个答案中给出了一个例子: