0

我在按 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>";
4

2 回答 2

1

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

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

于 2012-09-29T21:17:34.840 回答
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);
}

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

于 2012-09-30T11:33:12.043 回答