mysqli या PDO - पेशेवरों और विपक्ष क्या हैं? [बन्द है]


342

हमारे स्थान पर हम तैयार विवरण और लेनदेन समर्थन जैसे सामान के लिए mysqli और PDO का उपयोग करने के बीच विभाजित हैं। कुछ परियोजनाएँ एक का उपयोग करती हैं, कुछ अन्य की। हम में से किसी भी दूसरे RDBMS में जाने की बहुत कम संभावना है।

मैं इस कारण से पीडीओ को पसंद करता हूं कि यह तैयार किए गए कथनों के लिए नामित मापदंडों की अनुमति देता है, और जहां तक ​​मुझे जानकारी है mysqli नहीं करता है।

क्या हम एक मानक के रूप में दूसरे को चुनने के लिए कोई अन्य पेशेवरों और विपक्ष हैं क्योंकि हम अपनी परियोजनाओं को सिर्फ एक दृष्टिकोण का उपयोग करने के लिए समेकित करते हैं?


5
यह लेख चुनने में मदद करेगा कि कौन सा उपयोग करना है। आप प्रदर्शन पर विचार करें यह मदद कर सकता है आप का फैसला किया।
रविवि

3
यह हास्यास्पद है कि कितने लोगों ने एक प्रश्न को उकसाया और अभिनीत किया जो "रचनात्मक नहीं" है। बात यह है कि, पूर्ण धागा बहुत रचनात्मक है - शायद मध्यस्थों को यह ध्यान में रखना चाहिए जब यह देखते हुए कि एक प्रश्न रचनात्मक है या नहीं?
marlar

@marlar मैं sooooooo आप के साथ सहमत हूँ! यह वास्तव में StackOverflow पर सबसे बड़ी समस्या है। उत्कृष्ट प्रश्न / चर्चा हमेशा बंद रहती है।
सालीक

जवाबों:


243

ठीक है, आप ऑब्जेक्ट ओरिएंटेड पहलू, तैयार किए गए कथनों, इस तथ्य के साथ बहस कर सकते हैं कि यह एक मानक बन जाता है, आदि। लेकिन मैं जानता हूं कि ज्यादातर समय, किसी को समझाने से किसी हत्यारा सुविधा के साथ बेहतर काम होता है। तो यह है:

पीडीओ के साथ एक बहुत अच्छी बात यह है कि आप डेटा को एक ऑब्जेक्ट में स्वचालित रूप से इंजेक्ट कर सकते हैं। यदि आप ORM का उपयोग नहीं करना चाहते हैं (क्योंकि यह एक त्वरित स्क्रिप्ट है), लेकिन आप ऑब्जेक्ट मैपिंग पसंद करते हैं, तो यह वास्तव में आसान है:

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
क्या उपरोक्त और के बीच कोई अंतर है $mysqliResult->fetch_object("student");?
एंडी फ्लेमिंग

2
@ ई-सतीस नहीं, मैं PHP का उपयोग करता हूं। सार्वजनिक क्षेत्र इनकैप्सुलेशन का उल्लंघन करते हैं, इसलिए AS A BEST PRACTICEयह सिर्फ ... lol :) Google सार्वजनिक क्षेत्रों का उपयोग नहीं करता है, केवल एक्सेसर्स : google-styleguide.googlecode.com/svn/trunk/…
OZ_

6
@ ई-सिटिस: कूदने के लिए क्षमा करें, लेकिन यदि चरों को बदल दिया जाता है तो क्या होता है, इसे नियंत्रित करने के लिए गेटर्स और सेटर आवश्यक हैं। अन्यथा आप साधारण अपनी वस्तु की आंतरिक स्थिति की गारंटी नहीं दे सकते हैं (यह विशेष रूप से एक मुद्दा है अगर आपके अंदर कोई अन्य वस्तु है)। यह पूरी तरह से स्वतंत्र भाषा है। @OZ_: आसानी से करो। व्यक्तिगत आलोचना केवल किसी और को रक्षात्मक पर रखेगी।
जेम्स पी।

