आपकी चिंताओं का उत्तर देने के लिए:
-
देशी तैयारी सुरक्षा के लिए कोई फर्क नहीं पड़ता। छद्म-तैयार बयान अभी भी क्वेरी पैरामीटर मानों से बच जाएंगे, यह सिर्फ पीडीओ लाइब्रेरी में बाइनरी प्रोटोकॉल का उपयोग करके MySQL सर्वर पर स्ट्रिंग के साथ किया जाएगा। दूसरे शब्दों में, वही पीडीओ कोड आपके
EMULATE_PREPARES
पर ध्यान दिए बिना इंजेक्शन हमलों के लिए समान रूप से असुरक्षित (या असुरक्षित) होगा। सेटिंग। केवल अंतर यह है कि जहां पैरामीटर प्रतिस्थापन होता है --EMULATE_PREPARES
. के साथ , यह पीडीओ पुस्तकालय में होता है; बिनाEMULATE_PREPARES
. के , यह MySQL सर्वर पर होता है। -
EMULATE_PREPARES
के बिना आपको निष्पादन-समय के बजाय तैयारी-समय पर वाक्यविन्यास त्रुटियां मिल सकती हैं;EMULATE_PREPARES
के साथ निष्पादन समय पर आपको केवल सिंटैक्स त्रुटियां मिलेंगी क्योंकि पीडीओ के पास निष्पादन समय तक MySQL को देने के लिए कोई प्रश्न नहीं है। ध्यान दें कि यह आपके द्वारा लिखे जाने वाले कोड को प्रभावित करता है ! खासकर यदि आपPDO::ERRMODE_EXCEPTION
. का उपयोग कर रहे हैं !
एक अतिरिक्त विचार:
prepare()
. के लिए एक निश्चित लागत है (मूल रूप से तैयार किए गए कथनों का उपयोग करके), इसलिए एकprepare();execute()
देशी तैयार बयानों के साथ नकली तैयार बयानों का उपयोग करके एक सादा पाठ्य क्वेरी जारी करने से थोड़ा धीमा हो सकता है। कई डेटाबेस सिस्टम परprepare()
. के लिए क्वेरी प्लान साथ ही कैश किया गया है और कई कनेक्शनों के साथ साझा किया जा सकता है, लेकिन मुझे नहीं लगता कि MySQL ऐसा करता है। इसलिए यदि आप कई प्रश्नों के लिए अपनी तैयार कथन वस्तु का पुन:उपयोग नहीं करते हैं तो आपका समग्र निष्पादन धीमा हो सकता है।
अंतिम अनुशंसा के रूप में , मुझे लगता है कि MySQL+PHP के पुराने संस्करणों के साथ, आपको तैयार किए गए कथनों का अनुकरण करना चाहिए, लेकिन अपने हाल के संस्करणों के साथ आपको अनुकरण बंद कर देना चाहिए।
पीडीओ का उपयोग करने वाले कुछ ऐप्स लिखने के बाद, मैंने एक पीडीओ कनेक्शन फ़ंक्शन बनाया है जिसमें मुझे लगता है कि सबसे अच्छी सेटिंग्स हैं। आपको शायद कुछ इस तरह का उपयोग करना चाहिए या अपनी पसंदीदा सेटिंग में बदलाव करना चाहिए:
/**
* 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;
}