PHP में mysql_*फ़ंक्शंस का उपयोग क्यों नहीं करना चाहिए?




database (12)

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

उदाहरण के तौर पर, कोई "enhzflep); drop table users"उपयोगकर्ता नाम के रूप में उपयोग कर सकता है । पुराने फ़ंक्शन प्रति क्वेरी एकाधिक कथन निष्पादित करने की अनुमति देंगे, इसलिए उस गंदे बगजर की तरह कुछ पूरी तालिका को हटा सकता है।

अगर कोई mysqli के पीडीओ का उपयोग करना था, तो उपयोगकर्ता नाम समाप्त हो जाएगा "enhzflep); drop table users"

bobby-tables.com देखें ।

तकनीकी कारण क्या हैं कि किसी को mysql_* फ़ंक्शंस का उपयोग क्यों नहीं करना चाहिए? (उदाहरण के लिए mysql_query() , mysql_connect() या mysql_real_escape_string() )?

अगर मैं अपनी साइट पर काम करता हूं तो भी मुझे कुछ और क्यों उपयोग करना चाहिए?

अगर वे मेरी साइट पर काम नहीं करते हैं, तो मुझे त्रुटियां क्यों मिलती हैं

चेतावनी: mysql_connect (): ऐसी कोई फ़ाइल या निर्देशिका नहीं


उपयोग में आसानी

विश्लेषणात्मक और सिंथेटिक कारणों का पहले से ही उल्लेख किया गया था। नए आने वालों के लिए दिनांकित mysql_ फ़ंक्शंस का उपयोग रोकने के लिए एक और महत्वपूर्ण प्रोत्साहन है।

समकालीन डेटाबेस एपीआई का उपयोग करना आसान है।

यह ज्यादातर बाध्य पैरामीटर है जो कोड को सरल बना सकते हैं। और share के साथ PDO में संक्रमण अत्यधिक कठिन नहीं है।

एक बार में एक बड़ा कोड बेस लिखना समय लगता है। इस मध्यवर्ती विकल्प के लिए Raison d'être:

समकक्ष pdo_ * mysql_ के स्थान पर कार्य *

<pdo_mysql.php> का उपयोग करके आप पुराने प्रयासों से पुराने mysql_ फ़ंक्शंस से स्विच कर सकते हैं। यह pdo_ फ़ंक्शन रैपर जोड़ता है जो उनके mysql_ समकक्षों को प्रतिस्थापित करता है।

  1. बस शामिल करें <pdo_mysql.php> include_once( <pdo_mysql.php> ); प्रत्येक आमंत्रण स्क्रिप्ट में जिसे डेटाबेस के साथ बातचीत करना है।

  2. pdo_ फ़ंक्शन उपसर्ग को हर जगह हटाएं और इसे pdo_ साथ pdo_

    • mysql_ connect() pdo_ connect() हो जाता है connect()
    • mysql_ query() pdo_ query() बन जाता है query()
    • mysql_ num_rows() बन जाता है
    • mysql_ insert_id() बन जाता है
    • mysql_ fetch_array() बन जाता है
    • mysql_ pdo_ fetch_assoc() pdo_ fetch_assoc() बन जाता है
    • mysql_ pdo_ real_escape_string() pdo_ real_escape_string() बन जाता है
    • और इसी तरह...

  3. आपका कोड समान रूप से काम करेगा और फिर भी अधिकतर वही दिखाई देगा:

    include_once("pdo_mysql.php"); 
    
    pdo_connect("localhost", "usrABC", "pw1234567");
    pdo_select_db("test");
    
    $result = pdo_query("SELECT title, html FROM pages");  
    
    while ($row = pdo_fetch_assoc($result)) {
        print "$row[title] - $row[html]";
    }
    

और voilà।
आपका कोड पीडीओ का उपयोग कर रहा है
अब वास्तव में इसका उपयोग करने का समय है।

बाउंड पैरामीटर का उपयोग करना आसान हो सकता है

आपको बस कम अनावश्यक एपीआई चाहिए।

pdo_query() बाध्य पैरामीटर के लिए बहुत ही आसान समर्थन जोड़ता है। पुराना कोड कनवर्ट करना सरल है:

अपने चर को SQL स्ट्रिंग से बाहर ले जाएं।

  • उन्हें pdo_query() delimited फ़ंक्शन पैरामीटर के रूप में pdo_query()
  • प्रश्न चिह्न रखें ? प्लेसहोल्डर्स के रूप में जहां चर पहले थे।
  • ' सिंगल कोट्स ' से छुटकारा पाएं जो पहले स्ट्रिंग मान / चर संलग्न हैं।

लंबा कोड के लिए लाभ अधिक स्पष्ट हो जाता है।

अक्सर स्ट्रिंग चर को एसक्यूएल में इंटरपोलेट नहीं किया जाता है, लेकिन बीच में भागने से बचने के साथ संयोजित किया जाता है।

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title='" . pdo_real_escape_string($title) . "' OR id='".
   pdo_real_escape_string($title) . "' AND user <> '" .
   pdo_real_escape_string($root) . "' ORDER BY date")

के साथ ? प्लेसहोल्डर्स ने आपको लागू करने की आवश्यकता नहीं है:

