Domanda

Questo è un po 'strano, e potrei benissimo scrivere questo codice completamente sbagliato, quindi perché ho riscontrato lo stesso errore due volte in due giorni, in parti completamente diverse di uno script. Il codice che sto usando è sotto:


    public function findAll( $constraints = array() ) {

        // Select all records
        $SQL = 'SELECT * FROM ' . $this->tableName;

        // See if there's any constraints
        if( count( $constraints ) > 0 ) {
            $SQL .= ' WHERE ';

            foreach( $constraints as $field => $value ) {
                $SQL .= $field . ' = :' . $field . ' AND ';
            }

        }

        // Remove the final AND and prepare the statement
        $SQL = substr( $SQL, 0, -5 );       
        $PDOStatement = $this->PDO->prepare( $SQL );

        // Loop through constraints and bind parameters
        foreach( $constraints as $field => $value ) {
            print 'Binding ' . $field . ' to ' . $value . ' 
'; $PDOStatement->bindParam( $field, $value ); } $PDOStatement->execute(); var_dump($PDOStatement); while ( $results = $PDOStatement->fetch( PDO::FETCH_ASSOC ) ) { var_dump($results); } }

Sono abbastanza nuovo nell'uso del PDO, ma fondamentalmente sto cercando di superare una serie di vincoli, ad es.

array( 'active' => 1, 'name' => 'James' )
e restituisce tutte le righe dalla tabella
WHERE active = 1 AND name = 'James'

Se uso questo array, l'SQL eseguito dal primo

var_dump( )
è
SELECT * FROM {table} WHERE active = :active AND name = 'James'
, esattamente come mi aspetto. I parametri associati stampano "Binding attivo su 1" e "Binding name to James", esattamente come previsto. Le righe esistono nel database, eppure la seconda chiamata
var_dump()
per $ results non restituisce nulla, ovvero nessuna riga viene restituita.

Se passo una matrice di un singolo vincolo, ad es.

array( 'active' => 1 )
, funziona perfettamente. Sembra che ogni volta che vengono superati più vincoli smetta di funzionare.

È stato utile?

Soluzione

Questo perché bindParam funziona con associazione a una variabile e si sta riutilizzando la variabile ( $ value ) per più valori. Prova invece con bindValue .

O ancora meglio; Passa i valori come matrice a esegui anziché. Questo rende la dichiarazione apolide, che è generalmente una buona cosa in programmazione.

Altri suggerimenti

Come accennato, usando bindValue invece di bindParam riuscirà sicuramente a farlo. Tuttavia, dopo aver trascorso molto tempo a risolvere questo problema di recente, ho scoperto una soluzione alternativa. Ecco come realizzare l'associazione delle variabili PDO in un ciclo foreach utilizzando bindParam:

Sostituisci la seguente riga dal post originale:

$PDOStatement->bindParam( $field, $value );

... con questo:

$PDOStatement->bindParam( $field, $constraints[$field] );

Invece di associare $ value , usa $ array_name [$ array_key] . Questo funziona perché ora stai vincolando una variabile unica anziché una che viene riutilizzata ad ogni passaggio del ciclo.

Tuttavia, la variabile $ field utilizzata come segnaposto non deve necessariamente essere una variabile univoca. Non l'ho ancora studiato a fondo, ma una variabile utilizzata come segnaposto sembra essere analizzata immediatamente (anziché essere assegnata come riferimento variabile) anche quando si utilizza bindParam.

Inoltre, poiché non avresti più bisogno di accedere direttamente a $ value , puoi anche sostituire questo:

foreach( $constraints as $field => $value ) {

... con questo:

foreach (array_keys($constraints) as $field) {

Questo è facoltativo, poiché funzionerà bene senza questa modifica. A mio avviso, tuttavia, sembra più pulito, dal momento che potrebbe diventare più confuso in seguito al motivo per cui $ value è assegnato ma mai utilizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top