ho scritto un sacco di codice per i parametri del database e citando in Zend Framework mentre ero il team lead per il progetto (fino alla versione 1.0).
Ho cercato di incoraggiare le migliori pratiche laddove possibile, ma ho dovuto trovare un equilibrio con facilità d'uso.
Si noti che è sempre possibile esaminare il valore di stringa di un oggetto Zend_Db_Select
, per vedere come ha deciso di fare quoting.
print $select; // invokes __toString() method
Inoltre è possibile utilizzare il Zend_Db_Profiler
per ispezionare il codice SQL che viene eseguito sul vostro conto da Zend_Db
.
$db->getProfiler()->setEnabled(true);
$db->update(...);
print $db->getProfiler()->getLastQueryProfile()->getQuery();
print_r $db->getProfiler()->getLastQueryProfile()->getQueryParams();
$db->getProfiler()->setEnabled(false);
Ecco alcune risposte alle vostre domande specifiche:
Zend_Db_Select::where('last_name=?', $lname)
I valori sono espressi in modo appropriato. Sebbene "?
" assomigli a un segnaposto per parametro, in questo metodo l'argomento viene effettivamente quotato in modo appropriato e interpolato. Quindi non è un vero parametro di query. In realtà, le due istruzioni seguenti producono esattamente la stessa query come l'utilizzo di cui sopra:
$select->where($db->quoteInto('last_name=?', $lname));
$select->where('last_name=' . $db->quote($lname));
Tuttavia, se si passa un parametro che è un oggetto di tipo Zend_Db_Expr
, allora non è citato. Sei responsabile per i rischi di SQL injection, perché è interpolata pari pari, per sostenere valori di espressione:
$select->where('last_modified < ?', new Zend_Db_Expr('NOW()'))
Qualsiasi altra parte di quella espressione che deve essere quotate o delimitato è la vostra responsabilità. Ad esempio, se si interpola qualsiasi variabile PHP nell'espressione, la sicurezza è una vostra responsabilità. Se i nomi di colonna sono parole chiave SQL, è necessario delimitarli autonomamente con quoteIdentifier()
. Esempio:
$select->where($db->quoteIdentifier('order').'=?', $myVariable)
Zend_Db_Adapter_Abstract::insert(array('colname' => 'value'))
nome della tabella e delle colonne nomi sono delimitati, a meno che non si spegne AUTO_QUOTE_IDENTIFIERS
.
I valori sono parametrizzati come parametri di query reali (non interpolati). A meno che il valore non sia un oggetto Zend_Db_Expr
, nel qual caso è interpolato letteralmente, quindi è possibile inserire espressioni o NULL
o qualsiasi altra cosa.
Zend_Db_Adapter_Abstract::update(array('colname' => 'value'), $where)
nome della tabella e delle colonne nomi sono delimitati, a meno che non si spegne AUTO_QUOTE_IDENTIFIERS
.
I valori sono parametrizzati, a meno che non si tratti di oggetti Zend_Db_Expr
, come nel metodo insert()
.
L'argomento $where
non è filtrato affatto, quindi sei responsabile per qualsiasi rischio di iniezione SQL in quello. È possibile utilizzare il metodo quoteInto()
per rendere più conveniente la quotatura.
fonte
2009-06-12 06:50:54
Ottima risposta, Bill e un ottimo componente a tutto tondo :) –
Se si utilizza la funzione 'insert()' su un'istanza di 'TableGateway', l'escape delle colonne con nomi riservati viene eseguito automaticamente per te come indicato nel secondo punto sopra. Se lo si esegue manualmente (ad es. (SQL Server) 'array ([from] => 1));' produce un errore del database che dice ''[from]'' è un nome di colonna non valido. Quella colonna potrebbe essere stata sfuggita due volte come '[[from]]' –