2012-09-03 9 views
8

Sto usando Propel 1.6 e non sono sicuro di come ottenere un oggetto (dato il suo valore di attributo "id") da una collezione di oggetti propel. Non sono riuscito a trovare una risposta diretta nella documentazione di Propel (PropelCollection methods non sembra applicabile?). Per esempio: Diciamo che ho una tabella "Persona" con il seguente schema:Come ottenere oggetto con "id" dalla collezione di oggetti propel?

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

devo fare la seguente query per ottenere una collezione di oggetti "persona":

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

Poi, ho desidera trovare un oggetto "Persona" con un determinato "id" (ad es. "Persona" con "id = 3"), senza creare una nuova query nel database. Come posso farlo?

$persons->get(...?)? 

In altre parole, io non voglio fare:

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

Contesto:

Vorrei evitare che facendo una query di database per migliorare le prestazioni. La dichiarazione deve essere inserito all'interno di una dichiarazione foreach che altrimenti porterebbe a numerose connessioni al database, come il seguente:

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

risposta

4

Beh, che non sarà molto efficiente, ma si può passare attraverso la raccolta per trovarlo .

$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

Puoi farlo in un modo più elegante con 'array_filter()' :-) – Florent

+0

@ J0K: stavo cercando per evitare un ciclo di foreach, ma suppongo, come suggerisci, che non posso evitarlo. Penso che andare con il ciclo sarebbe ancora più efficiente di fare più connessioni al database. Grazie per la tua risposta! – RayOnAir

+1

@Florent: non sono sicuro di come implementare la funzione [array_filter] (http://php.net/manual/en/function.array-filter.php) in questo caso, ma indagherò su ... Grazie! – RayOnAir

3

Dal Propel non memorizza nella cache risultato della query correttamente, è necessario scorrere la collezione (come @ J0K ha detto). Invece di utilizzare un ciclo foreach, è possibile chiamare array_filter passando una chiusura (con 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]; 

Se si è sicuri che la persona sarà trovato, si può anche scrivere (con PHP 5.4) le seguenti righe:

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

grazie per aver condiviso una soluzione alternativa con array_filter! Questa soluzione sarebbe migliore dal punto di vista delle prestazioni rispetto all'utilizzo di un ciclo foreach? Se è così, potresti condividere l'intuizione dietro? – RayOnAir

+1

Con PHP 5.4, 'foreach' è 3 volte più veloce di' array_filter() '. Inoltre usando 'foreach' puoi' break' quando la tua voce viene trovata. Ma a mio parere 'array_filter()' è più _estetico_. – Florent

+0

Lo terrò a mente. Grazie! – RayOnAir

2

se si imposta Propel :: isInstancePoolingEnabled() è vera (è vero per impostazione predefinita), quindi è possibile

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

scusa per il mio inglese.

7

Un'altra alternativa, soprattutto se avete bisogno di cercare più volte è quello di ottenere array di oggetti da id con $ Collezione> getArrayCopy ('id').

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

Poi si può fare

$person = $personsById[3]; 

o

if (isset($personsById[3])) { 
    $person = $personsById[3]; 
    ... 
} 
Problemi correlati