mysqli veya PDO - artıları ve eksileri nelerdir? [kapalı]


342

Bizim yerimizde hazırlanmış ifadeler ve işlem desteği gibi şeyler için mysqli ve PDO kullanma arasında bölünmüş durumdayız. Bazı projeler birini, diğerini kullanır. Başka bir RDBMS'ye geçme ihtimalimiz çok az gerçekçi.

Ben hazırlanan ifadeler için adlandırılmış parametrelere izin tek nedeni PDO tercih ve bildiğim kadarıyla mysqli değil.

Projelerimizi tek bir yaklaşım kullanacak şekilde birleştirdiğimizden diğerini standart olarak seçmenin başka artıları ve eksileri var mı?


5
Bu makale hangisini kullanacağınızı seçmenize yardımcı olacaktır. Performansı düşünürseniz, bu seçmenize yardımcı olabilir.
ravi404

3
Kaç kişinin "yapıcı olmayan" bir soruyu iptal ettiği ve oynadığı komik. Mesele şu ki, tam iş parçacığı çok yapıcıdır - belki de moderatörler bir sorunun yapıcı olup olmadığını değerlendirirken bunu dikkate almalıdır?
marlar

@marlar Sooooooo sana katılıyorum! Bu gerçekten StackOverflow'daki en büyük sorundur. Mükemmel sorular / tartışmalar her zaman kapalıdır.
Sliq

Yanıtlar:


243

Nesne yönelimli yönüyle, hazırlanan ifadelerle, bunun standart haline geldiği vb. İşte orada:

PDO ile gerçekten güzel bir şey, verileri bir nesneye otomatik olarak enjekte ederek getirebilmenizdir. Bir ORM kullanmak istemiyorsanız (çünkü bu sadece hızlı bir komut dosyasıdır) ancak nesne eşlemesini seviyorsanız, GERÇEKTEN havalı:

class Student {

    public $id;
    public $first_name;
    public $last_name

    public function getFullName() {
        return $this->first_name.' '.$this->last_name
    }
}

try 
{
    $dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)

    $stmt = $dbh->query("SELECT * FROM students");

    /* MAGIC HAPPENS HERE */

    $stmt->setFetchMode(PDO::FETCH_INTO, new Student);


    foreach($stmt as $student)
    {
        echo $student->getFullName().'<br />';
    } 

    $dbh = null;
}
catch(PDOException $e)
{
    echo $e->getMessage();
}

12
yukarıdakiler arasında bir fark var $mysqliResult->fetch_object("student");mı?
Andy Fleming

2
@ e-satis hayır, PHP kullanıyorum. Genel alanlar kapsüllemeyi ihlal ettiğinden, AS A BEST PRACTICEyalnızca ... lol :) Google genel alanları kullanmaz, yalnızca erişimciler kullanır: google-styleguide.googlecode.com/svn/trunk/… .
OZ_

6
@ e-satis: Atladığım için üzgünüm, ancak değişkenler değiştiğinde ne olacağını kontrol etmek istiyorsanız alıcılar ve ayarlayıcılar gereklidir. Aksi takdirde, nesnenizin dahili durumunu garanti edemezsiniz (özellikle içinde başka bir nesne varsa bu bir sorundur). Bu tamamen dilden bağımsızdır. @OZ_: Kolaylaşın. Kişisel eleştiri sadece birisini savunmaya geçirir.
James P.

2
@monadic: Kabul etti. Kapsülleme elbette çekirdek bileşenler veya karmaşık nesneler vb. İle uğraşırken geçerli bir argümandır, ancak aksi halde okuma-yazma doçenti olacak kayıtların temsili olarak. diziler, bu kabul edilebilir. Ayrıca, kayıtlar sistem içinde yüzdüğü için daha kolay yazım denetimine izin verir.
Dan Lugg

