3 回答

TA貢獻(xiàn)1770條經(jīng)驗 獲得超3個贊
的MySQL>=5.1.17(或>=5.1.21) PREPARE
和 EXECUTE
發(fā)言) 可以在查詢緩存中使用準(zhǔn)備好的語句。 ..因此,您的MySQL+PHP版本可以在查詢緩存中使用準(zhǔn)備好的語句。但是,請仔細(xì)注意MySQL文檔中緩存查詢結(jié)果的注意事項。有許多類型的查詢不能被緩存,或者即使它們被緩存,也是無用的。根據(jù)我的經(jīng)驗,查詢緩存通常不是一個很大的勝利。查詢和架構(gòu)需要特殊的構(gòu)造才能最大限度地利用緩存。通常,從長遠(yuǎn)來看,應(yīng)用程序級緩存最終是必要的。 本機(jī)準(zhǔn)備對安全性沒有任何影響。偽準(zhǔn)備語句仍將轉(zhuǎn)義查詢參數(shù)值,它將在PDO庫中使用字符串完成,而不是在MySQL服務(wù)器上使用二進(jìn)制協(xié)議完成。換句話說,相同的PDO代碼將同樣容易受到注入攻擊(或不受攻擊),而不管您的攻擊是什么。 EMULATE_PREPARES
背景。唯一的區(qū)別是參數(shù)替換發(fā)生在什么地方 EMULATE_PREPARES
,它發(fā)生在PDO庫中; EMULATE_PREPARES
,它發(fā)生在MySQL服務(wù)器上。 無 EMULATE_PREPARES
您可能在準(zhǔn)備時而不是在執(zhí)行時出現(xiàn)語法錯誤; EMULATE_PREPARES
只有在執(zhí)行時才會收到語法錯誤,因為PDO直到執(zhí)行時才會向MySQL提供查詢。請注意 這會影響您將要編寫的代碼。!尤其是如果你用 PDO::ERRMODE_EXCEPTION
!
有固定的成本 prepare()
(使用本機(jī)準(zhǔn)備的語句),因此 prepare();execute()
對于本機(jī)準(zhǔn)備的語句,可能比使用模擬準(zhǔn)備語句發(fā)出普通文本查詢要慢一些。在許多數(shù)據(jù)庫系統(tǒng)中, prepare()
也是緩存的,并且可以與多個連接共享,但我認(rèn)為MySQL不會這樣做。因此,如果不將準(zhǔn)備好的語句對象用于多個查詢,則總體執(zhí)行速度可能會更慢。
作為最后建議
/** * Return PDO handle for a MySQL connection using supplied settings * * Tries to do the right thing with different php and mysql versions. * * @param array $settings with keys: host, port, unix_socket, dbname, charset, user, pass. Some may be omitted or NULL. * @return PDO * @author Francis Avila */function connect_PDO($settings){ $emulate_prepares_below_version = '5.1.17'; $dsndefaults = array_fill_keys(array('host', 'port', 'unix_socket', 'dbname', 'charset'), null); $dsnarr = array_intersect_key($settings, $dsndefaults); $dsnarr += $dsndefaults; // connection options I like $options = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ); // connection charset handling for old php versions if ($dsnarr['charset'] and version_compare(PHP_VERSION, '5.3.6', '<')) { $options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$dsnarr['charset']; } $dsnpairs = array(); foreach ($dsnarr as $k => $v) { if ($v===null) continue; $dsnpairs[] = "{$k}={$v}"; } $dsn = 'mysql:'.implode(';', $dsnpairs); $dbh = new PDO($dsn, $settings['user'], $settings['pass'], $options); // Set prepared statement emulation depending on server version $serverversion = $dbh->getAttribute(PDO::ATTR_SERVER_VERSION); $emulate_prepares = (version_compare($serverversion, $emulate_prepares_below_version, '<')); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, $emulate_prepares); return $dbh;}
添加回答
舉報