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 に答える