شرح - w3school php insert mysql




لماذا لا يمكنني استخدام وظائف mysql_*في PHP؟ (10)

سهولة الاستعمال

وقد ذكر بالفعل الأسباب التحليلية والاصطناعية. للوافدين الجدد هناك حافز أكثر أهمية لوقف استخدام وظائف mysql_ مؤرخة.

APIs قاعدة البيانات المعاصرة هي فقط أسهل للاستخدام.

إنها في الغالب المعلمات المرتبطة التي يمكن أن تبسط التعليمات البرمجية. ومع share فإن الانتقال إلى الشركة ليس أمرًا شاقًا للغاية.

ومع ذلك ، فإن إعادة كتابة رمز الكود الأكبر دفعة واحدة يستغرق وقتًا. سبب وجود لهذا البديل وسيطة:

وظائف pdo_ * المكافئة بدلاً من mysql_ *

باستخدام <pdo_mysql.php> يمكنك التبديل من وظائف mysql_ القديمة بأقل جهد . يضيف pdo_ الدالة wrappers التي تحل محل نظائر mysql_ الخاصة بهم.

  1. ببساطة include_once( <pdo_mysql.php> ); في كل نص برمجي استفزازي يتفاعل مع قاعدة البيانات.

  2. قم بإزالة بادئة وظيفة mysql_ كل مكان pdo_ بـ pdo_ .

    • mysql_ connect() يصبح pdo_ connect()
    • يصبح mysql_ query() pdo_ query()
    • mysql_ num_rows() يصبح pdo_ num_rows()
    • mysql_ insert_id() يصبح pdo_ insert_id()
    • mysql_ fetch_array() يصبح pdo_ fetch_array()
    • mysql_ fetch_assoc() يصبح pdo_ fetch_assoc()
    • mysql_ 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]";
    }
    

Et voilà.
كودك يستخدم PDO.
الآن حان الوقت لاستخدامها بالفعل.

يمكن أن تكون المعلمات المقيدة سهلة الاستخدام

أنت فقط بحاجة إلى واجهة برمجة تطبيقات أقل ثباتًا.

يضيف pdo_query() دعم سهل جدًا للمعلمات المربوطة. تحويل رمز قديم بسيط:

نقل المتغيرات الخاصة بك خارج سلسلة SQL.

  • pdo_query() كمعلمات الدالة الفاصلة محددة إلى pdo_query() .
  • ضع علامات استفهام ? كعناصر نائبة حيث كانت المتغيرات من قبل.
  • تخلص من ' علامات الاقتباس المفردة التي كانت متضمنة في السابق قيم / متغيرات السلسلة.

تصبح الميزة أكثر وضوحًا للشفرة الطويلة.

غالبًا لا يتم تقريبًا متغيرات السلسلة فقط إلى SQL ، ولكن متسلسلة مع مكالمات الهروب بينهما.

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_ * لا يزال يسمح إما أو .
فقط لا تهرب من متغير وتربطه في نفس الاستعلام.

  • يتم توفير الميزة النائب بواسطة PDO الحقيقي خلفها.
  • هكذا سمح أيضا :named القوائم المؤقتة في وقت لاحق.

الأهم من ذلك يمكنك تمرير $ _REQUEST [] المتغيرات بأمان خلف أي استعلام. عندما تتطابق حقول <form> تقديمها مع بنية قاعدة البيانات بالضبط ، فإنها تكون أقصر:

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

الكثير من البساطة. ولكن دعونا نعود إلى بعض أكثر من إعادة كتابة المشورة والأسباب التقنية لماذا قد ترغب في التخلص من mysql_ والهروب.

إصلاح أو إزالة أي وظيفة sanitize() oldschool

بمجرد أن تقوم بتحويل كافة المكالمات mysql_ إلى pdo_query مع params المنضمة ، قم بإزالة كافة مكالمات pdo_real_escape_string .

على وجه الخصوص ، يجب أن تقوم بإصلاح أي sanitize أو clean أو clean_data أو وظائف clean_data كما هو معلن من قبل برامج تعليمية clean_data في نموذج واحد أو آخر:

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

