Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

PDO MySQL:PDO::ATTR_EMULATE_PREPARES का प्रयोग करें या नहीं?

आपकी चिंताओं का उत्तर देने के लिए:

  1. MySQL>=5.1.17 (या>=5.1.21 PREPARE के लिए और EXECUTE कथन) क्वेरी कैश में तैयार किए गए कथनों का उपयोग कर सकते हैं . तो MySQL+PHP का आपका संस्करण क्वेरी कैश के साथ तैयार कथन का उपयोग कर सकता है। हालांकि, MySQL प्रलेखन में क्वेरी परिणामों को कैशिंग करने के लिए सावधानियों का ध्यान रखें। ऐसे कई प्रकार के प्रश्न हैं जिन्हें कैश नहीं किया जा सकता है या जो कैश होने पर भी बेकार हैं। मेरे अनुभव में क्वेरी कैश अक्सर वैसे भी बहुत बड़ी जीत नहीं होती है। कैश का अधिकतम उपयोग करने के लिए क्वेरी और स्कीमा को विशेष निर्माण की आवश्यकता होती है। अक्सर एप्लिकेशन-स्तरीय कैशिंग लंबे समय में वैसे भी आवश्यक हो जाती है।

  2. देशी तैयारी सुरक्षा के लिए कोई फर्क नहीं पड़ता। छद्म-तैयार बयान अभी भी क्वेरी पैरामीटर मानों से बच जाएंगे, यह सिर्फ पीडीओ लाइब्रेरी में बाइनरी प्रोटोकॉल का उपयोग करके MySQL सर्वर पर स्ट्रिंग के साथ किया जाएगा। दूसरे शब्दों में, वही पीडीओ कोड आपके EMULATE_PREPARES पर ध्यान दिए बिना इंजेक्शन हमलों के लिए समान रूप से असुरक्षित (या असुरक्षित) होगा। सेटिंग। केवल अंतर यह है कि जहां पैरामीटर प्रतिस्थापन होता है -- EMULATE_PREPARES . के साथ , यह पीडीओ पुस्तकालय में होता है; बिना EMULATE_PREPARES . के , यह MySQL सर्वर पर होता है।

  3. 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;
}


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL अपडेट केस मदद

  2. एक पंक्ति सम्मिलित करने के लिए SqlDataAdapter का उपयोग करना

  3. MySQL को मारियाडीबी 10 में अपग्रेड करें (भाग 1 - मारियाडीबी 5.5 स्थापित करें)

  4. MySQL डेटाबेस में सिंगल टेबल का बैकअप कैसे लें?

  5. डेटाबेस व्यवस्थापकों के लिए शीर्ष MySQL ब्लॉग और वेबसाइट