SORU
11 NİSAN 2012, ÇARŞAMBA


PDO MySQL: PDO::ATTR_EMULATE_PREPARES mı?

Bu okudum ne kadar PDO::ATTR_EMULATE_PREPARES

  1. PDO's prepare emulation is better for performance since MySQL's native prepare bypasses the query cache.
  2. MySQL's native prepare is better for security (preventing SQL Injection).
  3. MySQL's native prepare is better for error reporting.

Ne kadar doğru bu ifadelerin herhangi bir artık bilmiyorum. Bir MySQL arayüzü en büyük endişem SQL Enjeksiyon engelliyor. İkinci endişe performans.

Benim uygulama şu anda usul MySQLi (hazır deyimler olmadan) kullanır ve sorgu önbelleği biraz kullanır. Nadiren yeniden kullanım, tek bir istekte tablolar hazırlandı. Hazırlanan isimlendirilmiş parametreleri ve güvenlik için PDO için hareket başladı.

MySQL 5.1.61 PHP 5.3.2 kullanıyorum

PDO::ATTR_EMULATE_PREPARES ya da sağladı mı bırakayım? Bir şekilde sorgu önbellek performans ve hazırlanmış deyimleri güvenliğini de var mı?

CEVAP
4 Mayıs 2012, Cuma


Endişelerinizi yanıtlamak için:

  1. PREPARE EXECUTE açıklamaları = 5.1.21) can use prepared statements in the query cache. MySQL PHP sürümünüz sorgu önbelleği ile ilgili hazırlanan ifadeleri kullanabilirsiniz. Ancak, MySQL belgelerinde sorgu sonuçlarını önbelleğe alma için uyarılar dikkatli not alın. Önbelleğe edemiyor veya önbelleğe alınmış olsa bile işe yaramaz sorgular, pek çok çeşidi vardır. Benim durumumda sorgu önbellek genellikle çok büyük bir kazanç değildir zaten. Sorgular ve şemalar Özel yapım önbelleği maksimum faydalanmak gerekir. Sık sık uygulama düzeyi biter zaten gerekli olan uzun vadede önbellekleme.

  2. Yerel güvenlik için herhangi bir fark yapmaz hazırlar. Sözde hazırlanan ifadeleri hala sorgu parametre değerleri kaçar, sadece MySQL sunucunun ikili protokolünü kullanarak dizeleri ile PDO Kütüphanesi yerine yapılacak. Diğer bir deyişle, aynı PDO kodu aynı derecede hassas (kırılgan) enjeksiyon saldırıları EMULATE_PREPARES ayarı ne olursa olsun, olacak. Tek fark, parametre değiştirme PDO kütüphane oluşur EMULATE_PREPARES--oluştuğu; EMULATE_PREPARES MySQL sunucusu üzerinde oluşur.

  3. Olmadan EMULATE_PREPARES olabilir alın yazım hatalarını hazır-zaman yerine de yürütme zamanı; EMULATE_PREPARES tek alın yazım hatalarını yürütme zamanında çünkü PDO yok bir sorgu vermek için MySQL kadar yürütme zamanı. Unutmayınbu yazacağım kodu etkiler! Özellikle PDO::ERRMODE_EXCEPTION kullanıyorsunuz.

Ek bir husus:

  • Bir sabit maliyet için prepare() (kullanarak yerel hazır deyimler), prepare();execute() ile yerel hazırlanan ifadeleri olabilir biraz daha yavaş veren bir düz metin sorgu kullanarak taklit hazırlanan ifadeleri. Birçok veritabanı sistemi prepare() için bir sorgu planı önbelleğe alınır ve birden çok bağlantı ile paylaşılabilir, ama MySQL bunu yapar sanmıyorum. Eğer öyleyse hazırlanmış deyimi yeniden eğer birden fazla sorgu için genel yürütme yavaş olabilir nesnesi.

Son bir öneri olarakMySQL PHP eski sürümleri ile bence hazırlanmış deyimleri taklit gerekir, ama çok son sürümleri ile öykünme kapatmanız gerekir.

PDO kullanan bir kaç uygulamalar yazdıktan sonra, bence ne var ki PDO bağlantı işlevi en iyi ayarları yaptım. Muhtemelen böyle bir şeyi kullanmak veya tercih ayarlarını çimdik gerekir:

/**
 * 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;
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EEVblog

    EEVblog

    4 NİSAN 2009
  • Kyler Briskey

    Kyler Briske

    20 ŞUBAT 2011
  • laptopmag

    laptopmag

    25 Ocak 2008