pdo_query("SELECT id, links, html, title, user, date FROM articles
   WHERE title=? OR id=? AND user<>? ORDER BY date", $title, $id, $root)

याद रखें कि pdo_ * अभी भी या तो अनुमति देता है।
बस एक चर से बचें और इसे एक ही प्रश्न में बांधें।

  • प्लेसहोल्डर सुविधा इसके पीछे असली पीडीओ द्वारा प्रदान की जाती है।
  • इस प्रकार भी अनुमति दी गई :named बाद में प्लेसहोल्डर :named सूचीबद्ध।

अधिक महत्वपूर्ण बात यह है कि आप किसी भी क्वेरी के पीछे सुरक्षित रूप से $ _REQUEST [] चर पारित कर सकते हैं। सबमिट किए जाने पर <form> फ़ील्ड डेटाबेस संरचना से मेल खाते हैं, यह बिल्कुल छोटा है:

pdo_query("INSERT INTO pages VALUES (?,?,?,?,?)", $_POST);

बहुत सादगी। लेकिन आइए कुछ और पुनर्लेखन सलाह और तकनीकी कारणों पर वापस आएं कि आप mysql_ से छुटकारा पाने और भागने से क्यों बच सकते हैं।

किसी भी पुरानेस्कूल sanitize() फ़ंक्शन को ठीक या हटा दें

एक बार जब आप सभी mysql_ कॉल को pdo_query में बाध्य pdo_query साथ परिवर्तित कर pdo_query , तो सभी अनावश्यक pdo_real_escape_string कॉल हटा दें।

विशेष रूप से आपको किसी भी रूप में या किसी अन्य रूप में दिनांकित ट्यूटोरियल द्वारा विज्ञापित के रूप में किसी भी sanitize या clean या filterThis को ठीक करना चाहिए या clean_data फ़ंक्शन को ठीक करना चाहिए:

function sanitize($str) {
   return trim(strip_tags(htmlentities(pdo_real_escape_string($str))));
}

यहां सबसे चमकदार बग दस्तावेज़ीकरण की कमी है। अधिक महत्वपूर्ण रूप से फ़िल्टरिंग का क्रम बिल्कुल गलत क्रम में था।

  • सही आदेश होगा: बहिष्कृत रूप से strip_tags रूप से सबसे पहले कॉल के रूप में strip_tags , फिर trim , बाद में strip_tags , आउटपुट संदर्भ के लिए strip_tags , और केवल आखिरकार _escape_string को इसके अनुप्रयोग के रूप में सीधे SQL intersparsing को _escape_string चाहिए।

  • लेकिन पहले चरण के रूप में बस _real_escape_string कॉल से छुटकारा _real_escape_string

  • यदि आपके डेटाबेस और एप्लिकेशन प्रवाह एचटीएमएल-संदर्भ-सुरक्षित तारों की अपेक्षा करते हैं तो आपको अपने शेष sanitize() फ़ंक्शन को अभी भी रखना पड़ सकता है। एक टिप्पणी जोड़ें कि यह केवल एचटीएमएल से बचने पर लागू होता है।

  • स्ट्रिंग / वैल्यू हैंडलिंग को पीडीओ और इसके पैरामीटरयुक्त बयान में सौंपा गया है।

  • यदि आपके sanitize फ़ंक्शन में stripslashes() का कोई उल्लेख था, तो यह उच्च स्तर की निगरानी का संकेत दे सकता है।

    Magic_quotes पर ऐतिहासिक नोट। वह सुविधा सही ढंग से बहिष्कृत है। हालांकि अक्सर गलत सुरक्षा सुविधा के रूप में इसे गलत तरीके से चित्रित किया जाता है। लेकिन जादू_क्वाट्स एक असफल सुरक्षा सुविधा हैं क्योंकि टेनिस गेंद पोषण स्रोत के रूप में विफल रही है। वह बस उनका उद्देश्य नहीं था।

    PHP2 / FI में मूल कार्यान्वयन ने इसे स्पष्ट रूप से प्रस्तुत किया है, " उद्धरण स्वचालित रूप से बच जाएंगे जिससे फ़ॉर्म डेटा सीधे एमएसक्यूएल प्रश्नों को पास करना आसान हो जाएगा "। विशेष रूप से यह mSQL साथ उपयोग करने के लिए mSQL रूप से सुरक्षित था, क्योंकि केवल ASCII समर्थित था।
    फिर PHP3 / Zend ने MySQL के लिए magic_quotes को पुन: प्रस्तुत किया और इसे गलत तरीके से दस्तावेज किया। लेकिन मूल रूप से यह केवल एक सुविधा सुविधा थी , सुरक्षा के लिए इरादा नहीं।

तैयार बयान कैसे भिन्न होते हैं

जब आप एसक्यूएल क्वेरीज में स्ट्रिंग वैरिएबल को स्कैम्बल करते हैं, तो यह आपके लिए अनुसरण करने के लिए और अधिक जटिल नहीं होता है। यह MySQL के लिए कोड और डेटा को फिर से अलग करने के लिए भी अपर्याप्त प्रयास है।

एसक्यूएल इंजेक्शन बस तब होते हैं जब डेटा कोड संदर्भ में खून बहता है। एक डेटाबेस सर्वर बाद में स्पॉट नहीं कर सकता जहां PHP मूल रूप से क्वेरी क्लॉज के बीच चर चिपक गया।

बाध्य पैरामीटर के साथ आप अपने PHP कोड में SQL कोड और SQL-संदर्भ मान अलग करते हैं। लेकिन यह दृश्यों के पीछे फिर से नहीं घूमता है (पीडीओ :: EMULATE_PREPARES को छोड़कर)। आपके डेटाबेस को अनवरोधित SQL कमांड और 1: 1 परिवर्तनीय मान प्राप्त होते हैं।

हालांकि इस जवाब पर जोर दिया गया है कि आपको mysql_ को छोड़ने के पठनीयता के फायदे की परवाह करनी चाहिए। इस दृश्यमान और तकनीकी डेटा / कोड अलगाव के कारण कभी-कभी एक प्रदर्शन लाभ भी होता है (केवल अलग मूल्यों के साथ INSERT को दोहराया जाता है)।

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

हाइब्रिड पीडीओ उपयोग करें

ये pdo_* फ़ंक्शन कोडिंग-अनुकूल स्टॉप-गैप एपीआई बनाते हैं। (यह बहुत कुछ है जो MYSQLI हो सकता था अगर यह idiosyncratic फ़ंक्शन हस्ताक्षर शिफ्ट के लिए नहीं था)। वे ज्यादातर बार वास्तविक पीडीओ का पर्दाफाश करते हैं।
नए pdo_ फ़ंक्शन नामों का उपयोग करने पर पुनर्लेखन को रोकना नहीं है। आप प्रत्येक pdo_query () को एक सादे $ pdo-> तैयार () -> execute () कॉल में एक करके एक संक्रमण कर सकते हैं।

फिर भी सरलीकरण शुरू करना सबसे अच्छा है। उदाहरण के लिए आम परिणाम प्राप्त करना:

$result = pdo_query("SELECT * FROM tbl");
while ($row = pdo_fetch_assoc($result)) {

केवल एक foreach पुनरावृत्ति के साथ प्रतिस्थापित किया जा सकता है:

foreach ($result as $row) {

या बेहतर अभी तक एक सीधी और पूर्ण सरणी पुनर्प्राप्ति:

$result->fetchAll();

अधिकांश मामलों में आपको पीडीओ या mysql_ की तुलना में अधिक उपयोगी चेतावनियां मिलेंगी जो आम तौर पर विफल प्रश्नों के बाद प्रदान करती हैं।

अन्य विकल्प

इसलिए उम्मीद है कि mysql_ को छोड़ने के लिए कुछ व्यावहारिक कारणों और एक मूल्यवान मार्ग की कल्पना की गई है।

बस pdo स्विच करने से काफी कटौती नहीं होती है। pdo_query() भी उस पर एक अग्रभाग है।

जब तक आप पैरामीटर बाध्यकारी भी पेश नहीं करते हैं या nicer एपीआई से कुछ और उपयोग कर सकते हैं, यह एक व्यर्थ स्विच है। मुझे आशा है कि यह नए लोगों को निराशा न करने के लिए पर्याप्त सरल चित्रित किया गया है। (शिक्षा आमतौर पर निषेध से बेहतर काम करती है।)

हालांकि यह सबसे सरल चीज के लिए अर्हता प्राप्त करता है-संभवतः काम कर सकता है, यह अभी भी बहुत प्रयोगात्मक कोड है। मैंने इसे सप्ताहांत में लिखा था। हालांकि विकल्पों में काफी कुछ है।PHP डेटाबेस अबास्ट्रक्शन के लिए बस गूगल और थोड़ा ब्राउज़ करें। इस तरह के कार्यों के लिए हमेशा उत्कृष्ट पुस्तकालयों रहे हैं और होंगे।

यदि आप अपने डेटाबेस इंटरैक्शन को और सरल बनाना चाहते हैं, तो Paris/Idiorm जैसे मैपर एक कोशिश के लायक हैं। जैसे कि कोई भी जावास्क्रिप्ट में ब्लेंड डीओएम का उपयोग नहीं करता है, आपको आजकल कच्चे डेटाबेस इंटरफेस को बेबीसिट करने की ज़रूरत नहीं है।


इस तरह के फ़ंक्शन mysql_connect(), mysql_query()प्रकार पिछले संस्करण PHP यानी (PHP 4) फ़ंक्शंस हैं और अब उपयोग में नहीं हैं।

इन्हें प्रतिस्थापित किया गया है mysqli_connect(), mysqli_query()इसी प्रकार नवीनतम PHP5 में।

त्रुटि के पीछे यही कारण है।


यह उत्तर यह दिखाने के लिए लिखा गया है कि खराब लिखित PHP उपयोगकर्ता-सत्यापन कोड को कैसे बाधित करना है, कैसे (और इसका उपयोग करके) इन हमलों का काम करता है और पुराने MySQL फ़ंक्शंस को एक सुरक्षित तैयार कथन के साथ कैसे बदला जाए - और मूल रूप से, क्यों उपयोगकर्ता (शायद बहुत सारे प्रतिनिधि के साथ) नए उपयोगकर्ताओं पर अपने कोड को बेहतर बनाने के लिए प्रश्न पूछ रहे हैं।

सबसे पहले, कृपया इस परीक्षण mysql डेटाबेस को बनाने के लिए स्वतंत्र महसूस करें (मैंने अपना प्रीपे कहा है):

mysql> create table users(
    -> id int(2) primary key auto_increment,
    -> userid tinytext,
    -> pass tinytext);
Query OK, 0 rows affected (0.05 sec)

mysql> insert into users values(null, 'Fluffeh', 'mypass');
Query OK, 1 row affected (0.04 sec)

mysql> create user 'prepared'@'localhost' identified by 'example';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on prep.* to 'prepared'@'localhost' with grant option;
Query OK, 0 rows affected (0.00 sec)

इसके साथ, हम अपने PHP कोड में जा सकते हैं।

आइए मान लें कि निम्न स्क्रिप्ट किसी वेबसाइट पर किसी व्यवस्थापक के लिए सत्यापन प्रक्रिया है (सरलीकृत है लेकिन अगर आप प्रतिलिपि बनाते हैं और परीक्षण के लिए इसका उपयोग करते हैं तो काम कर रहे हैं):

<?php 

    if(!empty($_POST['user']))
    {
        $user=$_POST['user'];
    }   
    else
    {
        $user='bob';
    }
    if(!empty($_POST['pass']))
    {
        $pass=$_POST['pass'];
    }
    else
    {
        $pass='bob';
    }

    $database='prep';
    $link=mysql_connect('localhost', 'prepared', 'example');
    mysql_select_db($database) or die( "Unable to select database");

    $sql="select id, userid, pass from users where userid='$user' and pass='$pass'";
    //echo $sql."<br><br>";
    $result=mysql_query($sql);
    $isAdmin=false;
    while ($row = mysql_fetch_assoc($result)) {
        echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
        $isAdmin=true;
        // We have correctly matched the Username and Password
        // Lets give this person full access
    }
    if($isAdmin)
    {
        echo "The check passed. We have a verified admin!<br>";
    }
    else
    {
        echo "You could not be verified. Please try again...<br>";
    }
    mysql_close($link);

?>

<form name="exploited" method='post'>
    User: <input type='text' name='user'><br>
    Pass: <input type='text' name='pass'><br>
    <input type='submit'>
</form>

पहली नज़र में पर्याप्त कानूनी लगता है।

उपयोगकर्ता को लॉगिन और पासवर्ड दर्ज करना है, है ना?

शानदार, निम्नलिखित में प्रवेश न करें:

user: bob
pass: somePass

और जमा करें।

आउटपुट निम्नानुसार है:

You could not be verified. Please try again...

सुपर! अपेक्षित कार्य करना, अब वास्तविक उपयोगकर्ता नाम और पासवर्ड आज़माएं:

user: Fluffeh
pass: mypass

गजब का! हाय-फाइव पूरे दौर में, कोड सही ढंग से एक व्यवस्थापक को सत्यापित किया। यह एकदम सही है!

असल में ऐसा नहीं है। आइए कहें कि उपयोगकर्ता एक चालाक छोटा व्यक्ति है। आइए कहें कि वह व्यक्ति है।

निम्नलिखित में दर्ज करें:

user: bob
pass: n' or 1=1 or 'm=m

और आउटपुट है:

The check passed. We have a verified admin!

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

तो, जवाब में, यह है कि आप क्यों पर भरोसा कर रहे हैं।

तो, चलिए देखते हैं कि क्या गलत हुआ, और मैं अभी आपके सुपर-एडमिन-केवल-बैट-गुफा में क्यों गया। मैंने अनुमान लगाया और माना कि आप अपने इनपुट से सावधान नहीं थे और उन्हें सीधे डेटाबेस में पास कर दिया। मैंने इनपुट को एक तरह से बनाया है जो उस क्वेरी को बदल देगा जो आप वास्तव में चल रहे थे। तो, यह क्या होना चाहिए था, और यह क्या खत्म हो गया?

select id, userid, pass from users where userid='$user' and pass='$pass'

यही सवाल है, लेकिन जब हम वास्तविक इनपुट के साथ चर को प्रतिस्थापित करते हैं, तो हम निम्नलिखित प्राप्त करते हैं:

select id, userid, pass from users where userid='bob' and pass='n' or 1=1 or 'm=m'

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

हालांकि, यह आपके बारे में चिल्लाने वाले लोगों के बारे में नहीं है, यह आपको यह दिखाने के बारे में है कि आपका कोड अधिक सुरक्षित कैसे बनाएं।

ठीक है, तो क्या गलत हुआ, और हम इसे कैसे ठीक कर सकते हैं?

यह एक क्लासिक एसक्यूएल इंजेक्शन हमला है। उस मामले के लिए सबसे सरल में से एक। हमले वैक्टर के पैमाने पर, यह एक बच्चा है जो टैंक पर हमला करता है - और जीतता है।

तो, हम आपके पवित्र व्यवस्थापक अनुभाग की रक्षा कैसे करते हैं और इसे अच्छा और सुरक्षित बनाते हैं? करने वाली पहली चीज़ उन पुराने और बहिष्कृत mysql_*कार्यों का उपयोग करना बंद कर देगी । मुझे पता है, आपने ऑनलाइन पाया एक ट्यूटोरियल का पालन किया और यह काम करता है, लेकिन यह पुराना है, यह पुराना है और कुछ ही मिनटों की जगह में, मैंने पसीने को तोड़ने के बिना इसे तोड़ दिया है।

अब, आपके पास mysqli_ या PDO का उपयोग करने के बेहतर विकल्प हैं । मैं व्यक्तिगत रूप से पीडीओ का बड़ा प्रशंसक हूं, इसलिए मैं इस उत्तर के बाकी हिस्सों में पीडीओ का उपयोग करूँगा। प्रो और कॉन हैं, लेकिन व्यक्तिगत रूप से मुझे लगता है कि समर्थक कॉन के काफी दूर है। यह एकाधिक डेटाबेस इंजनों में पोर्टेबल है - चाहे आप MySQL या Oracle या केवल खूनी कुछ भी उपयोग कर रहे हों - बस कनेक्शन स्ट्रिंग को बदलकर, इसमें सभी फैंसी फीचर्स हैं जिनका हम उपयोग करना चाहते हैं और यह अच्छा और साफ है। मुझे साफ पसंद है।

अब, इस कोड को फिर से देखें, इस बार पीडीओ ऑब्जेक्ट का उपयोग करके लिखा गया है:

<?php 

    if(!empty($_POST['user']))
    {
        $user=$_POST['user'];
    }   
    else
    {
        $user='bob';
    }
    if(!empty($_POST['pass']))
    {
        $pass=$_POST['pass'];
    }
    else
    {
        $pass='bob';
    }
    $isAdmin=false;

    $database='prep';
    $pdo=new PDO ('mysql:host=localhost;dbname=prep', 'prepared', 'example');
    $sql="select id, userid, pass from users where userid=:user and pass=:password";
    $myPDO = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    if($myPDO->execute(array(':user' => $user, ':password' => $pass)))
    {
        while($row=$myPDO->fetch(PDO::FETCH_ASSOC))
        {
            echo "My id is ".$row['id']." and my username is ".$row['userid']." and lastly, my password is ".$row['pass']."<br>";
            $isAdmin=true;
            // We have correctly matched the Username and Password
            // Lets give this person full access
        }
    }

    if($isAdmin)
    {
        echo "The check passed. We have a verified admin!<br>";
    }
    else
    {
        echo "You could not be verified. Please try again...<br>";
    }

?>

<form name="exploited" method='post'>
    User: <input type='text' name='user'><br>
    Pass: <input type='text' name='pass'><br>
    <input type='submit'>
</form>

प्रमुख अंतर यह है कि कोई और mysql_*कार्य नहीं है। यह सब पीडीओ ऑब्जेक्ट के माध्यम से किया जाता है, दूसरी बात, यह एक तैयार कथन का उपयोग कर रहा है। अब, एक प्रीपेड कथन क्या है जो आप पूछते हैं? क्वेरी चलाने से पहले डेटाबेस को बताने का यह एक तरीका है, सवाल यह है कि हम दौड़ने जा रहे हैं। इस मामले में, हम डेटाबेस को बताते हैं: "हाय, मैं आईडी, उपयोगकर्ता आईडी चाहते हैं और तालिका उपयोगकर्ताओं से पास एक चुनिंदा बयान चलाने जा रहा हूं जहां उपयोगकर्ता आईडी एक चर है और पास भी एक चर है।"

फिर, निष्पादित कथन में, हम डेटाबेस को उन सभी चर के साथ एक सरणी पास करते हैं, जिसे अब उम्मीद है।

परिणाम शानदार हैं। आइए पहले से उन उपयोगकर्ता नाम और पासवर्ड संयोजनों को आज़माएं:

user: bob
pass: somePass

उपयोगकर्ता सत्यापित नहीं किया गया था। बहुत बढ़िया।

कैसा रहेगा:

user: Fluffeh
pass: mypass

ओह, मैं बस थोड़ा उत्साहित हो गया, यह काम किया: चेक पास हो गया। हमारे पास एक सत्यापित व्यवस्थापक है!

अब, डेटा को आज़माएं कि एक चालाक चैप हमारे छोटे सत्यापन प्रणाली को पाने की कोशिश करने के लिए प्रवेश करेगा:

user: bob
pass: n' or 1=1 or 'm=m

इस बार, हम निम्नलिखित प्राप्त करते हैं:

You could not be verified. Please try again...

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

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


सबसे पहले, हम मानक टिप्पणी से शुरू करते हैं जो हम सभी को देते हैं:

share । वे अब बनाए रखा नहीं है deprecatedलाल बॉक्स देखें? इसके बजाय तैयार बयानों के बारे में जानें, और PDO या MySQLi उपयोग करें - यह आलेख आपको यह तय करने में मदद करेगा कि कौन सा है। यदि आप पीडीओ चुनते हैं, तो यहां एक अच्छा ट्यूटोरियल है

आइए इसके माध्यम से, वाक्य द्वारा वाक्य, और समझाओ:

  • वे अब बनाए रखा नहीं है, और आधिकारिक तौर पर बहिष्कृत हैं

    इसका मतलब यह है कि PHP समुदाय धीरे-धीरे इन पुराने कार्यों के लिए समर्थन छोड़ रहा है। वे PHP के भविष्य (हालिया) संस्करण में मौजूद नहीं होने की संभावना है! इन कार्यों का निरंतर उपयोग आपके कोड को (भविष्य में) भविष्य में तोड़ सकता है।

    नया! - ext / mysql अब deprecated

    नई! ext / mysql को PHP 7 में हटा दिया गया है

  • इसके बजाय, आपको तैयार बयान के बारे में सीखना चाहिए

    mysql_* एक्सटेंशन तैयार कथन का समर्थन नहीं करता है, जो (अन्य चीजों के साथ) एसक्यूएल इंजेक्शन के खिलाफ एक बहुत ही प्रभावी countermeasure है। यह MySQL आश्रित अनुप्रयोगों में एक बहुत ही गंभीर भेद्यता तय करता है जो हमलावरों को आपकी स्क्रिप्ट तक पहुंच प्राप्त करने और आपके डेटाबेस पर कोई भी संभावित क्वेरी करने की अनुमति देता है।

    अधिक जानकारी के लिए, मैं PHP में एसक्यूएल इंजेक्शन को कैसे रोक सकता हूं?

  • लाल बॉक्स देखें?

    जब आप किसी भी mysql फ़ंक्शन मैन्युअल पृष्ठ पर जाते हैं, तो आप एक लाल बॉक्स देखते हैं, यह समझाते हुए कि इसका अब और उपयोग नहीं किया जाना चाहिए।

  • या तो पीडीओ या MySQLi का प्रयोग करें

    बेहतर, अधिक मजबूत और अच्छी तरह से निर्मित विकल्प हैं, PDO , जो डेटाबेस इंटरैक्शन के लिए एक पूर्ण ओओपी दृष्टिकोण प्रदान करता है, और MySQLi , जो एक MySQL विशिष्ट सुधार है।


MySQL एक्सटेंशन:

  • सक्रिय विकास के तहत नहीं है
  • आधिकारिक तौर पर PHP 5.5 (जून 2013 को जारी) के रूप में deprecated किया deprecated
  • पूरी तरह से PHP 7.0 के रूप में removed गया removed (दिसंबर 2015 जारी)
    • इसका मतलब है कि 31 दिसंबर 2018 तक यह PHP के किसी भी समर्थित संस्करण में मौजूद नहीं होगा। वर्तमान में, यह केवल सुरक्षा अद्यतन प्राप्त करता है।
  • एक ओओ इंटरफेस लाता है
  • समर्थन नहीं करता है:
    • गैर-अवरुद्ध, असीमित प्रश्न
    • तैयार बयान या पैरामीटरयुक्त प्रश्न
    • संग्रहित प्रक्रियाएं
    • एकाधिक वक्तव्य
    • लेन-देन
    • "नया" पासवर्ड प्रमाणीकरण विधि (डिफ़ॉल्ट रूप से MySQL 5.6 में; 5.7 में आवश्यक)
    • MySQL 5.1 में सभी कार्यक्षमता

चूंकि इसे बहिष्कृत किया गया है, इसका उपयोग करके आपका कोड कम भविष्य का प्रमाण बनाता है।

तैयार बयानों के लिए समर्थन की कमी विशेष रूप से महत्वपूर्ण है क्योंकि वे अलग-अलग फ़ंक्शन कॉल से मैन्युअल रूप से भागने की तुलना में बाहरी डेटा से बचने और उद्धृत करने की एक स्पष्ट, कम त्रुटि-प्रवण विधि प्रदान करते हैं।

एसक्यूएल एक्सटेंशन की तुलना देखें।


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

mysql_*फ़ंक्शंस का उपयोग करते समय, आपको उपयोगकर्ता द्वारा आपूर्ति किए गए पैरामीटर को चलाने के लिए याद रखना होगा mysql_real_escape_string()। यदि आप केवल एक ही स्थान में भूल जाते हैं या यदि आप इनपुट के केवल भाग से बचने के लिए होते हैं, तो आपका डेटाबेस हमले के अधीन हो सकता है।

तैयार कथन का उपयोग करना PDOया mysqliइसे बनाना होगा ताकि प्रोग्रामिंग त्रुटियों के इन प्रकारों को और अधिक कठिन बना दिया जा सके।


mysql_कार्य:

  1. पुराने हैं - वे अब और बनाए रखा नहीं जा रहे हैं
  2. आपको किसी अन्य डेटाबेस बैकएंड में आसानी से स्थानांतरित करने की अनुमति न दें
  3. इसलिए तैयार बयान का समर्थन न करें
  4. प्रोग्रामर को प्रश्न बनाने के लिए concatenation का उपयोग करने के लिए प्रोत्साहित करते हैं, जिससे एसक्यूएल इंजेक्शन भेद्यताएं होती हैं

mysql_ * कार्यों को बहिष्कृत किया गया था ( PHP 5.5 के रूप में ) इस तथ्य को देखते हुए कि बेहतर कार्य और कोड संरचनाएं विकसित की गई थीं। तथ्य यह है कि समारोह को बहिष्कृत किया गया था इसका मतलब है कि प्रदर्शन और सुरक्षा के मामले में इसे सुधारने के लिए कोई और प्रयास नहीं किया जाएगा, जिसका अर्थ है कि यह भविष्य का सबूत है

यदि आपको और कारणों की आवश्यकता है:

  • mysql_ * फ़ंक्शंस तैयार कथन का समर्थन नहीं करते हैं।
  • mysql_ * फ़ंक्शन पैरामीटर के बाध्यकारी का समर्थन नहीं करते हैं।
  • mysql_ * कार्यों में ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के लिए कार्यक्षमता की कमी है।
  • सूची चलती जाती है ...

मुझे उपर्युक्त उत्तर वास्तव में लंबा लगता है, इसलिए संक्षेप में:

MySQL एक्सटेंशन में कई लाभ हैं, MySQL एक्सटेंशन पर महत्वपूर्ण वृद्धिएं हैं:

  • ऑब्जेक्ट उन्मुख इंटरफ़ेस
  • तैयार वक्तव्य के लिए समर्थन
  • एकाधिक वक्तव्यों के लिए समर्थन
  • लेनदेन के लिए समर्थन
  • उन्नत डीबगिंग क्षमताओं
  • एम्बेडेड सर्वर समर्थन

स्रोत: MySQLi सिंहावलोकन

जैसा कि उपरोक्त उत्तरों में बताया गया है, mysql के विकल्प mysqli और पीडीओ (PHP डेटा ऑब्जेक्ट्स) हैं।

  • एपीआई सर्वर-साइड तैयार वक्तव्य का समर्थन करता है: MYSQLi और पीडीओ द्वारा समर्थित
  • एपीआई क्लाइंट-साइड तैयार वक्तव्य का समर्थन करता है: केवल पीडीओ द्वारा समर्थित
  • एपीआई संग्रहीत प्रक्रियाओं का समर्थन करता है: MySQLi और पीडीओ दोनों
  • एपीआई एकाधिक वक्तव्यों और सभी MySQL 4.1+ कार्यक्षमता का समर्थन करता है - MySQLi द्वारा समर्थित और ज्यादातर पीडीओ द्वारा भी

MySQLi और PDO दोनों को PHP 5.0 में पेश किया गया था, जबकि MySQL को PHP 3.0 से पहले पेश किया गया था। ध्यान देने योग्य बिंदु यह है कि MySQL को PHP5.x में शामिल किया गया है हालांकि बाद के संस्करणों में बहिष्कृत किया गया है।


mysql_*Mysqli या पीडीओ का उपयोग कर लगभग सभी कार्यों को परिभाषित करना संभव है । बस उन्हें अपने पुराने PHP एप्लिकेशन के शीर्ष पर शामिल करें, और यह PHP7 पर काम करेगा। मेरा समाधान here

<?php

define('MYSQL_LINK', 'dbl');
$GLOBALS[MYSQL_LINK] = null;

function mysql_link($link=null) {
    return ($link === null) ? $GLOBALS[MYSQL_LINK] : $link;
}

function mysql_connect($host, $user, $pass) {
    $GLOBALS[MYSQL_LINK] = mysqli_connect($host, $user, $pass);
    return $GLOBALS[MYSQL_LINK];
}

function mysql_pconnect($host, $user, $pass) {
    return mysql_connect($host, $user, $pass);
}

function mysql_select_db($db, $link=null) {
    $link = mysql_link($link);
    return mysqli_select_db($link, $db);
}

function mysql_close($link=null) {
    $link = mysql_link($link);
    return mysqli_close($link);
}

function mysql_error($link=null) {
    $link = mysql_link($link);
    return mysqli_error($link);
}

function mysql_errno($link=null) {
    $link = mysql_link($link);
    return mysqli_errno($link);
}

function mysql_ping($link=null) {
    $link = mysql_link($link);
    return mysqli_ping($link);
}

function mysql_stat($link=null) {
    $link = mysql_link($link);
    return mysqli_stat($link);
}

function mysql_affected_rows($link=null) {
    $link = mysql_link($link);
    return mysqli_affected_rows($link);
}

function mysql_client_encoding($link=null) {
    $link = mysql_link($link);
    return mysqli_character_set_name($link);
}

function mysql_thread_id($link=null) {
    $link = mysql_link($link);
    return mysqli_thread_id($link);
}

function mysql_escape_string($string) {
    return mysql_real_escape_string($string);
}

function mysql_real_escape_string($string, $link=null) {
    $link = mysql_link($link);
    return mysqli_real_escape_string($link, $string);
}

function mysql_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql);
}

function mysql_unbuffered_query($sql, $link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, $sql, MYSQLI_USE_RESULT);
}