معظم الأخطاء الصارخة هنا هي عدم وجود وثائق. الأهم من ذلك أن ترتيب التصفية كان بالضبط في الترتيب الخطأ.

  • قد يكون الترتيب الصحيح: stripslashes أعمق ، ثم يتم strip_tags بعد ذلك ، strip_tags ، strip_tags لسياق الإخراج ، وأخيراً فقط _escape_string يجب أن _escape_string مباشرة intersparsing SQL.

  • ولكن كخطوة أولى فقط تخلص من استدعاء _real_escape_string .

  • قد تضطر إلى الاحتفاظ بباقي وظيفة sanitize() في الوقت الحالي إذا كنت تتوقع أن تتدفق قاعدة البيانات الخاصة بك وتدفق التطبيقات السلاسل المضمنة في سياق HTML. أضف تعليقًا يفيد أنه لا ينطبق إلا على HTML الذي يهرب من الآن فصاعدًا.

  • يتم تفويض مناولة السلسلة / القيمة لشركة تنمية نفط عمان والعبارات ذات المعلمات.

  • إذا كان هناك أي ذكر لـ stripslashes() في وظيفة التعقيم ، فقد يشير ذلك إلى مستوى أعلى من الإشراف.

    ملاحظة تاريخية على magic_quotes. يتم إيقاف هذه الميزة عن حق. غالبًا ما يتم تصويره بشكل خاطئ على أنه ميزة أمان فاشلة. لكن magic_quotes هي ميزة أمنية فاشلة بقدر فشل كرات التنس كمصدر للتغذية. هذا ببساطة لم يكن هدفهم.

    التطبيق الأصلي في PHP2 / FI قدمه بشكل صريح مع " علامات الاقتباس " فقط سوف يتم إهمالها تلقائيًا مما يسهل تمرير بيانات النموذج مباشرة إلى استعلامات msql ". وتجدر الإشارة إلى أنه كان آمنًا بشكل آمن للاستخدام مع mSQL ، لأن ذلك يدعم ASCII فقط.
    ثم أعد PHP3 / Zend إعادة صياغة magic_quotes لـ MySQL وأخطأ في تفسيره. ولكن في الأصل كانت مجرد ميزة ملائمة ، لا تنوي الأمن.

كيف تختلف البيانات المعدة

عندما تتقلب على متغيرات السلسلة في استعلامات SQL ، لا تصبح أكثر تعقيدًا لتتبعها. انها أيضا محاولة غريبة ل MySQL لعزل الكود والبيانات مرة أخرى.

حقنات SQL هي ببساطة عندما ينزف البيانات في سياق التعليمات البرمجية . يتعذر على خادم قاعدة البيانات بعد ذلك تحديد مكان لصق PHP للمتغيرات في الأصل بين عبارات الاستعلام.

باستخدام المعلمات المُغلقة ، يمكنك فصل شفرة SQL وقيم سياق SQL في شفرة PHP الخاصة بك. ولكن لا يتم تبديلها مرة أخرى خلف الكواليس (باستثناء PDO :: EMULATE_PREPARES). يتلقى قاعدة البيانات الخاصة بك أوامر SQL غير منسقة وقيم متغير 1: 1.

بينما تؤكد هذه الإجابة على أنه يجب أن تهتم بمزايا إمكانية القراءة الخاصة بإسقاط mysql_ . هناك أحيانًا ميزة أداء (تكرار INSERTs بقيم مختلفة فقط) بسبب فصل البيانات / الشفرة المرئي والفني.

احترس من أن ربط المعلمة لا يزال ليس حلًا سحريًا وقويًا ضد جميع عمليات حقن SQL. يتعامل مع الاستخدام الأكثر شيوعًا للبيانات / القيم. ولكن لا يمكن تحديد معرّفات اسم الجدول / القائمة البيضاء ، أو المساعدة في إنشاء جملة ديناميكية ، أو قوائم قيم الصفيف البسيطة فقط.

استخدام PDO الهجين