15
@outis Umarım burada azınlıkta değilim, ama cevapların yeni geliştiricilere karşı güvenlikleri konusunda yargılanması gerektiğini düşünmüyorum. Kulağa sert geliyor, ama bu doğru. SO'ya verilen cevabın amacı sadece kopyala ve yapıştır kodu sağlamak değil, aynı zamanda anlayış sağlamaktır. Her güvenlik açığının veya desen kusurunun bir örnekte ele alındığından emin olmak yanıtın işi değildir, bununla yüzleşelim, kodun kopyalandığı uygulama, aynı kodu kullanan diğer tüm uygulamalardan doğal olarak farklıdır.
Mattygabe

57

Bir uygulamayı bir veritabanından diğerine taşımak çok yaygın değildir, ancak er ya da geç kendinizi farklı bir RDBMS kullanarak başka bir proje üzerinde çalışırken bulabilirsiniz. Eğer PDO ile evdeyseniz, o zaman öğrenilecek en az bir şey daha olacaktır.

Bunun dışında PDO API'sini biraz daha sezgisel buluyorum ve daha gerçekten nesne odaklı hissediyor. mysqli, ne demek istediğimi biliyorsanız, sadece nesneleştirilmiş bir prosedürel API gibi hissediyor. Kısacası, PDO'nun çalışmasını daha kolay buluyorum, ancak bu elbette öznel.


25

Bence PDO kullanmaya başladım çünkü ifade desteği daha iyi. ActiveRecord-esque veri erişim katmanı kullanıyorum ve dinamik olarak oluşturulan ifadeleri uygulamak çok daha kolay. MySQLi'nin parametre bağlaması tek bir işlev / yöntem çağrısında yapılmalıdır, bu yüzden çalışma zamanına kadar kaç parametreyi bağlamak istediğinizi bilmiyorsanız, seçimler için kullanmak zorundasınız call_user_func_array()(doğru işlev adı olduğuna inanıyorum) . Ve basit dinamik sonuç bağlamayı unutun.

En önemlisi, PDO'yu seviyorum çünkü çok makul bir soyutlama seviyesi. SQL yazmak istemediğiniz tamamen soyut sistemlerde kullanımı kolaydır, ancak daha optimize edilmiş, saf bir sorgu tipi sistemi kullanmayı veya ikisini karıştırıp eşleştirmeyi de kolaylaştırır.


2
Dinamik olarak üretilen sorgularla sonuç bağlama mümkündür, bunu uygulamalarımızda yaparız. Ancak bu büyük bir acıdır.
Pim Jager

17

PDO standarttır, çoğu geliştiricinin kullanmayı beklediği şey budur. mysqli aslında belirli bir soruna ısmarlama bir çözümdü, ancak diğer DBMS'ye özgü kütüphanelerin tüm sorunlarına sahip. PDO, tüm sıkı çalışmanın ve akıllı düşünmenin gideceği yerdir.


15

Akılda tutulması gereken başka bir şey var: Şimdilik (PHP 5.2) PDO kütüphanesi hatalıdır . Garip böceklerle dolu. Örneğin: PDOStatementbir değişkeni saklamadan önce , değişken unset()bir ton hatadan kaçınmalıdır. Bunların çoğu PHP 5.3'te düzeltildi ve muhtemelen diğer birçok hataya sahip olacak olan PHP 5.3'te yayınlanacak. Topluluğa yardım etmek istiyorsanız, kararlı bir sürüm istiyorsanız, PHP 6.1 için PDO kullanmaya ve PHP 5.3 için PDO kullanmaya odaklanmalısınız.


2
PDO'nun sunduğu kazanımların hataların anlaşılması ve üzerinde çalışılmaya değer olduğunu düşünüyorum. PHP, çok verimli hatalarla doludur, bazıları verimli bir şekilde çalışamadık ve yine de diğer seçenekler yerine kullanmamıza neden olan birçok fayda sunuyor.
Brian Warshaw

11
Uhm, garip, PDO ile hiç bir hata yaşamadım. Ve onu çok kullanıyorum.
NikiC

