فلاتر PHP
تستخدم فلاتر (تصفيات) PHP لفلترة و جعل البيانات شرعية التي تأتي من جهات غير محمية مثل مدخلات المستخدم .
ماهو فلتر / تصفية PHP ؟
تستخدم فلاتر (تصفيات) PHP لفلترة و جعل البيانات شرعية التي تأتي من جهات غير محمية مثل مدخلات المستخدم .
يعتبر اختبار أو تصفية مدخل مستخدم أو أي بيانات تقليدية خطوة مهمة لأي تطبيق على الانترنت .
تم تصميم زيادات فلاتر PHP لجعل فلترة البيانات أسهل وأسرع .
لماذا نستخدم الفلاتر ؟
غالباً تعتمد جميع تطبيقات الانترنت على مدخلات خارجية و ذلك يأتي من مستخدم أو من خلال تطبيق آخر ( مثل خدمات الويب ) و باستخدام الفلترة يمكنك أن تكون واثقاً بأن تطبيقك حصل على نوع المدخل الصحيح .
يجب دائماً استخدام الفلترة للبيانات الخارجية
تعتبر فلترة المدخلات واحدة من أهم القضايا الأمنية المهمة للتطبيقات .
ماهي البيانات الخارجية ؟
- البيانات المدخلة من خلال النماذج .
- الكوكيز cookies .
- بيانات الويب الخدمية .
- نتائج أوامر قواعد البيانات .
الوظائف و الفلاتر
لفلترة أو تصفية متغير يمكن استخدام احدى هذه الأكواد الوظيفية :
- filter_var() : فلترة متغير واحد مع فلتر محدد .
- filter_var_array() : فلترة متغيرات متعددة مع فلترات متشابهة أو مختلفة .
- filter_input : الحصول على متغير لمدخل واحد و فلترته .
- filter_input_array : الحصول على متغيرات لمدخلات متعددة و فلترتهم مع فلترات مختلفة او متشابهة .
في المثال التالي سنقوم بتفعيل رقم باستخدام الوظيفة filter_var() :
<?php
$int = 123;
if(!filter_var($int, FILTER_VALIDATE_INT))
{
echo("Integer is not valid");
}
else
{
echo("Integer is valid");
}
?>
تم استخدام الفلتر FILTER_VALIDATE_INT لفلترة متغير . بما أن الرقم فعال سيتم إظهار نتيجة الكود "Integer is valid" .
لو كان المتغير ليس رقماً ( مثل "123abc" ) سيتم إظهار نتيجة الكود "Integer is not valid" .
للحصول على قائمة كاملة للوظائف و الفلاتر يمكنك زيارة مرجع فلاتر PHP .
التفعيل Validating و التعقيم Sanitizing
هناك نوعين من الفلترة :
تفعيل الفلاتر
- تستخدم لتفعيل مدخل مستخدم .
- تثبيت القواعد ( مثل تفعيل URL أو Email ) .
- إعادة الأنواع المتوقعة من النجاج أو الفشل .
تعقيم الفلاتر
- تستخدم للمساح أو عدم السماح بحرف معين في النص .
- لايوجد قواعد معينة للبيانات .
- دائماً تعيد نص .
الخيارات و الرايات
تستخدم الخيارات والرايات لإضافة فلترة اضافية الى فلتر معين .
تختلف الخيارات والرايات مع اختلاف الفلاتر .
في المثال التالي قمنا بتفعيل رقم معين integer باستخدام filter_var() بالاضافة الى خيارات min_range و max_range :
<?php
$var=300;
$int_options = array(
"options"=>array
(
"min_range"=>0,
"max_range"=>256
)
);
if(!filter_var($var, FILTER_VALIDATE_INT, $int_options))
{
echo("Integer is not valid");
}
else
{
echo("Integer is valid");
}
?>
للحصول على قائمة كاملة للوظائف و الفلاتر يمكنك زيارة مرجع فلاتر PHP . يمكنك فحص كل فلتر لمشاهدة الخيارات و الرايات المتوفرة .
المدخلات المفعلة
دعنا نقوم بتفعيل مدخل للنموذج .
أول شيء يجب أن نقوم فيه هو تأكيد بأن بيانات الادخال التي نبحث عنها موجودة . ثم نقوم بفلترة البيانات المدخلة باستخدام الوظيفة filter_input() .
في المثال التالي سيتم ارسال مدخل المتغير "email" الى صفحة PHP :
<?php
if(!filter_has_var(INPUT_GET, "email"))
{
echo("Input type does not exist");
}
else
{
if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL))
{
echo "E-Mail is not valid";
}
else
{
echo "E-Mail is valid";
}
}
?>
شرح المثال
يحتوي المثال السابق على مدخل تم ارساله الى باستخدام طريقة GET :
- سيفحص فيما اذا مدخل البريد email فعال و موجود باستخدام النوع GET .
- اذا كان المتغير موجود سيتم فحص فعالية البريد الالكتروني .
تعقيم المدخلات
دعونا نقوم بتنظيف الرابط URL المرسل من النموذج .
أولاً يجب التأكيد على أن البيانات المدخلة التي نبحث عنها موجودة . ثم نقوم بتعقيم البيانات المدخلة من خلال استخدام الوظيفة filter_input()
في المثال التالي سيتم ارسال مدخل المتغير url الى صفحة PHP :
<?php
if(!filter_has_var(INPUT_POST, "url"))
{
echo("Input type does not exist");
}
else
{
$url = filter_input(INPUT_POST,
"url", FILTER_SANITIZE_URL);
}
?>
شرح المثال
يحتوي المثال السابق على مدخل url تم ارساله الى باستخدام طريقة POST :
- سيفحص فيما اذا مدخل url فعال و موجود باستخدام النوع POST .
- اذا كان المتغير موجود سيتم تعقيم ( حذف الأحرف الغير فعالة ) و حفظها في المتغير $url .
اذا كان مدخلات المتغير نص عادي مثل http://www.exååmple.com/ سيتم اختيار الرابط الصحيح و تعقيمه من خلال المتغير $url كالتالي :
http://www.Example.com/
فلترة مدخلات متعددة
دائماً مايحتوي النموذج على واحد أو اكثر من مدخلات النصوص . ولتجنب استدعاء filter_var أو filter_input مرات و مرات يمكن استخدام filter_var_array أو filter_input_array .
في المثال التالي قيمنا باستخدام filter_input_array() لفلترة ثلاث متغيرات من نوع GET . المتغير من نوع GET المستلم هو الاسم والعمر و عنوان البريد الالكتروني :
<?php
$filters = array
(
"name" => array
(
"filter"=>FILTER_SANITIZE_STRING
),
"age" => array
(
"filter"=>FILTER_VALIDATE_INT,
"options"=>array
(
"min_range"=>1,
"max_range"=>120
)
),
"email"=> FILTER_VALIDATE_EMAIL,
);
$result = filter_input_array(INPUT_GET, $filters);
if (!$result["age"])
{
echo("Age must be a number between 1 and 120.<br />");
}
elseif(!$result["email"])
{
echo("E-Mail is not valid.<br />");
}
else
{
echo("User input is valid");
}
?>
شرح المثال
يحتوي المثال السابق على ثلاث متغيرات ( الاسم و العمر و البريد ) تم ارسالهم الى البريد نفسه باستخدام الطريقة GET
- تم ضبط مصفوفة تحتوي على متغيرات وفلاتر اسم المدخل المستخدمة مع متغير لمدخل محدد .
- استدعاء الوظيفة filter_input_array() مع متغيرات GET المدخلة و المصفوفة التي أنشأناها مسبقاً .
- فحص متغيرات العمر age و البريد الالكتروني email في متغير $result للمدخلات الغير فعالة .
يمكن أن يكون القيمة الثانية في الوظيفة filter_input_array() مصفوفة أو فلتر ID واحد .
اذا كان المتغير فلتر id واحد عندها سيتم فلترة جميع المتغيرات في مصفوفة مدخلات من خلال فلتر محدد .
اذا كان المتغير مصفوفة عندها يجب اتبّاع التعليمات التالية
- يجب أن يكون مرفق بمصفوفة تحتوي على متغير مدخل مثل وسم المصفوفة .
- قيمة المصفوفة يجب أن تكون مفلترة id او مصفوفة تحدد فلتر او راية او خيار .
استدعاء الفلتر
يمكنك استدعاء وظيفة معرفة من خلال المستخدم و استخدامه كفلتر باستخدام ميزة FILTER_CALLBACK . و بهذه الطريقة لديك تحكم كامل بفلترة البيانات .
يمكنك إنشاء وظفة خاصة للمستخدم او استخدام وظائف PHP الحالية .
الوظيفة التي ترغب باستخدامها لفلترتها محددة بنفس الطريقة كخيار مخصص .
في المثال التالي سيتم إنشاء وظيفة تقوم بتحويل جميع "_" الى فراغات :
<?php
function convertSpace($string)
{
return str_replace("_", " ", $string);
}
$string = "Peter_is_a_great_guy!";
echo filter_var($string, FILTER_CALLBACK,
array("options"=>"convertSpace"));
?>
ستظهر النتيجة على المتصفح كالتالي :
Peter is a great guy!
شرح المثال
في المثال التالي سيتم إنشاء وظيفة تقوم بتحويل جميع "_" الى فراغات :
- إنشاء function لاستبدال "_" الى فراغات .
- استدعاء filter_var() مع الفلتر FILTER_CALLBACK و مصفوفة تحتوي على function .
معالجة الأخطاء الافتراضي في PHP بسيط جداً . يتم ارسال رسالة الخطأ بإسم الملف أو رقم السطر أو شرح الخطأ في رسالة الى المتصفح .
معالجة الأخطاء
تعتبر معالجة الأخطاء مهمة جداً عند إنشاء تطبيقات و سكربتات على الانترنت . سيبدو برنامجط غير احترافي وربما يمكن أن يكون معرض للمخاطر الأمنية اذا كان الكود لديك ينقصه فحص الأخطاء .
يحتوي الدورة لدينا على بعض طرق فواص الأخطاء السائدة في لغة PHP .
سنقوم بعرض طرق مختلفة لمعالجة الأخطاء :
- رسالة بسيطة من خلال die() .
- إحداث رسائل أخطاء تقليدية .
- تقاير الأخطاء .
معالج الأخطاء البسيط die()
يظهر المثال التالي كود بسيط حيث يفتح ملف نصي :
<?php
$file=fopen("welcome.txt","r");
?>
اذا لم يتم إيجاد الملف سيتم إظهار رسالة خطئ :
Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: No such file or directory in C:webfoldertest.php on line 2
لتجنب رسالة الخطأ مثل المثال السابق سيتم فحص فيما اذا كان الملف موجود قبل المحاولة بالدخول اليه :
<?php
if(!file_exists("welcome.txt"))
{
die("File not found");
}
else
{
$file=fopen("welcome.txt","r");
}
?>
ان لم يتم ايجاد النص ستظهر هذه الرسالة على المتصفح :
File not found
إنشاء معالج أخطاء
ان إنشاء معالج الأخطاء بسيط جداً . ببساطة يمكن إنشاء كود وظيفي خاص يمكن استدعائه عند حدوث الخطأ في PHP .
يجب أن يكون معالج الأخطاء ويجب أن يحمل قيمتين على الأقل ( مستوى الخطأ و رسالة الخطأ ) ولكن يمكن قبول خمسة قيم ( اختياري : الملف , رقم السطر , محتوى الخطأ ) .
التركيبة
error_function(error_level,error_message, error_file,error_line,error_context)
| القيمة | الشرح |
|---|---|
| error_level | مطلوب . يحدد مستوى تقرير الخطأ نوع الخطأ المعرّف للمستخدم . كما يجب أن يكون رقم للقيمة . |
| error_message | مطلوب . تحديد رسالة الخطأ |
| error_file | اختياري . تحدد اسم الملف بحيث وقوع الخطأ . |
| error_line | اختياري . تحدد رقم السطر حيث وقوع الخطأ . |
| error_context | اختياري . تحدد المصفوفة التي تحتوي على كل متغير و قيمهم المستخدمة حيث وقوع الخطأ . |
مستويات تقارير الخطأ
تحتوي مستويات تقارير الاخطاء على أنواع مختلفة والتي تعالج الأخطاء التي يمكن أن تستخدم لأجل مايلي :
| القيمة | الثوابت | الشرح |
|---|---|---|
| 2 | E_WARNING | Non-fatal run-time errors. Execution of the script is not halted |
| 8 | E_NOTICE | Run-time notices. The script found something that might be an error, but could also happen when running a script normally |
| 256 | E_USER_ERROR | Fatal user-generated error. This is like an E_ERROR set by the programmer using the PHP function trigger_error() |
| 512 | E_USER_WARNING | Non-fatal user-generated warning. This is like an E_WARNING set by the programmer using the PHP function trigger_error() |
| 1024 | E_USER_NOTICE | User-generated notice. This is like an E_NOTICE set by the programmer using the PHP function trigger_error() |
| 4096 | E_RECOVERABLE_ERROR | Catchable fatal error. This is like an E_ERROR but can be caught by a user defined handle (see also set_error_handler()) |
| 8191 | E_ALL | All errors and warnings, except level E_STRICT (E_STRICT will be part of E_ALL as of PHP 6.0) |
الآن سنقوم بإنشاء function حيث يعالج الأخطاء :
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}
يعتبر الكود في المثال السابق بسيط جداً . عندما يتم التعيين سيتم معرفة مستوى الخطأ و رسالة الخطأ . ثم سيتم إظهار رسالة الخطأ و مستوى الخطأ ثم حذف السكربت .
و الآن وبعد إنشاء معالج للأخطاء سنحتاج الى معرفة أن سظهر بلضبط .
ضبط معالج الأخطاء
يمكن معالجة الأخطاء من خلال استخدام معالج الأخطاء في PHP . سنقوم بإنشاء function فوق معالج الأخطاء الافتراضي لمدة السكربت .
يمكن تغيير معالج الأخطاء من أجل تطبيق بعض التغيرات الخاصة بالأخطاء البسيطة و بتلك الطريقة يمكن معالجة أخطاء مختلفة بطرق مختلفة . على أي حال في هذا المثال سنقوم باستخدام معالج الأخطاء لجميع أنواع الأخطاء :
set_error_handler("customError");
يمكن set_error_handler() أن يتحكم بجميع الأخطاء و فقط حتاج قيمة واحدة و ان أردت اضافة قيمة أخرى فهي تحديد مستوى الخطأ .
مثال
اختبار معالجة الأخطاء من خلال المحاولة بإظهار متغير غير موجود أصلاً :
<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr";
}//set error handler
set_error_handler("customError");//trigger error
echo($test);
?>
ستكون النتيجة على المتصفح كالتالي :
Error: [8] Undefined variable: test
إستكشاف الأخطاء
يمكن استخدام استكشاف الأخطاء عند حدوث ادخال غير شرعي وذلك سيتم حدوثه من خلال trigger_error() وذلك في السكربت حيث يمكن للمستخدمين وضع بياناتهم .
مثال
في المثال التالي سيتم حدوث الخطأ اذا كان المتغير test أكبر من 1 :
<?php
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below");
}
?>
ستكون النتيجة على المتصفح كالتالي :
Notice: Value must be 1 or below in C:webfoldertest.php on line 6
يمكن اظهار الخطأ في أي مكان في السكربت و ذلك بإضافة قيمة أخرى كما يمكنك تحديد مستوى الخطأ الذي سيظهر .
أنواع الأخطاء المحتملة
- E_USER_ERROR : خطأ مروع يحدث عند خطأ يحدثه المستخدم و هذا الخطأ لايمكن تغطيته . يكون انجاز السكربت متوقف .
- E_USER_WARNING : خطأ غير مروع يتم التحذير فيه و يكون إنجاز السكربت غير متوقف .
- E_USER_NOTICE : ملاحظة عند امكانية حدوث خطأ معين و لكن يمكن أن يحدث أيضاً حتى في الحالة العادية للسكربت .
مثال
في هذا المثال سيتم استدعاء الخطأ E_USER_WARNING اذا كان المتغير test أكبر من الرقم 1 و اذا حدث E_USER_WARNING سنستخدم معالج الأخطاء و سيتم إنهاء السكربت :
<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}//set error handler
set_error_handler("customError",E_USER_WARNING);//trigger error
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>
ستظهر النتيجة على المتصفح كالتالي :
Error: [512] Value must be 1 or below Ending Script
و الأن تعلمنا إنشاء أخطاء و كيفية استكشافهم و الآن سنتعلم حول أخطاء تسجيل الدخول .
أخطاء السجلات
بشكل افتراضي ترسل PHP سجلات الأخطاء الى نظام سجل السيرفر أو الملف و ذلك اعتماداً على كيفية ضبط اعدادات error_log في ملف php.ini . باستخدام error_log() يمكن ارسال سجلات الأخطاء الى ملف أو وجهة مخصصة .
تعتبر طريقة جيدة بارسال سجلات الأخطاء لبريدك الالكتروني و بذلك يتم ارسال التنبيهات لبريدك عند تحديد الأخطاء .
ارسال رسالة خطأ بالبريد الالكتروني
في المثال التالي سنقوم بارسال بريد اللكتروني برسالة الخطأ و إنهاء السكربت اذا حدث ذلك الخطأ :
<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Webmaster has been notified";
error_log("Error: [$errno] $errstr",1,
"someone@example.com","From: webmaster@example.com");
}//set error handler
set_error_handler("customError",E_USER_WARNING);//trigger error
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>
ستظهر النتجة على المتصفح كالتالي
Error: [512] Value must be 1 or below Webmaster has been notified And the mail received from the code above looks like this: Error: [512] Value must be 1 or below
ليس من الضروري استخدام هذه الطريقة لكل الأخطاء لأن الأخطاء النظامية ينبغي أن ترسل السجلات الى السيرفر باستخدام نظام السجلات الافتراضي الخاص بلغة PHP .