2
@monadic: सहमत। कोर घटकों, या जटिल वस्तुओं, आदि के साथ काम करते समय एनकैप्सुलेशन निश्चित रूप से एक मान्य तर्क है, हालांकि रिकॉर्ड के अभ्यावेदन के रूप में जो अन्यथा पढ़ा-लिखा होगा। arrays, यह स्वीकार्य है। इसके अलावा यह सिस्टम के माध्यम से रिकॉर्ड फ्लोट के रूप में आसान प्रकार की जाँच की अनुमति देता है।
डैन लुग जुग

15
@ मुझे उम्मीद है कि मैं यहां अल्पमत में नहीं हूं, लेकिन मुझे नहीं लगता कि नए डेवलपर्स के प्रति उनकी सुरक्षा पर जवाब देना चाहिए। कठोर लगता है, लेकिन यह सच है। SO पर एक उत्तर का उद्देश्य केवल कॉपी-एंड-पेस्ट कोड प्रदान करना नहीं है, बल्कि समझ प्रदान करना भी है। प्रत्येक सुरक्षा छेद या पैटर्न की खामी को एक उदाहरण में कवर किया गया है, यह सुनिश्चित करने के लिए उत्तरदाता का काम नहीं है, क्योंकि चलो इसका सामना करते हैं, जिस कोड में प्रतिलिपि बनाई जाती है वह उसी कोड का उपयोग करके प्रत्येक अन्य एप्लिकेशन की तुलना में स्वाभाविक रूप से भिन्न होता है।
मत्तगबेग

57

एक डेटाबेस से दूसरे में एप्लिकेशन ले जाना बहुत आम नहीं है, लेकिन जल्द ही या बाद में आप अपने आप को एक अलग RDBMS का उपयोग करके किसी अन्य प्रोजेक्ट पर काम कर सकते हैं। यदि आप पीडीओ के साथ घर पर हैं तो उस बिंदु पर सीखने के लिए कम से कम एक चीज कम होगी।

इसके अलावा मुझे पीडीओ एपीआई थोड़ा अधिक सहज लगता है, और यह वास्तव में ऑब्जेक्ट ओरिएंटेड लगता है। mysqli को लगता है कि यह सिर्फ एक प्रक्रियात्मक एपीआई है जिसे ऑब्जेक्टिफाई किया गया है, यदि आप जानते हैं कि मेरा क्या मतलब है। संक्षेप में, मुझे पीडीओ के साथ काम करना आसान लगता है, लेकिन यह निश्चित रूप से व्यक्तिपरक है।


25

मैंने पीडीओ का उपयोग करना शुरू कर दिया है, क्योंकि मेरी राय में बयान का समर्थन बेहतर है। मैं एक ActiveRecord-esque डेटा-एक्सेस लेयर का उपयोग कर रहा हूं, और गतिशील रूप से जेनरेट किए गए कथनों को लागू करना बहुत आसान है। MySQLi का पैरामीटर बाइंडिंग एक फ़ंक्शन / विधि कॉल में किया जाना चाहिए, इसलिए यदि आप रनटाइम तक नहीं जानते हैं कि आप कितने मापदंडों को बांधना चाहते हैं, तो आप चयन के लिए उपयोग करने के लिए बाध्य हैं call_user_func_array()(मुझे विश्वास है कि सही फ़ंक्शन नाम है) । और सरल गतिशील परिणाम बाध्यकारी के बारे में भूल जाओ।

सबसे अधिक, मुझे पीडीओ पसंद है क्योंकि यह अमूर्तता का एक बहुत ही उचित स्तर है। यह पूरी तरह से अमूर्त प्रणालियों में इसका उपयोग करना आसान है जहां आप एसक्यूएल लिखना नहीं चाहते हैं, लेकिन यह एक और अधिक अनुकूलित, शुद्ध क्वेरी प्रकार की प्रणाली का उपयोग करना या दोनों को मिलाना और मैच करना आसान बनाता है।


2
गतिशील उत्पन्न क्वेरी के साथ परिणाम बंधन संभव है, हम इसे अपने अनुप्रयोगों में करते हैं। हालांकि यह एक बहुत बड़ा दर्द है।
पीम जगर

17

पीडीओ मानक है, यह वही है जो अधिकांश डेवलपर्स उपयोग करने की उम्मीद करेंगे। mysqli अनिवार्य रूप से एक विशेष समस्या का एक समाधान था, लेकिन इसमें अन्य DBMS- विशिष्ट पुस्तकालयों की सभी समस्याएं हैं। पीडीओ वह जगह है जहां सभी कड़ी मेहनत और चतुर सोच जाएंगे।