Mysqli'nin de hataları var. Tüm yazılımlarda hatalar var.
Bill Karwin

10

PDO ile ilgili bir başka önemli (iyi) fark, PDO::quote()yöntemin otomatik olarak ekli tırnakları mysqli::real_escape_string()eklemesidir , oysa (ve benzerleri):

PDO :: quote (), tırnakları girdi dizesinin etrafına (gerekirse) yerleştirir ve temel sürücüye uygun bir tırnak stili kullanarak girdi dizesinin içindeki özel karakterlerden kaçar.


8

PDO, sitenizi / web uygulamanızı günlük olarak veritabanına dağıtmak için Ana ve bağımlı bağlantıları kurabildiğiniz gibi ölçeklenmeyi çok daha kolay hale getirecektir, ayrıca PHP standart olarak PDO'ya geçmeye doğru ilerlemektedir.

PDO Bilgisi

Web Uygulamasını Ölçeklendirme


6

Yürütme hızı açısından MySQLi kazanır, ancak MySQLi kullanarak iyi bir sarıcı yoksa, hazırlanan ifadelerle ilgilenen işlevleri korkunçtur.

Benimkimde hala hatalar var, ama kimse isterse, işte burada .

Kısacası, bir hız kazancı arıyorsanız, MySQLi; kullanım kolaylığı istiyorsanız, o zaman PDO.


2
hız açısından ölçütler verebilir misiniz?
Julius F

8
Jonathen Robson, jonathanrobson'da ikisinin iyi bir hız karşılaştırması yaptı. Me/2010/06/mysqli-vs-pdo-benchmarks . Özet: inserts - neredeyse eşittir, selects - mysqli, hazırlanmamış ifadeler için ~% 2.5, hazırlanmış ifadeler için ~% 6.7 daha hızlıdır. Performans cezalarının ne kadar küçük olduğu düşünüldüğünde, kullanım özellikleri ve esnekliği PDOgenellikle performans vuruşundan ağır basar.
Adam

1
@Adam Bloguma bağladığınız için teşekkürler!
jnrbsn

@ daemonfire300 Bu doğrudur, kriterlere gerek yoktur. PDO mysqli kütüphanesini sarar. Birisi PDO'nun mysqli'den daha hızlı olduğunu kanıtlayabilirse muhtemelen fanı vurabilirim. :-D
Dyin

@jnrbsn Adam'a söylediklerine katılıyor musun?
Basit

5

Şahsen PDO kullanıyorum, ama bence bu bir tercih meselesi.

PDO, SQL enjeksiyonuna ( hazırlanmış ifadelere ) yardımcı olan bazı özelliklere sahiptir , ancak SQL'inize dikkat ediyorsanız mysqli ile de bunu başarabilirsiniz.

Başka bir veritabanına geçmek PDO'yu kullanmak için bir neden değildir. "Özel SQL özellikleri" kullanmadığınız sürece, bir DB'den diğerine geçiş yapabilirsiniz. Ancak, örneğin "SELECT ... LIMIT 1" kullandığınız anda MS-SQL'e "SELECT TOP 1 ..." olduğu yere gidemezsiniz. Bu zaten sorunlu.


22
MySQLi ifadeler hazırladı.
Kule

5

Düzenlenmiş cevap.

Bu API'ların her ikisiyle de biraz deneyim kazandıktan sonra, mysqli'yi yerel hazırlanmış ifadelerle kullanılamaz hale getiren 2 engelleme düzeyi özelliği olduğunu söyleyebilirim.
Zaten 2 mükemmel (ancak yolun altında kalan) cevapta belirtilmişlerdir:

  1. Değerleri isteğe bağlı yer tutucu sayısına bağlama
  2. Verileri salt dizi olarak döndürme

(her ikisi de bu cevapta belirtilmiştir )

Nedense mysqli her ikisiyle de başarısız oldu.
Günümüzde ikincisi için bazı iyileştirmeler yapıldı ( get_result ), ancak yalnızca mysqlnd kurulumlarında çalışır, komut dosyalarınızda bu işleve güvenemeyeceğiniz anlamına gelir.