function mysql_set_charset($charset, $link=null){
    $link = mysql_link($link);
    return mysqli_set_charset($link, $charset);
}

function mysql_get_host_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_host_info($link);
}

function mysql_get_proto_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_proto_info($link);
}
function mysql_get_server_info($link=null) {
    $link = mysql_link($link);
    return mysqli_get_server_info($link);
}

function mysql_info($link=null) {
    $link = mysql_link($link);
    return mysqli_info($link);
}

function mysql_get_client_info() {
    $link = mysql_link();
    return mysqli_get_client_info($link);
}

function mysql_create_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "CREATE DATABASE `$db`");
}

function mysql_drop_db($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "DROP DATABASE `$db`");
}

function mysql_list_dbs($link=null) {
    $link = mysql_link($link);
    return mysqli_query($link, "SHOW DATABASES");
}

function mysql_list_fields($db, $table, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    $table = str_replace('`', '', mysqli_real_escape_string($link, $table));
    return mysqli_query($link, "SHOW COLUMNS FROM `$db`.`$table`");
}

function mysql_list_tables($db, $link=null) {
    $link = mysql_link($link);
    $db = str_replace('`', '', mysqli_real_escape_string($link, $db));
    return mysqli_query($link, "SHOW TABLES FROM `$db`");
}