15

यहाँ कुछ और ध्यान में रखना है: अभी (PHP 5.2) के लिए पीडीओ लाइब्रेरी छोटी गाड़ी है । यह अजीब कीड़े से भरा है। उदाहरण के लिए: PDOStatementएक चर में भंडारण करने से पहले , चर को unset()एक टन बग से बचने के लिए होना चाहिए । इनमें से अधिकांश PHP 5.3 में तय किए गए हैं और वे 2009 की शुरुआत में PHP 5.3 में जारी किए जाएंगे, जिसमें संभवतः कई अन्य कीड़े होंगे। यदि आप समुदाय को मदद करना चाहते हैं, तो आपको PHP 6.1 के लिए PDO का उपयोग करने पर ध्यान केंद्रित करना चाहिए और यदि आप PHP 5.3 के लिए PDO का उपयोग करना चाहते हैं।


2
मुझे लगता है कि पीडीओ द्वारा प्रदान किए जाने वाले लाभ कीड़े के आसपास समझने और काम करने के लायक हैं। PHP अपने आप में बहुत ही आक्रामक कीड़े से भरा है, कुछ जिन्हें हम कुशलता से काम भी नहीं कर सकते हैं, और फिर भी यह कई लाभ प्रदान करता है जो हमें अन्य विकल्पों के बजाय इसका उपयोग करने का कारण बनता है।
ब्रायन वारशॉ

11
उह, अजीब, मुझे पीडीओ के साथ किसी भी बग का अनुभव नहीं हुआ। और मैं इसका भरपूर उपयोग करता हूं।
निकी सी

मैसकली में कीड़े भी हैं। सभी सॉफ्टवेयर में बग हैं।
बिल कारविन

10

पीडीओ के बारे में एक और उल्लेखनीय (अच्छा) अंतर यह है कि यह PDO::quote()विधि स्वचालित रूप से एन्क्लोजिंग कोट्स को जोड़ती है, जबकि mysqli::real_escape_string()(और सिमिलर) नहीं है:

पीडीओ :: उद्धरण () स्थानों में इनपुट स्ट्रिंग के आसपास (यदि आवश्यक हो) और इनपुट स्ट्रिंग के भीतर विशेष वर्णों से बच जाता है, अंतर्निहित ड्राइवर के लिए उपयुक्त उद्धरण शैली का उपयोग करता है।


8

यदि आपकी साइट / वेब एप वास्तव में जा रही है, तो पीडीओ इसे स्केल करना बहुत आसान बना देगा क्योंकि आप डेटाबेस में लोड वितरित करने के लिए मास्टर और गुलाम कनेक्शन को दैनिक रूप से सेट कर सकते हैं, साथ ही PHP एक मानक के रूप में पीडीओ में जाने की ओर अग्रसर है।

पीडीओ जानकारी

एक वेब अनुप्रयोग स्केलिंग


6

निष्पादन की गति के संदर्भ में MySQLi जीतता है, लेकिन जब तक आपके पास MySQLi का उपयोग करने वाला एक अच्छा आवरण नहीं होता है, तब तक तैयार किए गए कथनों से निपटने वाले इसके कार्य भयानक होते हैं।

मेरी अभी भी कीड़े हैं, लेकिन अगर कोई इसे चाहता है, तो यहां है

तो संक्षेप में, यदि आप गति हासिल करने की तलाश में हैं, तो MySQLi; यदि आप उपयोग में आसानी चाहते हैं, तो पी.डी.ओ.


2
गति के अर्थ में, क्या आप बेंचमार्क दे सकते हैं?
जूलियस एफ

8
जोनाथन रॉबसन ने jonathanrobson.me/2010/06/mysqli-vs-pdo-benchmarks पर दोनों की एक अच्छी गति तुलना की है । सारांश: inserts - लगभग बराबर, selects - mysqli ~ 2.5% तेज है गैर-तैयार कथनों के लिए / ~ 6.7% तेजी से तैयार कथनों के लिए। यह देखते हुए कि प्रदर्शन की पेनल्टी कितनी छोटी है, PDOआमतौर पर प्रदर्शन हिट की सुविधाओं और लचीलेपन का उपयोग किया जाता है।
एडम