Yine de, bugüne kadar bile bir değeri yoktur.

Yani, tek bir seçenek var: PDO

Gibi diğer tüm nedenler

  • yer tutucular olarak adlandırıldı (bu sözdizimi şekeri abartılıyor)
  • farklı veritabanları desteği (aslında hiç kimse kullanmamış)
  • nesneye getir (sadece işe yaramaz sözdizimi şekeri)
  • hız farkı (yok)

önemli bir önemi yok.

Aynı zamanda bu iki API'ler azından bazı yoksun gerçek önemli özellikleri gibi,

  • tanımlayıcı yer tutucusu
  • dinamik bağlamayı daha az zahmetli hale getirmek için karmaşık veri türlerinin yer tutucusu
  • daha kısa uygulama kodu.

Bu nedenle, gerçek yaşam ihtiyaçlarını karşılamak için, bu API'lardan birine dayanarak manuel olarak ayrıştırılmış yer tutucular uygulayarak kendi soyutlama kütüphanesini oluşturmanız gerekir. Bu durumda mysqli'yi tercih ederim, çünkü daha az soyutlama seviyesine sahiptir.


Sonunda hayatın gerçeklerini bilen ve inkar etmeyen biri ...
İhsan

4

Karşılaştırma komut dosyamda , her yöntem 10000 kez test edilir ve her yöntem için toplam süre farkı yazdırılır. Bunu kendi yapılandırmanızda yapmalısınız, eminim sonuçlar değişecektir!

Bunlar benim sonuçlarım:

  • " SELECT NULL" -> PGO()~ 0.35 saniye daha hızlı
  • " SHOW TABLE STATUS" -> mysqli()~ 2,3 saniye daha hızlı
  • " SELECT * FROM users" -> mysqli()~ 33 saniye daha hızlı

Not: mysqli için -> fetch_row () kullanarak, sütun adları diziye eklenmez, ben PGO bunu yapmak için bir yol bulamadık. - - fetch_array () kullansam bile, mysqli biraz daha yavaş ama yine de PGO'dan daha hızlı (SELECT NULL hariç).


17
PGO nedir? Ve daha hızlı 33 saniye ?! İnanması çok zor ...
Alix Axel

3

PDO MySQLi gerçekten sevmediğim bir şey var PDO belirli bir sınıf türü (örneğin $pdo->fetchObject('MyClass')) bir nesne olarak bir sonuç döndürme yeteneğidir . MySQLi fetch_object()yalnızca bir stdClassnesne döndürür .


19
Aslında, bir sınıfı manuel olarak belirtebilirsiniz: "object mysqli_result :: fetch_object ([string $ class_name [, array $ params]])". stdClass yalnızca hiçbir şey belirtmezseniz kullanılır.
Andrioid

-4

Akılda tutulması gereken bir şey var.

Mysqli, sütunları sütun adlarını temsil eden anahtarlarla döndürecek fetch_assoc () işlevini desteklemez. Tabii ki bunu yapmak için kendi işlevinizi yazmak mümkün, çok uzun değil, ama yazarken gerçekten zorlandım (inanmayanlar için: eğer size kolay geliyorsa, kendi başınıza deneyin ve yapma ' t hile :))



2
Uzun zaman önce uyguluyordum, ama evet kılavuzu kontrol ettim. Hazırlanan ifadelerle çalışır mı? Şüpheliyim ...
mike

2
Aslında, merakla kısmi bir desteği var. Dizileri düzenli sorgularda alabilir, ancak parametreli sorgularda değil: -!
Álvaro González

1
Açıkça yanlış olan bir cevabı neden silmiyorsunuz?
Majid Fouladpour

2
@MajidFouladpour - Cevap açıkçası yanlış değil . Sadece bir bağlamı eksik. Mysqli yok değil tamamen ilişkili dizi alma.
Álvaro González
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.