pdo_* هذه pdo_* واجهة برمجة تطبيقات لإيقاف التشغيل. (إلى حد كبير ما MYSQLI يمكن أن يكون MYSQLI لو لم يكن MYSQLI التوقيع الدالة MYSQLI ). كما أنهم يعرضون PDO الحقيقية في معظم الأوقات.
إعادة الكتابة لا يجب أن تتوقف عند استخدام أسماء الدوال pdo_ الجديدة. يمكنك تحويل واحد كل واحد pdo_query () إلى pd $ عادي -> تحضير () -> تنفيذ () المكالمة.

من الأفضل البدء في التبسيط مرة أخرى. على سبيل المثال ، جلب النتيجة الشائعة:

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

يمكن الاستعاضة عنها بتكرار foreach:

foreach ($result as $row) {

أو الأفضل بعد استرجاع مجموعة مباشرة وكاملة:

$result->fetchAll();

ستحصل على تحذيرات أكثر فائدة في معظم الحالات من PDO أو mysql_ عادة ما تقدم بعد الاستعلامات الفاشلة.

خيارات أخرى

لذلك هذا الأمل تصور بعض الأسباب العملية ومسار يستحق أن يسقط mysql_ .

مجرد التبديل إلى pdo لا pdo تماما. pdo_query() هو أيضا مجرد واجهة على ذلك.

ما لم تقدم أيضًا ربطًا للمعلمات أو يمكنك استخدام شيء آخر من واجهة برمجة تطبيقات أفضل ، فهو مفتاح لا طائل من ورائه. آمل أن يتم تصويره بشكل بسيط بما فيه الكفاية لعدم زيادة الإحباط للوافدين الجدد. (التعليم عادة ما يعمل بشكل أفضل من الحظر).

في حين أنها تتأهل لفئة أبسط الأشياء التي قد تكون قادرة على العمل ، فإنها لا تزال أيضًا مدونة تجريبية جدًا. أنا فقط كتبت ذلك في عطلة نهاية الأسبوع. هناك عدد كبير من البدائل. مجرد جوجل للحصول على تجريد قاعدة بيانات PHP وتصفح قليلا. هناك دائما وستكون هناك الكثير من المكتبات الممتازة لمثل هذه المهام.

إذا كنت تريد تبسيط تفاعل قاعدة البيانات بشكل أكبر ، Paris/Idiorm مثل Paris/Idiorm . تمامًا كما لم يعد أحد يستخدم DOM اللامع في جافا سكريبت ، لم تعد بحاجة إلى واجهة قاعدة بيانات أولية في الوقت الحاضر.

ما هي الأسباب الفنية لماذا لا يجب استخدام وظائف mysql_* ؟ (مثل mysql_query() أو mysql_connect() أو mysql_real_escape_string()

لماذا يجب علي استخدام شيء آخر حتى إذا كان يعمل على موقعي؟

إذا لم يعملوا على موقعي ، فلماذا أواجه أخطاء مثل

تحذير: mysql_connect (): لا يوجد ملف أو دليل


أولاً ، لنبدأ بالتعليق القياسي الذي نقدمه للجميع:

share . لم يعد يتم الاحتفاظ deprecated . انظر المربع الأحمر ؟ تعرف على البيانات المعدة بدلاً من ذلك ، واستخدم PDO أو MySQLi - MySQLi هذه المقالة في تحديد أي منها. إذا اخترت شركة تنمية نفط عمان ، فهنا برنامج تعليمي جيد .

دعونا نذهب من خلال هذه الجملة ، جملة ، ونوضح:

  • لم يعد يتم الاحتفاظ بها ، ويتم إيقافها رسميًا

    هذا يعني أن مجتمع PHP يتخلى تدريجيا عن دعم هذه الوظائف القديمة جدا. من المرجح أن لا تكون موجودة في إصدار (PHP) في المستقبل (الأخيرة)! استمرار استخدام هذه الوظائف قد يكسر التعليمات البرمجية الخاصة بك في المستقبل البعيد (ليس كذلك).

    الجديد! - ext / mysql الآن deprecated

    أحدث! ext / mysql تمت إزالته في PHP 7 .

  • بدلا من ذلك ، يجب عليك معرفة البيانات المعدة

    لا يدعم الملحق mysql_* البيانات المعدة ، وهي (من بين أشياء أخرى) مضاد فعال ضد حقن SQL . انها ثبات خطير للغاية في التطبيقات التي تعتمد على MySQL والتي تسمح للمهاجمين للوصول إلى البرنامج النصي الخاص بك وتنفيذ أي استفسار ممكن على قاعدة البيانات الخاصة بك.

    لمزيد من المعلومات ، راجع كيف يمكنني منع إدخال SQL في PHP؟

  • انظر الصندوق الأحمر؟

    عندما تذهب إلى أي صفحة دليل الدالة mysql ، سترى مربع أحمر ، موضحا أنه لا ينبغي أن تستخدم بعد الآن.

  • استخدم إما PDO أو MySQLi

    هناك بدائل أفضل وأكثر قوة وجيدة البناء ، PDO ، الذي يقدم نهج OOP كامل لتفاعل قاعدة البيانات ، و MySQLi ، وهو تحسين محدد في MySQL.


ملحق MySQL:

  • ليس تحت التطوير النشط
  • يتم deprecated رسميًا اعتبارًا من 5.5 بيزو فلبيني (تم إصداره في يونيو 2013).
  • تمت removed تمامًا بدءًا من PHP 7.0 (تم إصداره في كانون الأول 2015)
    • وهذا يعني أنه اعتبارًا من 31 ديسمبر 2018 لن يكون موجودًا في أي إصدار مدعوم من PHP. في الوقت الحالي ، يحصل فقط على تحديثات أمنية .
  • يفتقر إلى واجهة OO
  • لا يدعم:
    • استعلامات غير متزامنة وغير متزامنة
    • بيانات جاهزة أو استعلامات معلمة
    • الإجراءات المخزنة
    • بيانات متعددة
    • المعاملات
    • طريقة مصادقة كلمة المرور "الجديدة" (بشكل افتراضي في MySQL 5.6 ؛ مطلوب في 5.7)
    • كل الوظائف في MySQL 5.1

نظرًا لأنه يتم إهماله ، فإن استخدامه يجعل شفرتك أقل برهانًا في المستقبل.

يعتبر عدم وجود دعم للبيانات المعدة أهمية خاصة لأنها توفر طريقة أكثر وضوحًا وأقل عرضة للهروب من البيانات الخارجية واقتباسها من الهروب اليدوي مع استدعاء وظيفة منفصل.

انظر المقارنة بين ملحقات SQL .


تم إيقاف وظائف mysql_ * (اعتبارًا من 5.5 بيزو فلبيني ) نظرًا إلى أنه تم تطوير وظائف وهياكل تعليمات أفضل. إن إهمال الوظيفة يعني أنه لن يتم بذل المزيد من الجهد لتحسينها من حيث الأداء والأمان ، مما يعني أنها أقل برهانًا في المستقبل .

إذا كنت بحاجة إلى مزيد من الأسباب:

  • لا تدعم الدالات mysql_ * عبارات المعدة.
  • لا تدعم الدالات mysql_ * ربط المعلمات.
  • mysql_ * وظائف تفتقر إلى وظيفة البرمجة Object Oriented.
  • والقائمة تطول ...

تمت كتابة هذه الإجابة لإظهار مدى التباطؤ في تجاوز كود التحقق من صحة مستخدم PHP بشكل سيئ ، وكيفية (واستخدام ما) هذه الهجمات تعمل وكيفية استبدال وظائف 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'

انظر كيف أنشأت "كلمة المرور" الخاصة بي بحيث يتم إغلاق الاقتباس الفردي حول كلمة المرور ، ثم إدخال مقارنة جديدة تمامًا؟ ثم فقط من أجل الأمان ، أضفت "سلسلة" أخرى بحيث يتم إغلاق الاقتباس المفرد كما هو متوقع في الشفرة التي كان لدينا في الأصل.

ومع ذلك ، لا يتعلق الأمر بالناس الذين يصرخون عليك الآن ، فهذا يتعلق بتوضيح كيفية جعل رمزك أكثر أمانًا.

حسنًا ، ما الخطأ الذي حدث ، وكيف يمكننا إصلاحه؟

هذا هو هجوم حقن SQL الكلاسيكية. واحدة من أبسط هذه المسألة. على نطاق المتجهات الهجومية ، هذا هو طفل صغير يهاجم دبابة - والفوز.

لذا ، كيف نحمي قسم الإدارة المقدسة ونجعله لطيفًا وآمنًا؟ أول شيء يجب فعله هو التوقف عن استخدام تلك mysql_*الوظائف القديمة والمهملة . وأنا أعلم أنك اتبعت برنامجًا تعليميًا عثرت عليه عبر الإنترنت وهو يعمل ، ولكنه قديم ، وقد عفا عليه الزمن ، وفي غضون دقائق معدودة ، كنت قد تجاوزته للتو دون أن أتمكن من كسر العرق.

الآن ، لديك خيارات أفضل لاستخدام mysqli_ أو PDO . أنا شخصياً معجب كبير بشركة تنمية نفط عمان ، لذا سأستخدم شركة تنمية نفط عمان في بقية هذه الإجابة. هناك المؤيد والمعارك ، ولكن شخصيا أجد أن الموالية تفوق بكثير con's. إنه محمول عبر محركات قواعد بيانات متعددة - سواء كنت تستخدم MySQL أو Oracle أو فقط أي شيء دموي - فقط بتغيير سلسلة الاتصال ، فإنه يحتوي على جميع الميزات الفاخرة التي نرغب في استخدامها وهي جميلة ونظيفة. أنا أحب نظيفة.

الآن ، دعونا نلقي نظرة على هذا الرمز مرة أخرى ، هذه المرة مكتوبة باستخدام كائن PDO:

<?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_*وظائف أخرى. كل ذلك يتم عبر كائن PDO ، وثانياً ، يستخدم عبارة معدّة. الآن ، ما هو البيان السابق الذي تسأله؟ إنها طريقة لإخبار قاعدة البيانات قبل تشغيل استعلام ، ما هو الاستعلام الذي سنقوم بتشغيله. في هذه الحالة ، نخبر قاعدة البيانات: "مرحبًا ، سأقوم بتشغيل عبارة محددة تريد معرفًا ، userid ونمرر من مستخدمي الجدول حيث يكون معرف المستخدم متغيرًا ويكون التمرير أيضًا متغيرًا.".

ثم ، في بيان التنفيذ ، نمرر قاعدة البيانات مصفوفة بجميع المتغيرات التي تتوقعها الآن.

النتائج رائعة. دعنا نجرب تركيبات اسم المستخدم وكلمة المرور هذه من قبل:

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...

هذا هو السبب في صراخك عند نشر أسئلة - لأنه يمكن أن يرى الناس أنه يمكن تجاوز التعليمات البرمجية الخاصة بك حتى wihout حتى المحاولة. من فضلك ، لا تستخدم هذا السؤال والإجابة لتحسين التعليمات البرمجية الخاصة بك ، لجعلها أكثر أمنا واستخدام الوظائف الحالية.

وأخيرًا ، لا يعني هذا أن هذا هو PERFECT code. هناك العديد من الأشياء التي يمكنك القيام بها لتحسينها ، استخدم كلمات المرور المجزأة على سبيل المثال ، تأكد من أنه عند تخزين المعلومات الحساسة في قاعدة البيانات ، لا تخزنها في نص عادي ، ولديك مستويات متعددة من التحقق - ولكن في الحقيقة ، إذا أنت فقط تغيير رمزك القديم عرضة للحقن لهذا ، سوف تكون على طول الطريق لكتابة رمز جيد - وحقيقة أنك حصلت على هذا الآن وما زلت تقرأ يعطيني شعوراً بالأمل بأنك لن تقوم فقط بتطبيق هذا النوع من رمز عند كتابة مواقع الويب والتطبيقات الخاصة بك ، ولكن يمكنك الخروج والبحث عن الأشياء الأخرى التي ذكرتها للتو - وأكثر من ذلك. اكتب أفضل رمز يمكنك ، وليس الكود الأساسي الذي يعمل بالكاد.


إن الوظائف التي تشبه هذا mysql_connect()، mysql_query()هي النوع السابق من وظائف PHP (PHP 4) ولا يتم استخدامها الآن.

يتم استبدال هذه mysqli_connect()، mysqli_query()بالمثل في أحدث PHP5.

هذا هو السبب وراء الخطأ.


تمديد MySQL هو أقدم من الثلاثة وكانت الطريقة الأصلية التي استخدمها المطورون للتواصل مع MySQL. ويجري الآن هذا التمديد deprecated لصالح الأخرى mysqli_ PDO بسبب التحسينات التي أدخلت في الإصدارات الأحدث من كلا PHP و MySQL.

  • mysqli_ هو mysqli_ "المحسن" للعمل مع قواعد بيانات MySQL. فإنه يستفيد من الميزات المتوفرة في الإصدارات الأحدث من خادم MySQL ، ويعرض كلاً من واجهة المنحى الوظيفية والوجهة الموجهة للمطور ، ويقوم بأشياء قليلة أخرى رائعة.

  • PDOتقدم PDO واجهة برمجة تطبيقات تعمل على دمج معظم الوظائف التي كانت موزعة مسبقًا عبر امتدادات الوصول إلى قاعدة البيانات الرئيسية ، مثل MySQL و PostgreSQL و SQLite و MSSQL وغيرها. وتعرض الواجهة كائنات عالية المستوى للمبرمج للعمل مع اتصالات قواعد البيانات والاستعلامات و مجموعات النتائج ، وبرامج التشغيل ذات المستوى المنخفض أداء الاتصالات وتداول الموارد مع خادم قاعدة البيانات. هناك الكثير من النقاش والعمل في شركة تنمية نفط عمان وتعتبر الطريقة المناسبة للعمل مع قواعد البيانات في القانون المهني الحديث.


لأنه (من بين أسباب أخرى) يكون من الأصعب التأكد من تطهير بيانات الإدخال. إذا كنت تستخدم استعلامات معلومة ، كما هو الحال مع PDO أو mysqli ، يمكنك تجنب المخاطر بالكامل.

على سبيل المثال ، يمكن لشخص ما استخدام "enhzflep); drop table users"اسم المستخدم. ستسمح الوظائف القديمة بتنفيذ عدة عبارات لكل استعلام ، بحيث يمكن لشيء مثل هذا التافه السيء حذف جدول كامل.

إذا كان أحد يستخدم PDO من mysqli ، فإن اسم المستخدم في نهاية المطاف يجري "enhzflep); drop table users".

انظر bobby-tables.com .


هناك العديد من الأسباب ، ولكن ربما أهمها هو أن تلك الوظائف تشجع ممارسات البرمجة غير الآمنة لأنها لا تدعم البيانات المعدة. تساعد العبارات المعدة في منع هجمات حقن SQL.

عند استخدام mysql_*الدالات ، يجب عليك تذكر تشغيل المعلمات التي يوفرها المستخدم من خلال mysql_real_escape_string(). إذا نسيت في مكان واحد فقط أو إذا كنت قد هربت من جزء من المدخلات ، فقد تكون قاعدة بياناتك عرضة للهجوم.

استخدام عبارات معدّة في PDOأو mysqliسيجعلها بحيث يصعب صنع أنواع الأخطاء البرمجية هذه.


و mysql_ظائف:

  1. قديمة - لا يتم الاحتفاظ بها بعد الآن
  2. لا تسمح لك بالتحرك بسهولة إلى خلفية قاعدة بيانات أخرى
  3. لا تدعم البيانات المعدة ، وبالتالي
  4. تشجيع المبرمجين على استخدام تسلسل لإنشاء استعلامات ، مما يؤدي إلى ثغرات أمنية في إدخال SQL




database