function mysql_db_query($db, $sql, $link=null) {
    $link = mysql_link($link);
    mysqli_select_db($link, $db);
    return mysqli_query($link, $sql);
}

function mysql_fetch_row($qlink) {
    return mysqli_fetch_row($qlink);
}

function mysql_fetch_assoc($qlink) {
    return mysqli_fetch_assoc($qlink);
}

function mysql_fetch_array($qlink, $result=MYSQLI_BOTH) {
    return mysqli_fetch_array($qlink, $result);
}

function mysql_fetch_lengths($qlink) {
    return mysqli_fetch_lengths($qlink);
}

function mysql_insert_id($qlink) {
    return mysqli_insert_id($qlink);
}

function mysql_num_rows($qlink) {
    return mysqli_num_rows($qlink);
}

function mysql_num_fields($qlink) {
    return mysqli_num_fields($qlink);
}

function mysql_data_seek($qlink, $row) {
    return mysqli_data_seek($qlink, $row);
}

function mysql_field_seek($qlink, $offset) {
    return mysqli_field_seek($qlink, $offset);
}

function mysql_fetch_object($qlink, $class="stdClass", array $params=null) {
    return ($params === null)
        ? mysqli_fetch_object($qlink, $class)
        : mysqli_fetch_object($qlink, $class, $params);
}

