في PHP 4، يتم الإعلان عن المتغيرات عادةً باستخدام var، بينما في PHP 5، يمكنك استخدام ميزات البرمجة الموجهة للكائنات (OOP) لتخصيص رؤية البيانات - أي أن إمكانية الوصول هنا تشبه إلى حد كبير نطاق المتغير. ، ولكنها توفر آلية تحكم أفضل، وهناك ثلاثة أنواع من معدّلات الرؤية:
عامة (افتراضية) - يمكن الوصول إلى المتغيرات أو تعديلها في النطاق العالمي.
محمي--لا يمكن الوصول إلى المتغيرات أو تعديلها إلا داخل الفئة نفسها والفئات المشتقة مباشرة (باستخدام عبارة الامتداد).
خاص--لا يمكن الوصول إلى المتغيرات أو تعديلها إلا داخل الفصل.
مثل تطبيقات الواجهة، فإن انتهاك هذه القواعد في البرنامج سيؤدي إلى أخطاء جسيمة؛ ومثل الواجهات، فهي موجودة فقط لراحة المبرمجين. لكن هذا لا يعني أنه يمكن تجاهلها. إن تحديد رؤية متغير عضو فئة معين يمكن أن يحمي البيانات الموجودة داخل الكائن من التأثير الخارجي.
لنفترض أن هناك فئة MySqlDB وتم إعلان متغير الارتباط $ خاصًا فيها، مما يعني أنه لا يمكن الوصول إلى هذا المتغير إلا من داخل الكائن باستخدام المتغير $this. وهذا يمنع الكتابة العرضية بواسطة كائنات أو وظائف أخرى خارج الفئة هنا سنستخدم سمة الرؤية لمساعدتنا في إنشاء كائن استعلام.
يمكنك اعتبار الاستعلام بمثابة كيان منفصل يمكن تنفيذه وإرجاع النتائج. تحتوي بعض أنظمة قواعد البيانات أيضًا على إجراءات مخزنة تشبه إلى حد كبير الوظائف، فهي تخزن عبارات الاستعلام وتقبل المعلمات المقابلة عند استدعائها.
في هذه المقالة، سيتم دمج الميزتين المذكورتين أعلاه في كائن الاستعلام الخاص بالمثال. وسيقوم المثال بمحاكاة إجراء مخزن أساسي وحفظ مؤشر النتيجة داخليًا. في الوقت الحالي، ينصب التركيز على تنفيذ الاستعلام من الكائن، حيث يمكنك استدعاء وظيفة query() لكائن MySqlDB.
يمكن تعريف الوظائف العامة التالية في كائن الاستعلام:
__construct()--يقبل المُنشئ معلمة تحتوي على مرجع مثيل للكائن الذي يقوم بتنفيذ واجهة قاعدة البيانات.
تحضير () - تقوم وظيفة التحضير () بتهيئة الإجراء المخزن للاستعلام. قد يحتوي على واحد أو أكثر من العناصر النائبة المحدودة، والتي سيتم تمريرها كمعلمات إلى وظيفة التنفيذ (). يتم تعريف العنصر النائب على أنه نقطتان مرتبطتان بعدد المعلمات متبوعًا بعدد صحيح وحرف مرتبط بنوع المعلمة.
يبدو الاستعلام البسيط الذي يحتوي على عناصر نائبة كما يلي:
SELECT col1,col2 FROM table_name WHERE col1=:1I
Execute()--ستعمل الدالة Execute() على تنفيذ الاستعلام. إذا تمت تهيئته قبل الأوان كإجراء مخزن بواسطة الدالة Prepar()، فسيتم استخدام أي معلمات تم تمريرها كمعلمات تنفيذ للإجراء المخزن، وإلا فسيتم استخدام المعلمة الأولى كنص استعلام فقط. ستعيد الدالة Execute() النتائج بعد تنفيذ الاستعلام.
ترجمة () - تشبه وظيفة التحويل البرمجي () وظيفة التنفيذ () في الواقع، لا يتم تنفيذ الاستعلام، ولكنها تستبدل جميع العناصر النائبة في سلسلة الاستعلام، وتقبل معلمات الإجراء المخزن، وترجع النسخة المترجمة. من الاستعلام.
الأعضاء المحميون
كما ذكرنا أعلاه، يمكن استخدام مفهوم الرؤية لإخفاء الأعمال الداخلية للكائن، وحماية سلامة البيانات المطلوبة للأعمال الداخلية. كما هو موضح سابقًا، سيتم حفظ مؤشر النتيجة الذي تم إرجاعه بواسطة الاستعلام كسمة محمية، ويتم استخدام العضو المحمي هنا لأن كائن استعلام قاعدة بيانات محدد مشتق من كائن الاستعلام قد يزيد من تحميل بعض الوظائف الأساسية.
بما فيه الكفاية
للتعمق في نظرية الكود
، فلنبدأ الآن في كتابة التعليمات البرمجية أولاً، قم بإنشاء قالب كما هو موضح في المثال 1:المثال 1:
فئة قالب DBQuery
لفئة استعلام قاعدة البيانات
{
/**
*حفظ مرجع لكائن يقوم بتنفيذ واجهة قاعدة البيانات.
*/
محمي $ ديسيبل
/**
*إذا كان إجراءً مخزنًا، فاضبطه على "صحيح".
*/
محمي $stored_procedure = false
/**
;
*حفظ استعلام مع حذف كافة السلاسل.
*/
استعلام خاص $
/**
* يستخدم لمطابقة علامات الاقتباس في SQL.
*/
خاص ثابت $QUOTE_MATCH = "/(".*(?db = $db;
}
تحضير الوظيفة العامة($query)
{
$this->stored_procedure = true;
}
ترجمة الوظيفة العامة($args)
{}
تنفيذ الوظيفة العامة(استعلام $)
{}
}
وظيفة التحضير
هي القالب في المثال 1. أول شيء عليك فعله هو إنشاء وظيفة التحضير () للتأكد من تحليل الأحرف غير المقتبسة كعناصر نائبة عن طريق الخطأ، يجب أن تقوم الوظيفة بإزالة كافة الأحرف في الاستعلام تخزينها مؤقتًا في مصفوفة. سيتم أيضًا استبدال السلسلة نفسها بالعناصر النائبة، والتي يتم التعرف عليها عادةً على أنها تسلسلات سلسلة لا ينبغي أن تظهر في عبارة SQL. أثناء تجميع الاستعلام، يتم أولاً استبدال العنصر النائب للإجراء ثم يتم إعادة السلسلة إلى الاستعلام. ويتم ذلك من خلال وظيفة preg_replace() ووظيفة رد اتصال مساعدة أخرى تستخدم كوظيفة preg_replace().
المثال 2: وظيفة التحضير ()
/**
* تحضير الاستعلام كإجراء مخزن.
* @param string $query نص الاستعلام المُجهز
* @العودة فارغة
*/
إعداد الوظيفة العامة(استعلام $)
{
$this->stored_procedure = true;
$this->quote_store = array(); // مسح علامات الاقتباس $this->query = preg_replace(self::$QUOTE_MATCH, '$this->sql_quote_replace("1"؟"1":'2')', $ استفسار)؛
}
وظيفة خاصة sql_quote_replace(تطابق $)
{
$number = count($this->query_strings);
$this->query_strings[] = $match;
إرجاع "$||$$رقم";
}
لاحظ هنا استخدام السمة QUOTE_MATCH الثابتة الخاصة، بالإضافة إلى السمة quote_store والدالة sql_quote_replace(). بالمقارنة مع المحمية، فإن تحديدها على أنها خاصة هنا يضمن أن أي فئة فرعية تتجاوز طريقة التحضير () لفئة الاستعلام تستخدم آليتها الخاصة لإزالة علامات الاقتباس.
ترجمة الدالة
الخطوة التالية هي إنشاء وظائف الترجمة () وتنفيذها ().
تحتوي الدالةcompile()، كما هو موضح في المثال 3، على الوظائف التالية:
· عدد المعلمات المقبولة متغير (أي معلمات متغيرة)، والتي ستتطابق مع العناصر النائبة في الاستعلام.
· تأكد من أن العنصر النائب من نوع البيانات الصحيح واستبدله بالقيمة الموجودة في المعلمة.
· قم بإرجاع الاستعلام كسلسلة ولكن لا تقم بتنفيذه.
·إذا لم تتم تهيئة كائن الاستعلام كإجراء مخزن باستخدام الدالة Prepar()، فسيتم طرح استثناء.
المثال 3: وظيفة الترجمة ()
/**
* إرجاع الاستعلام المترجم، ولكن لا يتم تنفيذه.
*param مختلط $args،... معلمات الاستعلام
*return سلسلة الاستعلام المترجمة
*/
ترجمة الوظيفة العامة ($params)
{
إذا (! $this->stored_procedure) {
رمي استثناء جديد("لم تتم تهيئة الإجراء المخزن!");
}
/* معلمات الاستبدال */
$params = func_get_args(); // الحصول على معلمات الدالة $query = preg_replace("/(?query);
return $this->add_strings($query); // ضع السلسلة مرة أخرى في الاستعلام
}
/**
* أعد إدخال السلسلة التي تمت إزالتها بواسطة وظيفة التحضير ().
*/
الوظيفة الخاصة add_strings($string)
{
$numbers = array_keys($this->query_strings);
$count = العد($numbers);
عمليات البحث $ = المصفوفة () ؛
ل($x = 0; $x < $count; $x++) {
$searches[$x] = "$||${$numbers[$x]}";
}
return str_replace($searches, $this->query_strings, $string);
}
/**
* في كل مرة يتم تنفيذها، يتم استبدال عنصر نائب في الإجراء المخزن.
*/
الوظيفة المحمية compil_callback($params, $index, $type)
{
--$index
/* طرح استثناء */
إذا (! isset($params[$index])) {
رمي استثناء جديد("الإجراء المخزن لم يتلق العدد المطلوب من المعلمات!");
}
/* يمكنك إضافة أنواع أخرى هنا، مثل التاريخ والوقت. */
التبديل (نوع $) {
حالات':
return '"' . $this->db->escape_string($params[$index]) .'"';
استراحة؛
الحالة "أنا":
إرجاع (int) $params[$index];
استراحة؛
الحالة "ن":
العودة (العائمة) $params[$index];
تقصير:
رمي استثناء جديد("لم يتم التعرف على نوع البيانات '$type' المحدد في الإجراء المخزن.");
}
}
يتم استخدام وظيفتين إضافيتين في الدالة compile(). يتم استخدام الدالة compile_callback() كدالة رد اتصال في استدعاء الدالة preg_replace() في كل مرة يتم فيها العثور على عنصر نائب في الاستعلام، يتم استبداله بالقيمة التي تم تمريرها إلى عند تجميع قيمة الدالة، سيتم تنفيذها.
تنفيذ الوظيفة
أخيرًا، تحتاج إلى إنشاء وظيفة تنفيذ (). تقوم وظيفة التنفيذ () بتجميع الاستعلام وتنفيذه باستخدام كائن قاعدة البيانات، والذي يُستخدم لتهيئة كائن DBQuery هنا. يرجى ملاحظة في المثال 4 كيفية استخدام الدالة call_user_func_array() للحصول على الاستعلام المترجم والسبب في ذلك هو أن الدالة Execute() لا يمكنها تحديد عدد الوسائط التي تم تمريرها إليها حتى وقت التشغيل.
المثال 4: تنفيذ الدالة ()
/**
*
* تنفيذ الاستعلام الحالي واستبدال العناصر النائبة بالمعلمات المتوفرة.
*
* @param مختلط $queryParams،... معلمة الاستعلام
* @return Resource مرجع إلى المورد الذي يمثل الاستعلام المنفذ.
*/
تنفيذ الوظيفة العامة($queryParams = '')
{
// على سبيل المثال: حدد * من الجدول حيث الاسم=:1S والنوع=:2I والمستوى=:3N
$args = func_get_args();
إذا ($this->stored_procedure) {
/* تجميع دالة الاستدعاء للحصول على الاستعلام */
$query = call_user_func_array(array($this, 'compile'), $args);
} آخر {
/* إذا لم تتم تهيئة الإجراء المخزن، فقم بتنفيذه كاستعلام قياسي. */
$query = $queryParams;
}
$this->result = $this->db->query($query)
;
}
الاستعلام
، تم إنشاء مثال صغير أدناه، والذي سيستخدم كائن DBQuery كإجراء مخزن ويتحقق مما إذا كان قد تم إدخال اسم المستخدم وكلمة المرور الصحيحين، برجاء مراجعة المثال 5:
مثال 5:
تتطلب 'mysql_db.php5'؛
require_once 'query2.php5'؛
$db = new MySqlDb;
$db->connect('host', 'username', 'pass');
$db->query('use content_management_system');
$
query = new DBQuery($db);
');
if ($result = $query->execute("visualad", "apron", time())) {
إذا ($db->num_rows($result) == 1) {
echo('بيانات الاعتماد صحيحة.');
} آخر {
echo('بيانات الاعتماد غير صحيحة وانتهت صلاحية الجلسة.');
}
} آخر {
echo("حدث خطأ أثناء تنفيذ الاستعلام:" . $db->error());
}
لقد رأيت في هذه المقالة كيفية حماية البيانات والحد من رؤية كائنات البيانات باستخدام معدلات الوصول الخاصة والمحمية والعامة عند الإعلان عن متغيرات الفئة. وفي الوقت نفسه، في PHP 5، يمكن أيضًا استخدام هذه المفاهيم في فئة بيانات أخرى لحماية بياناتها الداخلية المهمة.