التحقق من صحة النماذج في PHP
في الدرس السابق، تعلمت كيفية استلام بيانات النماذج. يتناول هذا الدرس الخطوة الأكثر أهمية — التحقق من صحة البيانات. لا تثق أبدًا في المدخلات التي يقدمها المستخدمون. فالمستخدمون يرتكبون أخطاءً إملائية، وقد يكونون ذوي نوايا خبيثة، كما أنهم يتركون الحقول فارغة. ويُعد التحقق من صحة البيانات في النماذج خط دفاعك الأول.
1. بنية التحقق من الصحة
تتم جميع عمليات التحقق من الصحة من جانب الخادم (PHP). أما التحقق من الصحة من جانب العميل (HTML5 / JavaScript) فهو مجرد طبقة مريحة يُفضل وجودها:
TEXT
Browser (JS validation, easily bypassed)
↓
PHP server (MUST validate — never skip this step)
↓
Store in database
PHP
<?php
$errors = [];
// 1. Collect and clean input
$name = trim($_POST['name'] ?? '');
$age = $_POST['age'] ?? '';
$email = trim($_POST['email'] ?? '');
// 2. Apply validation rules
if ($name === '') {
$errors['name'] = 'Name is required';
} elseif (strlen($name) > 50) {
$errors['name'] = 'Name must not exceed 50 characters';
}
if ($age === '') {
$errors['age'] = 'Age is required';
} elseif (!is_numeric($age)) {
$errors['age'] = 'Age must be a number';
} elseif ((int)$age < 1 || (int)$age > 150) {
$errors['age'] = 'Age must be between 1 and 150';
}
if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Invalid email format';
} // Email is optional, but if provided it must be valid
// 3. Determine the outcome
if (empty($errors)) {
echo "Validation passed!";
} else {
foreach ($errors as $field => $msg) {
echo "<p style='color:red'>{$msg}</p>";
}
}
?>
💡 نصيحة: استخدم مصفوفة مرتبطة
$errors لتجميع رسائل الخطأ. تتيح بنية $errors['field_name'] عرض الأخطاء بجانب الحقول المقابلة لها بسهولة.
2. التحقق من صحة البيانات باستخدام دالة filter_var()
تعد ميزة filter_var() المدمجة في لغة PHP الطريقة الأفضل للتحقق من صحة أنواع البيانات الشائعة:
PHP
<?php
// Email validation
$email = "test@example.com";
var_dump(filter_var($email, FILTER_VALIDATE_EMAIL));
// "test@example.com" (returns the original value on success)
$badEmail = "not-an-email";
var_dump(filter_var($badEmail, FILTER_VALIDATE_EMAIL));
// bool(false) (validation failed)
// URL validation
$url = "https://www.example.com";
var_dump(filter_var($url, FILTER_VALIDATE_URL));
// IP address validation
$ip = "192.168.1.1";
var_dump(filter_var($ip, FILTER_VALIDATE_IP));
// Integer range validation
$age = 25;
var_dump(filter_var($age, FILTER_VALIDATE_INT, [
"options" => ["min_range" => 1, "max_range" => 150]
]));
?>
▶ مثال: التحقق من صحة نموذج كامل باستخدام filter_var
PHP
<?php
$errors = [];
// Validate email
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
if ($email === false) {
$errors['email'] = 'Please enter a valid email address';
}
// Validate URL
$website = filter_var($_POST['website'] ?? '', FILTER_VALIDATE_URL);
if ($website === false && ($_POST['website'] ?? '') !== '') {
$errors['website'] = 'Please enter a valid URL';
}
// Validate integer range
$age = filter_var($_POST['age'] ?? '', FILTER_VALIDATE_INT, [
"options" => ["min_range" => 1, "max_range" => 120]
]);
if ($age === false) {
$errors['age'] = 'Age must be between 1 and 120';
}
?>
3. التحقق من صحة التعبيرات النمطية باستخدام preg_match()
وعندما لا تكفي أدوات التحقق المدمجة، تدخل التعبيرات النمطية لتحل محلها:
PHP
<?php
// Phone number (10-digit North American)
$phone = "5551234567";
if (preg_match('/^\d{10}$/', $phone)) {
echo "Phone number format is valid";
}
// Username (alphanumeric + underscore, 3-20 characters)
$username = "user_2024";
if (preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username)) {
echo "Username format is valid";
}
// Strong password (min 8 chars, at least one lowercase, one uppercase, one digit)
$password = "MyPass123";
if (preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/', $password)) {
echo "Password meets strength requirements";
}
?>
4. تعزيز الأمان
(1) htmlspecialchars() — منع هجمات XSS
إذا تم عرض مدخلات المستخدم التي تحتوي على علامات <script> مباشرةً، فسيقوم المتصفح بتنفيذها:
PHP
<?php
$userInput = '<script>alert("Hacked!")</script>';
// ❌ Dangerous — direct output
echo $userInput; // The script executes!
// ✅ Safe — escape special characters
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// Renders as: <script>alert("Hacked!")</script>
// The browser displays the text rather than executing it
?>
(2) strip_tags() — إزالة علامات HTML
PHP
<?php
$content = "<p>This is <b>important</b> content</p>";
echo strip_tags($content); // This is important content
// Optionally allow specific tags (whitelist as second argument)
echo strip_tags($content, '<b><i>'); // This is <b>important</b> content
?>
(3) trim() — إزالة المسافات البيضاء في بداية النص ونهايته
PHP
<?php
$input = " John ";
echo trim($input); // John
?>
▶ مثال: دالة كاملة لتنقية المدخلات
PHP
<?php
/**
* Clean user-supplied text input
*/
function cleanInput(string $data): string {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
return $data;
}
$name = cleanInput($_POST['name'] ?? '');
$comment = cleanInput($_POST['comment'] ?? '');
?>
5. تجميع كل العناصر معًا
▶ مثال: نموذج التسجيل الكامل مع عملية التحقق من صحة البيانات
PHP
<?php
$errors = [];
$username = $email = $password = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
// Username validation
if ($username === '') {
$errors['username'] = 'Username is required';
} elseif (strlen($username) < 3 || strlen($username) > 20) {
$errors['username'] = 'Username must be 3–20 characters';
} elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) {
$errors['username'] = 'Username may only contain letters, digits, and underscores';
}
// Email validation
$emailClean = filter_var($email, FILTER_VALIDATE_EMAIL);
if ($email === '') {
$errors['email'] = 'Email is required';
} elseif ($emailClean === false) {
$errors['email'] = 'Invalid email format';
}
// Password validation
if ($password === '') {
$errors['password'] = 'Password is required';
} elseif (strlen($password) < 6) {
$errors['password'] = 'Password must be at least 6 characters';
}
if (empty($errors)) {
$usernameSafe = htmlspecialchars($username, ENT_QUOTES, 'UTF-8');
echo "<h3 style='color:green'>Registration successful! Welcome, {$usernameSafe}!</h3>";
$username = $email = $password = '';
}
}
?>
<form method="POST" action="">
<div>
<label>Username:</label>
<input type="text" name="username"
value="<?= htmlspecialchars($username) ?>">
<span style="color:red"><?= $errors['username'] ?? '' ?></span>
</div>
<div>
<label>Email:</label>
<input type="email" name="email"
value="<?= htmlspecialchars($email) ?>">
<span style="color:red"><?= $errors['email'] ?? '' ?></span>
</div>
<div>
<label>Password:</label>
<input type="password" name="password">
<span style="color:red"><?= $errors['password'] ?? '' ?></span>
</div>
<button type="submit">Register</button>
</form>
❓ أسئلة شائعة
س لديّ بالفعل السمتان
required وpattern في الواجهة الأمامية. فهل ما زلت بحاجة إلى التحقق من الصحة باستخدام PHP؟ج بالتأكيد. يمكن تجاوز التحقق من الصحة في الواجهة الأمامية بسهولة — عن طريق تعطيل JavaScript، أو محاكاة طلب باستخدام curl. أما التحقق من الصحة من جانب PHP فهو خط الدفاع الأخير الذي لا يمكن تجاهله.
س متى يجب عليّ استخدام
htmlspecialchars ومتى strip_tags؟ج استخدم
htmlspecialchars عندما تريد عرض مدخلات المستخدم كما هي ولكن بطريقة آمنة (حيث يقوم بتحويل أحرف HTML دون إزالتها). استخدم strip_tags عندما تريد إزالة جميع عناصر HTML تمامًا. في معظم الحالات، يكفي استخدام htmlspecialchars.س تبدو التعبيرات النمطية معقدة. هل عليّ حفظها؟
ج لا. فالأنماط الشائعة (البريد الإلكتروني، رقم الهاتف، عناوين الويب) لها قواعد معروفة جيدًا. ما عليك سوى تذكر
preg_match() وبعض الرموز الأساسية — ^ (البداية)، $ (النهاية)، \d (الرقم)، [] (مجموعة الأحرف)، {} (الكمية) — وستكون على ما يرام.📖 ملخص
- تسلسل التحقق من الصحة: التحقق من الشروط المطلوبة → التحقق من النوع → التحقق من النطاق → التحقق من التنسيق
filter_var($val, FILTER_VALIDATE_EMAIL/URL/INT)هو الاختصار الأكثر دقة للتحقق من الصحةpreg_match('/pattern/', $val)يتعامل مع متطلبات التنسيق المعقدةhtmlspecialchars()يمنع هجمات XSS — إجراء عملية الهروب قبل الإخراج إلى HTMLstrip_tags()يزيل كل علامات HTML؛trim()يزيل المسافات البيضاء المحيطة- التحقق من صحة البيانات في الواجهة الأمامية يهدف إلى تحسين تجربة المستخدم؛ أما التحقق من صحة البيانات في PHP فيهدف إلى تعزيز الأمان
📝 تمارين
- قم بإنشاء نموذج لتعديل الملف الشخصي يتضمن الاسم المستعار والعمر والبريد الإلكتروني وعنوان URL للموقع الشخصي. قم بالتحقق من صحة كل حقل وفقًا للقاعدة المناسبة.
- إنشاء نموذج لتغيير كلمة المرور: اشترط إدخال كلمة المرور الحالية، واشترط أن تتكون كلمة المرور الجديدة من 8 أحرف على الأقل مع مزيج من الحروف والأرقام، وتأكد من تطابقها.
- اختبار ثغرة XSS: أنشئ نموذج سجل الزوار مع حذف
htmlspecialcharsعمدًا. حاول نشر<script>alert(1)</script>وراقب النتيجة. ثم أضفhtmlspecialcharsواختبر مرة أخرى.



