لماذا تعد شركة PDO أفضل للهروب من استعلامات/سلاسل الاستعلام MySQL من mysql_real_escape_string؟

StackOverflow https://stackoverflow.com/questions/1742066

سؤال

لقد قيل لي أنه من الأفضل أن أستخدمه PDO للهروب من MySQL، بدلاً من mysql_real_escape_string.

ربما أواجه يومًا ميتًا دماغيًا (أو ربما تكون حقيقة أنني لست مبرمجًا طبيعيًا على الإطلاق، وما زلت في مرحلة المبتدئين عندما يتعلق الأمر بـ PHP)، ولكن لدي راجعت دليل PHP وقرأت الإدخال على PDO, ، ما زلت غير واضح بشأن ماهية PDO فعليًا ولماذا هي أفضل من الاستخدام mysql_real_escape_string.قد يكون هذا لأنني لم أتمكن حقًا من التعامل مع تعقيدات OOP بعد (أفترض أن الأمر يتعلق بـ OOP)، ولكن بخلاف حقيقة أن المتغيرات وقيم المصفوفة يبدو أنها تحتوي على نقطتين أمامها، ما زلت غير متأكد من ماهيته بالفعل وكيفية استخدامه (ولماذا هو أفضل من mysql_real_escape_string.(قد يكون له أيضًا علاقة بحقيقة أنني لا أملك حقًا فهمًا واضحًا لماهية "الفئات"، لذلك عندما أقرأ "فئة PDO" فأنا لست أكثر حكمة حقًا).

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

هل يمكن لأي شخص أن يشرح لي باللغة الإنجليزية البسيطة ما هو PDO (أو يوجهني في اتجاه شيء ما حول هذا الموضوع مكتوب باللغة الإنجليزية البسيطة)، وكيف ستستخدمه؟

هل كانت مفيدة؟

المحلول

وكما تذهب الإجابات الحالية في التفاصيل بينما يهدف سؤالك أكثر في لمحة عامة، وأنا سوف محاولة إعطائها:

وتهدف هذه الطبقات PDO لتغليف كافة الوظائف اللازمة للتفاعل مع قاعدة البيانات. انهم يفعلون ذلك عن طريق تحديد "طرق" (OO صالون للوظائف) و "الخصائص" (OO صالون للمتغيرات). وكنت استخدامها بوصفها <م> الاستبدال الكامل لجميع وظائف "القياسية" الذي تستخدمه الآن للحديث إلى قاعدة بيانات.

وهكذا بدلا من استدعاء سلسلة من 'mysql_doSomething ()' وظائف، وتخزين نتائجها في المتغيرات الخاصة بك، يمكنك سوف "مثيل" كائن من الدرجة شركة تنمية نفط عمان ( 'الطبقة' = تعريف المجرد، 'الكائن' = الخرسانة مثيل وصالحة للاستعمال من فئة)، ودعوة الأساليب على هذا الكائن إلى أن تفعل الشيء نفسه.

وكمثال على ذلك، دون PDO، وكنت تفعل شيئا مثل هذا:

// Get a db connection
$connection = mysql_connect('someHost/someDB', 'userName', 'password');
// Prepare a query
$query = "SELECT * FROM someTable WHERE something = " . mysql_real_escape_string($comparison) . "'";
// Issue a query
$db_result = mysql_query($query);
// Fetch the results
$results = array();
while ($row = mysql_fetch_array($db_result)) {
  $results[] = $row;
}

وحين يكون هذا هو ما يعادل استخدام شركة تنمية نفط عمان:

// Instantiate new PDO object (will create connection on the fly)
$db = new PDO('mysql:dbname=someDB;host=someHost');
// Prepare a query (will escape on the fly)
$statement = $db->prepare('SELECT * FROM someTable WHERE something = :comparison');
// $statement is now a PDOStatement object, with its own methods to use it, e.g.
// execute the query, passing in the parameters to replace
$statement->execute(array(':comparison' => $comparison));
// fetch results as array
$results = $statement->fetchAll();

وهكذا على وهلة الأولى، ليس هناك الكثير من الفرق، ما عدا في بناء الجملة. ولكن النسخة PDO لديه بعض المزايا، وأكبر قاعدة بيانات واحدة استقلال الوجود:

إذا كنت تحتاج إلى نقاش على قاعدة بيانات كيو بدلا من ذلك، كنت فقط تغيير mysql:to pgsql: في new PDO() دعوة instantiating. مع الطريقة القديمة، عليك أن تذهب من خلال جميع التعليمات البرمجية، استبدال جميع "mysql_doSomething () 'وظائف مع نظيرهم' pg_doSomthing () '(التحقق دائما عن الاختلافات المحتملة في التعامل مع المعلمات). والأمر نفسه يكون هذا هو الحال بالنسبة للعديد من محركات قاعدة البيانات المعتمدة الأخرى.

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

ويجب أن تقرأ على بعض الأساسيات OOP للحصول على فكرة عن الآخر المزايا.

نصائح أخرى

لست على دراية كبيرة بشركة تنمية نفط عمان، ولكن هناك فرق بين "البيانات المعدة" والسلاسل المفلتة.الهروب هو على وشك إزالة سلاسل الأحرف غير المسموح بها من الاستعلام، ولكن البيانات المعدة على وشك إخبار قاعدة البيانات بنوع الاستعلام المتوقع.

يحتوي الاستعلام على أجزاء متعددة

أعتقد أنه من هذا الطريق:عندما تقدم استعلامًا إلى قاعدة البيانات، فإنك تخبرها بعدة أشياء منفصلة.قد يكون هناك شيء واحد ، على سبيل المثال ، "أريدك أن تقوم باختيار". آخر قد يكون "الحد من الصفوف حيث اسم المستخدم هو القيمة التالية."

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

'SELECT * FROM transactions WHERE username=$username'

عندما تحصل على هذه السلسلة، يجب عليها تحليلها وتحديد "هذا ملف SELECT مع WHERE".

الحصول على أجزاء مختلطة

لنفترض أن مستخدمًا ضارًا يقوم بإدخال اسم المستخدم الخاص به كـ billysmith OR 1=1.إذا لم تكن حذرًا، فقد تضع ذلك في السلسلة الخاصة بك، مما يؤدي إلى:

'SELECT * FROM transactions WHERE username=billysmith OR 1=1'

.. والذي سيعود جميع المعاملات لجميع المستخدمين, لأن 1 يساوي دائمًا 1.عفوًا، لقد تم اختراقك!

ترى ماذا حدث؟ لم تكن قاعدة البيانات تعرف الأجزاء المتوقعة في استعلامك, ، لذلك قام بتحليل السلسلة فقط.ولم يكن من المستغرب أن WHERE إمتلك OR, ، مع شرطين يمكن تحقيقه.

الحفاظ على الأجزاء مستقيمة

ولو كان يعلم ماذا تتوقع, ، وهي أ SELECT لمن WHERE كان لديه شرط واحد فقط، وهو ألا يتمكن المستخدم الضار من خداعه.

مع بيان معد، يمكنك أن تعطيه هذا التوقع الصحيح.يمكنك إخبار قاعدة البيانات "أنا على وشك أن أرسل لك ملف SELECT, ، وسوف يقتصر على الصفوف WHERE username = سلسلة أنا على وشك أن أعطيك.هذا كل شيء - لا توجد أجزاء أخرى للاستعلام.هل أنت جاهز؟حسنًا، هنا تأتي السلسلة للمقارنة باسم المستخدم."

مع هذا التوقع، لن يتم خداع قاعدة البيانات:سيرجع فقط الصفوف التي يوجد بها username يحتوي العمود على السلسلة الفعلية "billysmith OR 1 = 1". إذا لم يكن لدى أي شخص اسم المستخدم هذا ، فلن يعرض شيئا.

فوائد أخرى للبيانات المعدة

بالإضافة إلى فوائد الأمان، تتمتع البيانات المعدة بميزتين من حيث السرعة:

  • يمكن إعادة استخدامها مع معلمات مختلفة، والتي يجب أن تكون أسرع من إنشاء استعلام جديد من البداية، لأن قاعدة البيانات تعرف بالفعل ما أنت على وشك أن تطلبه.لقد قامت بالفعل ببناء "خطة الاستعلام" الخاصة بها.
  • ستبدأ بعض قواعد البيانات (أحدها، Postgres، على ما أعتقد) في وضع خطة استعلام بمجرد حصولها على البيان المُجهز - قبل أن ترسل فعليًا المعلمات لاستخدامها معها.لذلك قد ترى تسريعًا حتى عند الاستعلام الأول.

للحصول على تفسير آخر، راجع إجابة ثيو هنا.

وmysql_real_escape_string على خلاف، PDO يسمح لك لفرض نوع البيانات.

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>

لاحظ أن في المثال أعلاه، المعلمة الأولى، والسعرات الحرارية، لا بد أن يكون صحيحا (PDO :: PARAM_INT).

وثانيا، بالنسبة لي، معلمات PDO الاستعلامات أسهل للقراءة. فما استقاموا لكم فاستقيموا بدلا نصها كما يلي:

SELECT name FROM user WHERE id = ? AND admin = ? 

من

SELECT name FROM user WHERE id = mysql_real_escape_string($id) AND admin = mysql_real_escape_string($admin);

وثالثا، لم يكن لديك للتأكد من أنك أقتبس المعلمات بشكل صحيح. شركة تنمية نفط عمان يرعى ذلك. على سبيل المثال، mysql_real_query_string:

SELECT * FROM user WHERE name = 'mysql_real_escape_string($name)' //note quotes around param

ومقابل

SELECT * FROM user WHERE name = ?

وأخيرا، PDO يسمح لك ميناء التطبيق الخاص بك إلى ديسيبل مختلفة دون تغيير مكالمات البيانات PHP الخاص بك.

وتخيل أن تكتب شيئا على غرار:

$query = 'SELECT * FROM table WHERE id = ' . mysql_real_escape_string($id);

وهذا لن يخلصك من الحقن، لأن $ معرف يمكن أن يكون 1 OR 1=1 وستحصل على كافة السجلات من الجدول. عليك أن يلقي $ id لنوع البيانات المناسب (الباحث في هذه الحالة)

وشركة تنمية نفط عمان لديها ميزة أخرى، وهذا هو interchangability من الخلفيات قاعدة البيانات.

وبالإضافة إلى منع حقن SQL، PDO تسمح لك لإعداد استعلام مرة واحدة وتنفيذه عدة مرات. إذا تم تنفيذ الاستعلام عدة مرات (ضمن حلقة، على سبيل المثال)، وينبغي أن تكون هذه الطريقة أكثر فعالية (وأقول "يجب"، لأنه يبدو مثل هذا ليس الحال دائما على الإصدارات القديمة من الخلية). وإعداد / ربط الأسلوب هو أيضا أكثر انسجاما مع لغات أخرى لقد عملت مع.

لماذا تعد شركة PDO أفضل للهروب من استعلامات/سلاسل الاستعلام MySQL من mysql_real_escape_string؟

ببساطة لأن "الهروب" وحده لا معنى له.
علاوة على ذلك، الأمر مختلف لا تضاهى القضايا.

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

يمكن تحقيق الحماية تقريبًا في حالة لقد هربت ونقلت بياناتي, ، ولكنه لا ينطبق في كل مكان، بالنسبة للمعرفات على سبيل المثال (وكذلك PDO، بالمناسبة).

إذن الجواب هو:

  • عند قيام شركة PDO بالهروب من القيم المرتبطة، لا تطبق فقط الهروب ولكن أيضًا الاقتباس - وهذا هو السبب في أنه أفضل.
  • "الهروب" ليس مرادفا لـ "الحماية"."الهروب + الاقتباس" تقريبًا هو.
  • ولكن بالنسبة لبعض أجزاء الاستعلام، كلا الطريقتين غير قابلتين للتطبيق.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top