2012-09-03 15 views
8

私はPropel 1.6を使用していますが、propelオブジェクトコレクションからオブジェクト(その "id"属性値が与えられている)を取得する方法がわかりません。私はPropelの文書(PropelCollection methodsは当てはまらないと思われますか?)でまっすぐな答えを見つけることができませんでした。たとえば:propelオブジェクトコレクションから "id"でオブジェクトを取得する方法は?

<table name="person"> 
    <column name="id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/> 
    <column name="name" type="VARCHAR" size="100" required="true"/> 
</table> 

私は「人」オブジェクトのコレクションを取得するには、次のクエリを実行します:

$persons = PersonQuery::create()->find(); 

その後、私は は、私は、次のスキーマを使用した「人物」テーブルを考えてみましょう与えられた "id"(例えば、 "id = 3"の "Person")を持つ "Person"オブジェクト、をデータベースで新しいクエリを検索せずに探したいとします。どうしたらいいですか?

つまり
$persons->get(...?)? 

、私はしたくない:

$personX = PersonQuery::create()->findOneById(3); 

コンテキスト:

私はパフォーマンスを向上させるために、データベースクエリを作る防ぐしたいと思います。非常に効率的ではありませんが、あなたはそれを見つけるためにコレクションを行くことができる

foreach ($books as $book) { 
    $book['author_name'] = PersonQuery::create()->findOneById($book['author_id'])->getName(); 
} 

答えて

4

まあ、:文は次のようなそうでない場合は、多数のデータベース接続につながるforeach文、内部に挿入されます。

$persons = PersonQuery::create()->find(); 
foreach ($persons as $person) 
{ 
    if (3 == $person->getId()) 
    { 
    break; 
    } 
} 

// now you have your person with id = 3 
var_dump($person->getId()); 
+1

を行うことができます)' :-) – Florent

+0

j0k @:私がしようとしていましたforeachループを避けるために、私は推測する通り、あなたが示唆するように、私はそれを避けることはできません。私は、ループを使用することは、複数のデータベース接続を作成するより効率的であると思います。ご回答有難うございます! – RayOnAir

+1

@Florent:この場合、[array_filter](http://php.net/manual/en/function.array-filter.php)関数の実装方法はわかりませんが、調査します...ありがとう! – RayOnAir

3

Propelが適切にクエリ結果をキャッシュしませんので、あなたは、コレクションを反復処理する必要があります(j0k @ように述べ)。 foreachループを使用する代わりに、array_filter(PHP 5.3)クロージャを渡すことができます。

// Request the persons 
$persons = PersonQuery::create()->find(); 

// Filter the persons whose ID equals 3 
$filteredPersons = array_filter($persons, function ($person) { 
    return 3 === $person->getId(); 
}); 

// Get the first result 
$person = empty($filteredPersons) ? null : $filteredPersons[0]; 

あなたは人が発見されることが確実な場合は、次の行(PHP 5.4で)書くことができます(

// Filter the person whose ID equals 3 
$person = array_filter($persons, function ($person) { 
    return 3 === $person->getId(); 
})[0]; 
+0

array_filterを使用して代替ソリューションを共有してくれてありがとう! foreachループを使用するのと比較して、このソリューションはパフォーマンスの点で優れているでしょうか?もしそうなら、直感を分かち合うことができますか? – RayOnAir

+1

PHP 5.4では、 'foreach'は' array_filter() 'より3倍高速です。さらに、 'foreach'を使うと、あなたのエントリーが見つかったときに'中断することができます。しかし、私の意見では 'array_filter()'はもっと魅力的です。 – Florent

+0

私はそれを覚えておきます。ありがとう! – RayOnAir

2

あなたが設定している場合はPropel :: isInstancePoolingEnabled()が真でありますそれは本当にデフォルトです)、次にあなたは

// Request the persons 
$persons = PersonQuery::create()->find(); 
// get person from pool 
$person = PersonPeer::getInstanceFromPool(3); 

私の英語については申し訳ありません。

1

user2663223の答えにはPropel> = 1.5での選択肢は次のようになります。

$persons = PersonQuery::create()->find() 

$person = PersonQuery::create()->findPk(3); 

これは、インスタンス・プールを利用しています。内部的には、SQLクエリが以前に実行された場合はgetInstanceFromPoolが使用されます。詳細情報については

、相談:

http://propelorm.org/documentation/03-basic-crud.html#propel-instance-pool

7

別の方法として、あなたは何回か検索する必要がある場合は特には$集・> getArrayCopy( 'ID')とのidでオブジェクトの配列を取得することです。

$persons = PersonQuery::create()->find(); 
$personsById = $persons->getArrayCopy('Id'); 

その後、あなたはあなたが(array_filter `で、よりエレガントな方法でそれを行うことができます

$person = $personsById[3]; 

または

if (isset($personsById[3])) { 
    $person = $personsById[3]; 
    ... 
} 
関連する問題