function mysql_db_name($qlink, $row, $field='Database') {
    mysqli_data_seek($qlink, $row);
    $db = mysqli_fetch_assoc($qlink);
    return $db[$field];
}

function mysql_fetch_field($qlink, $offset=null) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    return mysqli_fetch_field($qlink);
}

function mysql_result($qlink, $offset, $field=0) {
    if ($offset !== null)
        mysqli_field_seek($qlink, $offset);
    $row = mysqli_fetch_array($qlink);
    return (!is_array($row) || !isset($row[$field]))
        ? false
        : $row[$field];
}

function mysql_field_len($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->length : false;
}

function mysql_field_name($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgname) ? $field->name : $field->orgname;
}

function mysql_field_table($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    if (!is_object($field))
        return false;
    return empty($field->orgtable) ? $field->table : $field->orgtable;
}

function mysql_field_type($qlink, $offset) {
    $field = mysqli_fetch_field_direct($qlink, $offset);
    return is_object($field) ? $field->type : false;
}

function mysql_free_result($qlink) {
    try {
        mysqli_free_result($qlink);
    } catch (Exception $e) {
        return false;
    }
    return true;
}

MySQL एक्सटेंशन तीन में से सबसे पुराना है और मूल तरीका था कि डेवलपर MySQL के साथ संवाद करने के लिए उपयोग करते थे। PHP और MySQL दोनों की नई रिलीज़ में किए गए सुधारों के कारण अब यह एक्सटेंशन अन्य mysqli_PDO पक्ष में deprecated किया जा रहा है ।mysqli_ PDO

  • mysqli_ MySQL डेटाबेस के साथ काम करने के लिए 'बेहतर' एक्सटेंशन है। यह उन सुविधाओं का लाभ उठाता है जो MySQL सर्वर के नए संस्करणों में उपलब्ध हैं, डेवलपर को फ़ंक्शन-ओरिएंटेड और ऑब्जेक्ट-ओरिएंटेड इंटरफ़ेस दोनों का खुलासा करता है और कुछ अन्य निफ्टी चीजें करता है।

  • PDO एक एपीआई प्रदान करता है जो अधिकांश कार्यक्षमता को समेकित करता है जो पहले बड़े डेटाबेस एक्सेस एक्सटेंशन, यानी MySQL, PostgreSQL, SQLite, MSSQL, आदि में फैल गया था। इंटरफ़ेस प्रोग्रामर के लिए डेटाबेस कनेक्शन, प्रश्नों के साथ काम करने के लिए उच्च स्तरीय ऑब्जेक्ट्स का खुलासा करता है। परिणाम सेट, और निम्न-स्तरीय ड्राइवर डेटाबेस सर्वर के साथ संचार और संसाधन हैंडलिंग करते हैं। पीडीओ में बहुत सी चर्चा और काम चल रहा है और इसे आधुनिक, पेशेवर कोड में डेटाबेस के साथ काम करने का उचित तरीका माना जाता है।





database