1
@ अदम मेरे ब्लॉग से लिंक करने के लिए धन्यवाद!
jnrbsn

@ daemonfire300 यह सच है, बेंचमार्क की कोई आवश्यकता नहीं है। PDO mysqli लाइब्रेरी को लपेटता है। मैं शायद प्रशंसक को मार सकता हूं अगर कोई यह साबित कर सकता है कि पीडीओ माइसिकली से तेज है। :
डायन

@jnrbsn क्या आप एडम के साथ सहमत हैं कि उसने क्या कहा?
बासित

5

व्यक्तिगत रूप से मैं पीडीओ का उपयोग करता हूं, लेकिन मुझे लगता है कि यह मुख्य रूप से वरीयता का सवाल है।

पीडीओ में कुछ विशेषताएं हैं जो एसक्यूएल इंजेक्शन ( तैयार किए गए स्टेटमेंट ) को फिर से मदद करती हैं, लेकिन यदि आप अपने एसक्यूएल के साथ सावधान हैं तो आप इसे मायसिकली भी प्राप्त कर सकते हैं।

किसी अन्य डेटाबेस में जाना पीडीओ का उपयोग करने का एक कारण नहीं है। जब तक आप "विशेष SQL सुविधाओं" का उपयोग नहीं करते हैं, तब तक आप एक DB से दूसरे में स्विच कर सकते हैं। हालाँकि, जैसे ही आप "SELECT ... LIMIT 1" उदाहरण के लिए उपयोग करते हैं, तो आप MS-SQL पर नहीं जा सकते जहाँ यह "SELECT TOP ..." है। तो यह वैसे भी समस्याग्रस्त है।


22
MySQLi ने स्टेटमेंट तैयार किए हैं।
टॉवर

5

संपादित उत्तर।

इन दोनों एपीआई के साथ कुछ अनुभव होने के बाद, मैं कहूंगा कि 2 ब्लॉकिंग स्तर की विशेषताएं हैं जो अन्य तैयार किए गए बयानों के साथ mysqli को अनुपयोगी बनाती हैं।
वे पहले से ही 2 उत्कृष्ट (अभी तक जिस तरह से अंडररेटेड) उत्तरों में उल्लिखित थे:

  1. प्लेसहोल्डर्स की मनमानी संख्या के लिए बाध्यकारी मान
  2. डेटा को मात्र सरणी के रूप में लौटाता है

(दोनों ने इस उत्तर में भी उल्लेख किया है )

किसी कारणवश mysqli दोनों के साथ विफल रही।
आजकल इसे दूसरे के लिए कुछ सुधार मिला ( get_result ), लेकिन यह केवल mysqlnd प्रतिष्ठानों पर काम करता है, इसका मतलब है कि आप अपनी स्क्रिप्ट में इस फ़ंक्शन पर भरोसा नहीं कर सकते।

फिर भी इसका आज तक कोई महत्व नहीं है।

इसलिए, केवल एक ही विकल्प है: पीडीओ

अन्य सभी कारण, जैसे कि

  • नामित प्लेसहोल्डर्स (यह सिंटैक्स शुगर ओवररेटेड है)
  • विभिन्न डेटाबेस समर्थन (कोई भी वास्तव में इसका इस्तेमाल नहीं किया)
  • वस्तु में लाना (बस बेकार सिंटैक्स चीनी)
  • गति अंतर (कोई नहीं है)

कोई महत्वपूर्ण महत्व नहीं है।

एक ही समय में इन दोनों एपीआई में कुछ वास्तविक महत्वपूर्ण विशेषताओं का अभाव है , जैसे

  • पहचानकर्ता प्लेसहोल्डर
  • जटिल डेटा प्रकारों के लिए प्लेसहोल्डर गतिशील बाध्यकारी कम toilsome बनाने के लिए
  • कम आवेदन कोड।

इसलिए, वास्तविक जीवन की जरूरतों को पूरा करने के लिए, किसी को अपने स्वयं के अमूर्त पुस्तकालय का निर्माण करना होगा, इन एपीआई में से एक के आधार पर, मैन्युअल रूप से पार्स किए गए प्लेसहोल्डर्स को लागू करना। इस मामले में मैं mysqli को प्राथमिकता दूंगा, क्योंकि इसमें अमूर्तता का स्तर कम है।


अंत में कोई ऐसा व्यक्ति जो जीवन के तथ्यों को जानता है और उसका खंडन नहीं करता है ...
इहसन

4

मेरी बेंचमार्क स्क्रिप्ट में , प्रत्येक विधि का 10000 बार परीक्षण किया जाता है और प्रत्येक विधि के लिए कुल समय का अंतर मुद्रित किया जाता है। आपको अपने स्वयं के कॉन्फ़िगरेशन पर यह करना चाहिए, मुझे यकीन है कि परिणाम अलग-अलग होंगे!

ये मेरे परिणाम हैं:

  • " SELECT NULL" -> PGO()~ 0.35 सेकंड से तेज
  • " SHOW TABLE STATUS" -> mysqli()~ 2.3 सेकंड से अधिक तेज़
  • " SELECT * FROM users" -> mysqli()~ 33 सेकंड से अधिक तेज़

नोट: mysqli के लिए -> fetch_row () का उपयोग करके, कॉलम के नाम सरणी में नहीं जोड़े गए हैं, मुझे ऐसा करने का कोई तरीका नहीं मिला जो PGO में हो। लेकिन यहां तक ​​कि अगर मैं -> fetch_array () का उपयोग करता हूं, तो mysqli थोड़ा धीमा है, लेकिन अभी भी PGO (SELECT NULL को छोड़कर) की तुलना में तेज है।


17
PGO क्या है? और तेजी से 33 सेकंड तक ! मुझे विश्वास है कि बहुत मुश्किल है ...
अलिक्स एक्सल

3

पीडीओ की एक बात यह है कि MySQLi ऐसा नहीं करता है कि मुझे वास्तव में पसंद है पीडीओ एक निर्दिष्ट वर्ग प्रकार (जैसे $pdo->fetchObject('MyClass')) के ऑब्जेक्ट के रूप में परिणाम वापस करने की क्षमता है । MySQLi's fetch_object()केवल एक stdClassऑब्जेक्ट लौटाएगा ।


19
वास्तव में, आप मैन्युअल रूप से एक वर्ग निर्दिष्ट कर सकते हैं: "ऑब्जेक्ट mysqli_result :: fetch_object ([स्ट्रिंग $ class_name [, सरणी $ params]])"। यदि आप कुछ भी निर्दिष्ट नहीं करते हैं तो stdClass का ही उपयोग किया जाता है।
एंड्रियाइड

-4

एक बात का ध्यान रखें।

माईसकली fetch_assoc () फ़ंक्शन का समर्थन नहीं करता है जो कॉलम के नामों का प्रतिनिधित्व करने वाले कुंजी के साथ कॉलम लौटाएगा। बेशक ऐसा करने के लिए अपना स्वयं का फ़ंक्शन लिखना संभव है, यह बहुत लंबा नहीं है, लेकिन मेरे पास इसे लिखने में वास्तव में बहुत कठिन समय था (गैर-विश्वासियों के लिए: यदि यह आपको आसान लगता है, तो इसे अपने समय पर करने की कोशिश करें और डॉन ' टी धोखा :))


4
क्या आपने मैनुअल की कोशिश की? php.net/manual/en/mysqli-result.fetch-assoc.php
तक

2
लंबे समय से पहले लागू हो रहा था, लेकिन हां मैंने मैनुअल जांच की। क्या यह तैयार बयानों के साथ काम करता है? मुझे शक है ...
माइक

2
दरअसल, इसमें आंशिक रूप से आंशिक समर्थन है। आप नियमित प्रश्नों में सरणियाँ प्राप्त कर सकते हैं लेकिन पैरामीट्रिक प्रश्नों में नहीं: -!
अल्वारो गोंजालेज

1
स्पष्ट रूप से गलत होने पर एक उत्तर को क्यों न हटाएं?
माजिद फौलादपुर

2
@MajidFouladpour - उत्तर स्पष्ट रूप से गलत नहीं है । बस कुछ संदर्भ याद आ रहा है। मैसकली सहयोगी सरणी पुनर्प्राप्ति का पूरी तरह से समर्थन नहीं करता है ।
एल्वारो गोंजालेज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.