🏠 مرحباً بك في المرجع الكامل لـ PHP
هذا دليلك الشامل الكامل لكل ما تحتاجه في PHP! أكثر من 150 مثال عملي جاهز للاستخدام.
✨ المحتوى الكامل:
- 12 قسم رئيسي شامل
- أكثر من 150 مثال كود
- أنظمة كاملة جاهزة
- أفضل الممارسات
- نصائح أمنية مهمة
💡 كيف تستخدم هذا المرجع:
- استخدم القائمة اليمين للتنقل
- اضغط Ctrl+K للبحث السريع
- كل كود فيه زر نسخ
- احفظ الملف للرجوع له دائماً
📖 أساسيات PHP الكاملة
1. المتغيرات والأنواع
<?php // أنواع المتغيرات $string = "مرحباً بك في PHP"; $integer = 42; $float = 3.14159; $boolean = true; $array = [1, 2, 3, 4, 5]; $null = null; // طباعة echo $string; print $string; print_r($array); var_dump($integer); // التحقق من الأنواع is_string($string); // true is_int($integer); // true is_float($float); // true is_bool($boolean); // true is_array($array); // true is_null($null); // true isset($string); // true empty($null); // true // تحويل الأنواع $num = "123"; $converted = (int)$num; // 123 $str = (string)$integer; // "42" $arr = (array)$string; // ["مرحباً بك في PHP"] ?>
2. المصفوفات الكاملة
<?php
// مصفوفة عادية (Indexed Array)
$fruits = ["تفاح", "موز", "برتقال", "مانجو"];
echo $fruits[0]; // تفاح
echo $fruits[2]; // برتقال
// مصفوفة ترابطية (Associative Array)
$person = [
"name" => "أحمد محمد",
"age" => 25,
"email" => "ahmed@example.com",
"city" => "الرياض",
"phone" => "0501234567"
];
echo $person["name"]; // أحمد محمد
echo $person["age"]; // 25
// مصفوفة متعددة الأبعاد
$users = [
["name" => "أحمد", "age" => 25, "city" => "الرياض"],
["name" => "فاطمة", "age" => 22, "city" => "جدة"],
["name" => "محمد", "age" => 30, "city" => "الدمام"]
];
echo $users[0]["name"]; // أحمد
echo $users[1]["city"]; // جدة
// إضافة عناصر
array_push($fruits, "عنب"); // إضافة للنهاية
$fruits[] = "كيوي"; // إضافة للنهاية
array_unshift($fruits, "فراولة"); // إضافة للبداية
// حذف عناصر
array_pop($fruits); // حذف آخر عنصر
array_shift($fruits); // حذف أول عنصر
unset($fruits[1]); // حذف عنصر محدد
// البحث والتحقق
in_array("تفاح", $fruits); // true
array_search("موز", $fruits); // يرجع المفتاح
array_key_exists("name", $person); // true
// دمج وتقطيع
$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$merged = array_merge($arr1, $arr2); // [1,2,3,4,5,6]
$slice = array_slice($fruits, 1, 2); // قطع جزء من المصفوفة
// ترتيب
sort($fruits); // ترتيب تصاعدي
rsort($fruits); // ترتيب تنازلي
asort($person); // ترتيب مع حفظ المفاتيح
ksort($person); // ترتيب حسب المفاتيح
// تحويل ومعالجة
$doubled = array_map(function($n) {
return $n * 2;
}, [1, 2, 3, 4, 5]); // [2,4,6,8,10]
$even = array_filter([1,2,3,4,5,6], function($n) {
return $n % 2 == 0;
}); // [2,4,6]
$sum = array_reduce([1,2,3,4,5], function($carry, $item) {
return $carry + $item;
}, 0); // 15
// معلومات عن المصفوفة
count($fruits); // عدد العناصر
array_sum([1,2,3,4,5]); // 15
array_keys($person); // ["name","age","email","city","phone"]
array_values($person); // ["أحمد محمد",25,"ahmed@example.com","الرياض","0501234567"]
array_unique([1,2,2,3,3,4]); // [1,2,3,4]
?>
3. الحلقات التكرارية
<?php
// For Loop
for ($i = 0; $i < 10; $i++) {
echo "العدد: $i\n";
}
// While Loop
$counter = 0;
while ($counter < 5) {
echo "Counter: $counter\n";
$counter++;
}
// Do-While Loop
$x = 0;
do {
echo "X = $x\n";
$x++;
} while ($x < 5);
// Foreach للمصفوفات العادية
$colors = ["أحمر", "أخضر", "أزرق"];
foreach ($colors as $color) {
echo "اللون: $color\n";
}
// Foreach للمصفوفات الترابطية
$student = ["name" => "أحمد", "grade" => "A", "age" => 20];
foreach ($student as $key => $value) {
echo "$key: $value\n";
}
// Foreach مع المفاتيح والقيم
$scores = ["Math" => 95, "Science" => 88, "English" => 92];
foreach ($scores as $subject => $score) {
echo "$subject: $score\n";
}
// Break و Continue
for ($i = 0; $i < 10; $i++) {
if ($i == 5) break; // يوقف الحلقة
if ($i % 2 == 0) continue; // يتخطى الأرقام الزوجية
echo $i . " ";
}
// حلقات متداخلة
for ($i = 1; $i <= 3; $i++) {
for ($j = 1; $j <= 3; $j++) {
echo "[$i,$j] ";
}
echo "\n";
}
?>
4. الشروط والمقارنات
<?php
// If, Else If, Else
$age = 20;
if ($age < 13) {
echo "طفل";
} elseif ($age < 18) {
echo "مراهق";
} elseif ($age < 60) {
echo "بالغ";
} else {
echo "كبير السن";
}
// Switch Statement
$day = "الاثنين";
switch ($day) {
case "السبت":
case "الجمعة":
echo "عطلة نهاية الأسبوع";
break;
case "الاثنين":
echo "بداية الأسبوع";
break;
case "الأربعاء":
echo "منتصف الأسبوع";
break;
default:
echo "يوم عادي";
}
// Ternary Operator
$result = ($age >= 18) ? "بالغ" : "قاصر";
$status = ($age >= 18) ? "allowed" : "not allowed";
// Null Coalescing Operator (PHP 7+)
$username = $_GET['name'] ?? 'ضيف';
$page = $_GET['page'] ?? 1;
// Spaceship Operator (PHP 7+)
echo 1 <=> 2; // -1
echo 2 <=> 2; // 0
echo 3 <=> 2; // 1
// المقارنات المختلفة
$a = 5;
$b = "5";
$a == $b; // true (قيمة فقط)
$a === $b; // false (قيمة ونوع)
$a != $b; // false
$a !== $b; // true
$a > 3; // true
$a < 10; // true
$a >= 5; // true
$a <= 5; // true
// العمليات المنطقية
$x = true;
$y = false;
$x && $y; // false (AND)
$x || $y; // true (OR)
!$x; // false (NOT)
// شروط معقدة
$score = 85;
$attendance = 90;
if ($score >= 80 && $attendance >= 85) {
echo "ممتاز";
} elseif ($score >= 70 || $attendance >= 80) {
echo "جيد";
}
?>
5. الدوال (Functions)
<?php
// دالة بسيطة
function sayHello() {
echo "مرحباً بالجميع!";
}
sayHello();
// دالة مع معاملات
function greet($name, $time = "صباح") {
return "مرحباً $name، $time الخير!";
}
echo greet("أحمد"); // مرحباً أحمد، صباح الخير
echo greet("فاطمة", "مساء"); // مرحباً فاطمة، مساء الخير
// دالة مع Type Declarations
function add(int $a, int $b): int {
return $a + $b;
}
echo add(5, 3); // 8
function divide(float $a, float $b): float {
if ($b == 0) {
throw new Exception("لا يمكن القسمة على صفر");
}
return $a / $b;
}
// دالة ترجع أكثر من قيمة
function getUserData() {
return ["أحمد", 25, "الرياض"];
}
list($name, $age, $city) = getUserData();
// أو استخدم array
function getStats() {
return [
'total' => 100,
'active' => 75,
'inactive' => 25
];
}
$stats = getStats();
echo $stats['active']; // 75
// دالة بمعاملات متغيرة
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3, 4, 5); // 15
// Anonymous Function (Closure)
$multiply = function($x, $y) {
return $x * $y;
};
echo $multiply(5, 3); // 15
// Arrow Function (PHP 7.4+)
$double = fn($x) => $x * 2;
echo $double(10); // 20
// Callback Functions
function calculate($a, $b, $operation) {
return $operation($a, $b);
}
echo calculate(10, 5, function($x, $y) {
return $x + $y;
}); // 15
// Variable Scope
$globalVar = "أنا متغير عام";
function testScope() {
global $globalVar;
echo $globalVar;
static $counter = 0;
$counter++;
echo $counter;
}
// Reference Parameters
function increment(&$num) {
$num++;
}
$value = 5;
increment($value);
echo $value; // 6
?>
✅ تمام القسم الأول! الآن عندك أساسيات PHP كاملة مع أمثلة شاملة. انتقل للقسم التالي
لقواعد البيانات!
🗄️ قواعد البيانات الكاملة
1. الاتصال بـ PDO (الطريقة الموصى بها)
<?php
// إعدادات الاتصال
$host = 'localhost';
$dbname = 'mydb';
$username = 'root';
$password = '';
try {
// إنشاء الاتصال
$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $username, $password, $options);
echo "تم الاتصال بنجاح!";
} catch (PDOException $e) {
die("فشل الاتصال: " . $e->getMessage());
}
// إعدادات إضافية مهمة
$pdo->exec("SET NAMES utf8mb4");
$pdo->exec("SET CHARACTER SET utf8mb4");
?>
2. INSERT - إضافة البيانات
<?php
// إضافة سجل واحد - طريقة 1 (Positional Parameters)
$sql = "INSERT INTO users (name, email, age, city) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute(["أحمد محمد", "ahmed@example.com", 25, "الرياض"]);
echo "تم الإضافة! ID الجديد: " . $pdo->lastInsertId();
// إضافة سجل - طريقة 2 (Named Parameters)
$sql = "INSERT INTO users (name, email, age, city) VALUES (:name, :email, :age, :city)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':name' => "فاطمة أحمد",
':email' => "fatima@example.com",
':age' => 22,
':city' => "جدة"
]);
// إضافة أكثر من سجل
$users = [
["محمد علي", "mohamed@example.com", 30, "الدمام"],
["سارة خالد", "sara@example.com", 27, "مكة"],
["عبدالله سعد", "abdullah@example.com", 35, "المدينة"]
];
$sql = "INSERT INTO users (name, email, age, city) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
foreach ($users as $user) {
$stmt->execute($user);
}
echo "تم إضافة " . count($users) . " مستخدمين";
// إضافة مع التحقق من التكرار
$sql = "INSERT INTO users (name, email, age, city) VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE age = ?, city = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(["أحمد", "ahmed@example.com", 26, "الرياض", 26, "الرياض"]);
?>
3. SELECT - قراءة البيانات
<?php
// جلب جميع السجلات
$sql = "SELECT * FROM users";
$stmt = $pdo->query($sql);
$users = $stmt->fetchAll();
foreach ($users as $user) {
echo $user['name'] . " - " . $user['email'] . "\n";
}
// جلب سجل واحد
$sql = "SELECT * FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([1]);
$user = $stmt->fetch();
echo $user['name'];
// جلب عمود واحد
$sql = "SELECT name FROM users";
$names = $pdo->query($sql)->fetchAll(PDO::FETCH_COLUMN);
print_r($names); // ["أحمد", "فاطمة", "محمد"]
// Count
$sql = "SELECT COUNT(*) FROM users";
$count = $pdo->query($sql)->fetchColumn();
echo "عدد المستخدمين: $count";
// WHERE مع شروط متعددة
$sql = "SELECT * FROM users WHERE age > ? AND city = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([20, 'الرياض']);
$users = $stmt->fetchAll();
// LIKE للبحث
$sql = "SELECT * FROM users WHERE name LIKE ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(['%محمد%']);
$results = $stmt->fetchAll();
// ORDER BY و LIMIT
$sql = "SELECT * FROM users ORDER BY created_at DESC LIMIT 10";
$latest = $pdo->query($sql)->fetchAll();
// BETWEEN
$sql = "SELECT * FROM users WHERE age BETWEEN ? AND ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([20, 30]);
$results = $stmt->fetchAll();
// IN
$sql = "SELECT * FROM users WHERE city IN (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute(['الرياض', 'جدة', 'الدمام']);
$results = $stmt->fetchAll();
// JOIN
$sql = "SELECT users.*, orders.total, orders.status
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE users.id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([1]);
$result = $stmt->fetch();
// GROUP BY
$sql = "SELECT city, COUNT(*) as count FROM users GROUP BY city";
$stats = $pdo->query($sql)->fetchAll();
// HAVING
$sql = "SELECT city, COUNT(*) as count
FROM users
GROUP BY city
HAVING count > 5";
$popular_cities = $pdo->query($sql)->fetchAll();
?>
4. UPDATE - تحديث البيانات
<?php
// تحديث سجل واحد
$sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute(['أحمد المحدث', 'newemail@example.com', 1]);
echo "تم التحديث! عدد السجلات: " . $stmt->rowCount();
// تحديث مع Named Parameters
$sql = "UPDATE users
SET name = :name,
email = :email,
age = :age,
updated_at = NOW()
WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':name' => 'أحمد محمد علي',
':email' => 'ahmed.new@example.com',
':age' => 26,
':id' => 1
]);
// تحديث بشرط
$sql = "UPDATE users SET status = 'active'
WHERE last_login > DATE_SUB(NOW(), INTERVAL 30 DAY)";
$pdo->exec($sql);
// تحديث أكثر من عمود
$sql = "UPDATE users SET status = 'verified', verified_at = NOW() WHERE email_verified = 1";
$pdo->exec($sql);
// تحديث باستخدام CASE
$sql = "UPDATE users
SET role = CASE
WHEN age < 18 THEN 'junior'
WHEN age >= 18 AND age < 60 THEN 'adult'
ELSE 'senior'
END";
$pdo->exec($sql);
?>
5. DELETE - حذف البيانات
prepare($sql); $stmt->execute([1]); echo "تم الحذف! عدد السجلات: " . $stmt->rowCount(); // حذف بشروط $sql = "DELETE FROM users WHERE status = 'inactive' AND created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR)"; $deleted = $pdo->exec($sql); echo "تم حذف $deleted سجلات"; // Soft Delete (الحذف المنطقي - موصى به) $sql = "UPDATE users SET deleted_at = NOW() WHERE id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([5]); // استرجاع المحذوفات منطقياً $sql = "UPDATE users SET deleted_at = NULL WHERE id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([5]); // حذف نهائي للمحذوفات منطقياً $sql = "DELETE FROM users WHERE deleted_at IS NOT NULL AND deleted_at < DATE_SUB(NOW(), INTERVAL 30 DAY)"; $pdo->exec($sql); ?>
6. Transactions - المعاملات
beginTransaction();
// عملية 1: إضافة طلب
$sql = "INSERT INTO orders (user_id, total, status) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([1, 500, 'pending']);
$orderId = $pdo->lastInsertId();
// عملية 2: إضافة تفاصيل الطلب
$sql = "INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$orderId, 10, 2, 250]);
// عملية 3: تحديث المخزون
$sql = "UPDATE products SET stock = stock - ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([2, 10]);
// عملية 4: خصم من رصيد المستخدم
$sql = "UPDATE users SET balance = balance - ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([500, 1]);
// إذا كل شي تمام، حفظ التغييرات
$pdo->commit();
echo "تمت العملية بنجاح!";
} catch (Exception $e) {
// إذا حدث خطأ، إلغاء كل التغييرات
$pdo->rollBack();
echo "فشلت العملية: " . $e->getMessage();
}
?>
7. Database Helper Class (كامل واحترافي)
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO($dsn, $username, $password, $options);
} catch (PDOException $e) {
die("فشل الاتصال: " . $e->getMessage());
}
}
// جلب كل السجلات
public function getAll($sql, $params = []) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
// جلب سجل واحد
public function getOne($sql, $params = []) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetch();
}
// جلب قيمة واحدة
public function getValue($sql, $params = []) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchColumn();
}
// إضافة (INSERT)
public function insert($table, $data) {
$keys = array_keys($data);
$fields = implode(', ', $keys);
$placeholders = ':' . implode(', :', $keys);
$sql = "INSERT INTO $table ($fields) VALUES ($placeholders)";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($data);
return $this->pdo->lastInsertId();
}
// تحديث (UPDATE)
public function update($table, $data, $where, $whereParams = []) {
$set = [];
foreach ($data as $key => $value) {
$set[] = "$key = :$key";
}
$setString = implode(', ', $set);
$sql = "UPDATE $table SET $setString WHERE $where";
$stmt = $this->pdo->prepare($sql);
$stmt->execute(array_merge($data, $whereParams));
return $stmt->rowCount();
}
// حذف (DELETE)
public function delete($table, $where, $params = []) {
$sql = "DELETE FROM $table WHERE $where";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->rowCount();
}
// تنفيذ استعلام مخصص
public function query($sql, $params = []) {
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt;
}
// بدء معاملة
public function beginTransaction() {
return $this->pdo->beginTransaction();
}
public function commit() {
return $this->pdo->commit();
}
public function rollback() {
return $this->pdo->rollBack();
}
}
// الاستخدام
$db = new Database('localhost', 'mydb', 'root', '');
// INSERT
$userId = $db->insert('users', [
'name' => 'أحمد محمد',
'email' => 'ahmed@example.com',
'age' => 25,
'city' => 'الرياض'
]);
echo "تم الإضافة! ID: $userId";
// SELECT
$users = $db->getAll("SELECT * FROM users WHERE age > ?", [20]);
$user = $db->getOne("SELECT * FROM users WHERE id = ?", [1]);
$count = $db->getValue("SELECT COUNT(*) FROM users");
// UPDATE
$affected = $db->update('users',
['name' => 'أحمد المحدث', 'email' => 'new@example.com'],
'id = :id',
[':id' => 1]
);
echo "تم تحديث $affected سجلات";
// DELETE
$deleted = $db->delete('users', 'id = ?', [5]);
echo "تم حذف $deleted سجلات";
// استعلام مخصص
$results = $db->query("SELECT * FROM users WHERE city = ?", ['الرياض'])->fetchAll();
// معاملة
$db->beginTransaction();
try {
$db->insert('orders', ['user_id' => 1, 'total' => 500]);
$db->update('users', ['balance' => 1000], 'id = ?', [1]);
$db->commit();
} catch (Exception $e) {
$db->rollback();
}
?>
⚠️ نصائح أمنية مهمة:
- استخدم دائماً Prepared Statements
- لا تستخدم أبداً string concatenation مع SQL
- استخدم PDO بدلاً من MySQLi
- نظف وفلتر جميع المدخلات
- استخدم Transactions للعمليات المترابطة
🔐 Sessions & Authentication الكامل
1. أساسيات Sessions
2. نظام تسجيل دخول كامل
getOne("SELECT id FROM users WHERE email = ?", [$email]);
if ($exists) {
return ['success' => false, 'message' => 'البريد موجود مسبقاً'];
}
// تشفير الباسورد
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// إضافة المستخدم
try {
$userId = $db->insert('users', [
'username' => $username,
'email' => $email,
'password' => $hashedPassword,
'created_at' => date('Y-m-d H:i:s')
]);
return ['success' => true, 'user_id' => $userId];
} catch (Exception $e) {
return ['success' => false, 'message' => 'فشل التسجيل'];
}
}
function login($email, $password, $db) {
// جلب المستخدم
$user = $db->getOne("SELECT * FROM users WHERE email = ?", [$email]);
if (!$user) {
return ['success' => false, 'message' => 'البريد أو الباسورد خطأ'];
}
// التحقق من الباسورد
if (!password_verify($password, $user['password'])) {
return ['success' => false, 'message' => 'البريد أو الباسورد خطأ'];
}
// تسجيل الدخول
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['role'] = $user['role'] ?? 'user';
$_SESSION['login_time'] = time();
// تجديد Session ID للأمان
session_regenerate_id(true);
// تحديث آخر تسجيل دخول
$db->update('users',
['last_login' => date('Y-m-d H:i:s')],
'id = ?',
[$user['id']]
);
return ['success' => true, 'user' => $user];
}
function logout() {
// حذف جميع بيانات الجلسة
session_unset();
session_destroy();
// حذف Cookie الجلسة
setcookie(session_name(), '', time() - 3600, '/');
// إعادة توجيه
header("Location: login.php");
exit();
}
function isLoggedIn() {
return isset($_SESSION['user_id']);
}
function requireLogin() {
if (!isLoggedIn()) {
header("Location: login.php");
exit();
}
}
function hasRole($role) {
return isset($_SESSION['role']) && $_SESSION['role'] === $role;
}
function requireRole($role) {
if (!hasRole($role)) {
die("ليس لديك صلاحية الوصول");
}
}
function getCurrentUser($db) {
if (!isLoggedIn()) {
return null;
}
return $db->getOne("SELECT * FROM users WHERE id = ?", [$_SESSION['user_id']]);
}
// register.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$password = $_POST['password'];
$confirmPassword = $_POST['confirm_password'];
// التحقق
$errors = [];
if (empty($username) || strlen($username) < 3) {
$errors[] = "اسم المستخدم يجب أن يكون 3 أحرف على الأقل";
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "البريد الإلكتروني غير صحيح";
}
if (strlen($password) < 8) {
$errors[] = "الباسورد يجب أن يكون 8 أحرف على الأقل";
}
if ($password !== $confirmPassword) {
$errors[] = "كلمات المرور غير متطابقة";
}
if (empty($errors)) {
$result = register($username, $email, $password, $db);
if ($result['success']) {
header("Location: login.php?registered=1");
exit();
} else {
$errors[] = $result['message'];
}
}
}
// login.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = trim($_POST['email']);
$password = $_POST['password'];
$result = login($email, $password, $db);
if ($result['success']) {
header("Location: dashboard.php");
exit();
} else {
$error = $result['message'];
}
}
// dashboard.php
requireLogin();
$user = getCurrentUser($db);
echo "مرحباً " . $user['username'];
// admin.php
requireLogin();
requireRole('admin');
echo "صفحة الإدارة";
// logout.php
logout();
?>
3. Session Security
0,
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Strict',
'use_strict_mode' => true
]);
// Session Timeout
function checkSessionTimeout($timeout = 1800) { // 30 دقيقة
if (isset($_SESSION['last_activity']) &&
(time() - $_SESSION['last_activity'] > $timeout)) {
session_unset();
session_destroy();
return false;
}
$_SESSION['last_activity'] = time();
return true;
}
// Session Fingerprinting
function getSessionFingerprint() {
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
return hash('sha256', $userAgent . $ip);
}
function validateSessionFingerprint() {
if (!isset($_SESSION['fingerprint'])) {
$_SESSION['fingerprint'] = getSessionFingerprint();
}
return $_SESSION['fingerprint'] === getSessionFingerprint();
}
// استخدام الحماية
session_start();
if (!checkSessionTimeout() || !validateSessionFingerprint()) {
session_destroy();
header('Location: login.php?timeout=1');
exit;
}
?>
4. Remember Me & Cookies
time() + 3600,
'path' => '/',
'domain' => 'example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
// قراءة Cookie
if (isset($_COOKIE['username'])) {
echo $_COOKIE['username'];
}
// حذف Cookie
setcookie('username', '', time() - 3600, '/');
// نظام Remember Me كامل
function rememberUser($userId, $db) {
// إنشاء token عشوائي آمن
$token = bin2hex(random_bytes(32));
$hashedToken = hash('sha256', $token);
// حفظ في قاعدة البيانات
$db->update('users',
['remember_token' => $hashedToken, 'remember_expires' => date('Y-m-d H:i:s', time() + (86400 * 30))],
'id = ?',
[$userId]
);
// حفظ في Cookie
setcookie('remember_token', $token, [
'expires' => time() + (86400 * 30),
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
}
function checkRememberToken($db) {
if (!isset($_COOKIE['remember_token'])) {
return false;
}
$token = $_COOKIE['remember_token'];
$hashedToken = hash('sha256', $token);
$user = $db->getOne(
"SELECT * FROM users WHERE remember_token = ? AND remember_expires > NOW()",
[$hashedToken]
);
if ($user) {
// تسجيل دخول تلقائي
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
// تجديد Token
rememberUser($user['id'], $db);
return true;
}
// حذف Cookie إذا غير صالح
setcookie('remember_token', '', time() - 3600, '/');
return false;
}
// في صفحة login
if (!isLoggedIn()) {
if (!checkRememberToken($db)) {
// عرض صفحة تسجيل الدخول
}
}
// عند تسجيل الدخول
if (isset($_POST['remember_me'])) {
rememberUser($_SESSION['user_id'], $db);
}
// عند تسجيل الخروج
function fullLogout($db) {
// حذف Remember Token من قاعدة البيانات
if (isset($_SESSION['user_id'])) {
$db->update('users',
['remember_token' => null, 'remember_expires' => null],
'id = ?',
[$_SESSION['user_id']]
);
}
// حذف Cookie
setcookie('remember_token', '', time() - 3600, '/');
// تسجيل خروج عادي
logout();
}
?>
✅ الآن عندك نظام Authentication كامل! يشمل: تسجيل، دخول، خروج، Remember Me، وحماية
أمنية شاملة.
📝 Forms & Input Handling الكامل
1. التعامل مع POST و GET
2. Input Sanitization (تنظيف المدخلات)
3. Input Validation (التحقق من الصحة)
20) {
$errors['username'] = 'اسم المستخدم يجب ألا يتجاوز 20 حرف';
}
// التحقق من Email
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'البريد الإلكتروني غير صحيح';
}
// التحقق من URL
$url = filter_var($_POST['website'], FILTER_SANITIZE_URL);
if (!empty($url) && !filter_var($url, FILTER_VALIDATE_URL)) {
$errors['website'] = 'الرابط غير صحيح';
}
// التحقق من الأرقام
if (!is_numeric($_POST['age'])) {
$errors['age'] = 'العمر يجب أن يكون رقم';
}
if ($_POST['age'] < 18) {
$errors['age'] = 'العمر يجب أن يكون 18 أو أكثر';
}
// التحقق من تطابق الباسورد
if ($_POST['password'] !== $_POST['confirm_password']) {
$errors['password'] = 'كلمات المرور غير متطابقة';
}
// التحقق من قوة الباسورد
if (strlen($_POST['password']) < 8) {
$errors['password'] = 'الباسورد يجب أن يكون 8 أحرف على الأقل';
}
if (!preg_match('/[A-Z]/', $_POST['password'])) {
$errors['password'] = 'يجب أن يحتوي على حرف كبير واحد على الأقل';
}
if (!preg_match('/[a-z]/', $_POST['password'])) {
$errors['password'] = 'يجب أن يحتوي على حرف صغير واحد على الأقل';
}
if (!preg_match('/[0-9]/', $_POST['password'])) {
$errors['password'] = 'يجب أن يحتوي على رقم واحد على الأقل';
}
// التحقق من رقم الجوال السعودي
if (!preg_match('/^05[0-9]{8}$/', $_POST['phone'])) {
$errors['phone'] = 'رقم الجوال غير صحيح (مثال: 0501234567)';
}
// التحقق من Checkbox
if (!isset($_POST['terms'])) {
$errors['terms'] = 'يجب الموافقة على الشروط والأحكام';
}
// التحقق من Select
$allowedCities = ['الرياض', 'جدة', 'الدمام', 'مكة', 'المدينة'];
if (!in_array($_POST['city'], $allowedCities)) {
$errors['city'] = 'المدينة غير صحيحة';
}
// التحقق من الملف المرفوع
if ($_FILES['image']['error'] === UPLOAD_ERR_NO_FILE) {
$errors['image'] = 'الصورة مطلوبة';
}
// التحقق من تاريخ الميلاد
$birthdate = $_POST['birthdate'];
$date = DateTime::createFromFormat('Y-m-d', $birthdate);
if (!$date) {
$errors['birthdate'] = 'التاريخ غير صحيح';
}
// إذا ما فيه أخطاء
if (empty($errors)) {
// حفظ البيانات
echo "تم بنجاح!";
} else {
// عرض الأخطاء
foreach ($errors as $field => $error) {
echo "$error
";
}
}
?>
4. Validator Class (احترافي كامل)
data = $data;
$this->db = $db;
}
public function validate($rules) {
foreach ($rules as $field => $ruleString) {
$value = $this->data[$field] ?? '';
$rules = explode('|', $ruleString);
foreach ($rules as $rule) {
$this->applyRule($field, $value, $rule);
}
}
return empty($this->errors);
}
private function applyRule($field, $value, $rule) {
$param = null;
if (strpos($rule, ':') !== false) {
list($rule, $param) = explode(':', $rule, 2);
}
switch ($rule) {
case 'required':
if (empty($value) && $value !== '0') {
$this->addError($field, "$field مطلوب");
}
break;
case 'email':
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->addError($field, "$field يجب أن يكون بريد إلكتروني صحيح");
}
break;
case 'url':
if (!filter_var($value, FILTER_VALIDATE_URL)) {
$this->addError($field, "$field يجب أن يكون رابط صحيح");
}
break;
case 'min':
if (strlen($value) < $param) {
$this->addError($field, "$field يجب أن يكون $param أحرف على الأقل");
}
break;
case 'max':
if (strlen($value) > $param) {
$this->addError($field, "$field يجب ألا يتجاوز $param حرف");
}
break;
case 'between':
list($min, $max) = explode(',', $param);
$len = strlen($value);
if ($len < $min || $len > $max) {
$this->addError($field, "$field يجب أن يكون بين $min و $max حرف");
}
break;
case 'numeric':
if (!is_numeric($value)) {
$this->addError($field, "$field يجب أن يكون رقم");
}
break;
case 'integer':
if (!filter_var($value, FILTER_VALIDATE_INT)) {
$this->addError($field, "$field يجب أن يكون رقم صحيح");
}
break;
case 'alpha':
if (!preg_match('/^[a-zA-Z]+$/', $value)) {
$this->addError($field, "$field يجب أن يحتوي على حروف فقط");
}
break;
case 'alphanumeric':
if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) {
$this->addError($field, "$field يجب أن يحتوي على حروف وأرقام فقط");
}
break;
case 'same':
if ($value !== ($this->data[$param] ?? '')) {
$this->addError($field, "$field يجب أن يطابق $param");
}
break;
case 'different':
if ($value === ($this->data[$param] ?? '')) {
$this->addError($field, "$field يجب أن يختلف عن $param");
}
break;
case 'in':
$allowed = explode(',', $param);
if (!in_array($value, $allowed)) {
$this->addError($field, "$field غير صحيح");
}
break;
case 'regex':
if (!preg_match($param, $value)) {
$this->addError($field, "$field غير صحيح");
}
break;
case 'phone':
if (!preg_match('/^05[0-9]{8}$/', $value)) {
$this->addError($field, "$field يجب أن يكون رقم جوال صحيح (مثال: 0501234567)");
}
break;
case 'unique':
if ($this->db) {
list($table, $column) = explode(',', $param);
$exists = $this->db->getValue("SELECT COUNT(*) FROM $table WHERE $column = ?", [$value]);
if ($exists > 0) {
$this->addError($field, "$field موجود مسبقاً");
}
}
break;
case 'exists':
if ($this->db) {
list($table, $column) = explode(',', $param);
$exists = $this->db->getValue("SELECT COUNT(*) FROM $table WHERE $column = ?", [$value]);
if ($exists == 0) {
$this->addError($field, "$field غير موجود");
}
}
break;
}
}
private function addError($field, $message) {
if (!isset($this->errors[$field])) {
$this->errors[$field] = [];
}
$this->errors[$field][] = $message;
}
public function getErrors() {
return $this->errors;
}
public function getFirstError($field) {
return $this->errors[$field][0] ?? null;
}
public function hasError($field) {
return isset($this->errors[$field]);
}
}
// الاستخدام
$validator = new Validator($_POST, $db);
$isValid = $validator->validate([
'username' => 'required|min:3|max:20|alphanumeric|unique:users,username',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8',
'confirm_password' => 'required|same:password',
'age' => 'required|integer|min:18',
'phone' => 'required|phone',
'city' => 'required|in:الرياض,جدة,الدمام',
'website' => 'url'
]);
if ($isValid) {
// البيانات صحيحة
echo "تم التحقق بنجاح!";
} else {
// عرض الأخطاء
$errors = $validator->getErrors();
foreach ($errors as $field => $fieldErrors) {
foreach ($fieldErrors as $error) {
echo "$error
";
}
}
}
// أو في HTML
?>
5. CSRF Protection (حماية من هجمات CSRF)
'; } } // استخدام أسهل ?>
💡 نصائح مهمة للـ Forms:
- نظف وفلتر جميع المدخلات دائماً
- استخدم POST للبيانات الحساسة
- طبق CSRF Protection على كل Forms
- استخدم HTTPS دائماً
- لا تثق بأي مدخل من المستخدم
📁 التعامل مع الملفات الكامل
1. رفع الملفات (File Upload)
$maxSize) {
die("حجم الملف كبير جداً! الحد الأقصى 5MB");
}
// 2. التحقق من الامتداد
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'];
$fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if (!in_array($fileExtension, $allowedExtensions)) {
die("نوع الملف غير مسموح! المسموح: " . implode(', ', $allowedExtensions));
}
// 3. التحقق من النوع الحقيقي (MIME Type)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $fileTmpName);
finfo_close($finfo);
$allowedMimes = [
'image/jpeg', 'image/png', 'image/gif',
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
if (!in_array($mimeType, $allowedMimes)) {
die("نوع الملف غير مسموح!");
}
// 4. إنشاء اسم فريد وآمن
$newFileName = uniqid('file_', true) . '.' . $fileExtension;
// 5. تحديد مجلد الحفظ
$uploadDir = 'uploads/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$destination = $uploadDir . $newFileName;
// 6. نقل الملف
if (move_uploaded_file($fileTmpName, $destination)) {
echo "تم رفع الملف بنجاح!";
echo "
اسم الملف: $newFileName";
echo "
الحجم: " . formatBytes($fileSize);
// حفظ معلومات الملف في قاعدة البيانات
$db->insert('files', [
'original_name' => $fileName,
'saved_name' => $newFileName,
'file_size' => $fileSize,
'file_type' => $fileExtension,
'uploaded_at' => date('Y-m-d H:i:s')
]);
} else {
die("فشل رفع الملف!");
}
} else {
// معالجة الأخطاء
$uploadErrors = [
UPLOAD_ERR_INI_SIZE => 'الملف أكبر من upload_max_filesize',
UPLOAD_ERR_FORM_SIZE => 'الملف أكبر من MAX_FILE_SIZE',
UPLOAD_ERR_PARTIAL => 'تم رفع جزء من الملف فقط',
UPLOAD_ERR_NO_FILE => 'لم يتم رفع ملف',
UPLOAD_ERR_NO_TMP_DIR => 'مجلد مؤقت مفقود',
UPLOAD_ERR_CANT_WRITE => 'فشل كتابة الملف',
UPLOAD_ERR_EXTENSION => 'امتداد PHP أوقف رفع الملف'
];
$errorMsg = $uploadErrors[$fileError] ?? 'خطأ غير معروف';
die("خطأ في رفع الملف: $errorMsg");
}
// دالة لتنسيق حجم الملف
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
?>
2. رفع ملفات متعددة
3. FileUpload Class (احترافي كامل)
uploadDir = rtrim($uploadDir, '/') . '/';
if (!is_dir($this->uploadDir)) {
mkdir($this->uploadDir, 0755, true);
}
// إضافة .htaccess للحماية
$this->createHtaccess();
}
private function createHtaccess() {
$htaccess = $this->uploadDir . '.htaccess';
if (!file_exists($htaccess)) {
$content = "php_flag engine off\n";
$content .= "Options -Indexes\n";
file_put_contents($htaccess, $content);
}
}
public function setAllowedTypes($types) {
$this->allowedTypes = $types;
return $this;
}
public function setMaxSize($bytes) {
$this->maxSize = $bytes;
return $this;
}
public function upload($file) {
if ($file['error'] !== UPLOAD_ERR_OK) {
$this->errors[] = 'خطأ في رفع الملف';
return false;
}
if ($file['size'] > $this->maxSize) {
$this->errors[] = 'حجم الملف كبير جداً';
return false;
}
$extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($extension, $this->allowedTypes)) {
$this->errors[] = 'نوع الملف غير مسموح';
return false;
}
// التحقق من MIME Type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
$allowedMimes = [
'image/jpeg', 'image/png', 'image/gif', 'application/pdf'
];
if (!in_array($mimeType, $allowedMimes)) {
$this->errors[] = 'نوع الملف غير مسموح';
return false;
}
$newName = bin2hex(random_bytes(16)) . '.' . $extension;
$destination = $this->uploadDir . $newName;
if (move_uploaded_file($file['tmp_name'], $destination)) {
return [
'success' => true,
'name' => $newName,
'path' => $destination,
'size' => $file['size'],
'extension' => $extension,
'original_name' => $file['name']
];
}
$this->errors[] = 'فشل في حفظ الملف';
return false;
}
public function uploadMultiple($files) {
$uploaded = [];
$count = count($files['name']);
for ($i = 0; $i < $count; $i++) {
$file = [
'name' => $files['name'][$i],
'type' => $files['type'][$i],
'tmp_name' => $files['tmp_name'][$i],
'error' => $files['error'][$i],
'size' => $files['size'][$i]
];
$result = $this->upload($file);
if ($result) {
$uploaded[] = $result;
}
}
return $uploaded;
}
public function delete($filename) {
$filepath = $this->uploadDir . $filename;
if (file_exists($filepath)) {
return unlink($filepath);
}
return false;
}
public function getErrors() {
return $this->errors;
}
}
// الاستخدام
$uploader = new FileUpload('uploads/documents/');
$uploader->setAllowedTypes(['pdf', 'doc', 'docx'])
->setMaxSize(10 * 1024 * 1024); // 10MB
if (isset($_FILES['document'])) {
$result = $uploader->upload($_FILES['document']);
if ($result) {
echo "تم رفع الملف: " . $result['name'];
// حفظ في قاعدة البيانات
$db->insert('documents', [
'filename' => $result['name'],
'original_name' => $result['original_name'],
'file_size' => $result['size'],
'uploaded_at' => date('Y-m-d H:i:s')
]);
} else {
foreach ($uploader->getErrors() as $error) {
echo "$error
";
}
}
}
// رفع ملفات متعددة
if (isset($_FILES['files'])) {
$results = $uploader->uploadMultiple($_FILES['files']);
echo "تم رفع " . count($results) . " ملفات";
}
?>
4. معالجة الصور
$x,
'y' => $y,
'width' => $width,
'height' => $height
]);
imagejpeg($cropped, $destination, 90);
imagedestroy($image);
imagedestroy($cropped);
}
// إضافة Watermark
function addWatermark($source, $watermarkPath, $destination, $position = 'bottom-right') {
$image = imagecreatefromjpeg($source);
$watermark = imagecreatefrompng($watermarkPath);
$imageWidth = imagesx($image);
$imageHeight = imagesy($image);
$watermarkWidth = imagesx($watermark);
$watermarkHeight = imagesy($watermark);
// حساب الموضع
switch ($position) {
case 'bottom-right':
$x = $imageWidth - $watermarkWidth - 10;
$y = $imageHeight - $watermarkHeight - 10;
break;
case 'bottom-left':
$x = 10;
$y = $imageHeight - $watermarkHeight - 10;
break;
case 'top-right':
$x = $imageWidth - $watermarkWidth - 10;
$y = 10;
break;
case 'top-left':
$x = 10;
$y = 10;
break;
case 'center':
$x = ($imageWidth - $watermarkWidth) / 2;
$y = ($imageHeight - $watermarkHeight) / 2;
break;
default:
$x = 10;
$y = 10;
}
imagecopy($image, $watermark, $x, $y, 0, 0, $watermarkWidth, $watermarkHeight);
imagejpeg($image, $destination, 90);
imagedestroy($image);
imagedestroy($watermark);
}
// Image Class احترافي
class ImageProcessor {
private $image;
private $width;
private $height;
private $type;
public function __construct($path) {
list($this->width, $this->height, $this->type) = getimagesize($path);
switch ($this->type) {
case IMAGETYPE_JPEG:
$this->image = imagecreatefromjpeg($path);
break;
case IMAGETYPE_PNG:
$this->image = imagecreatefrompng($path);
break;
case IMAGETYPE_GIF:
$this->image = imagecreatefromgif($path);
break;
default:
throw new Exception("نوع الصورة غير مدعوم");
}
}
public function resize($width, $height) {
$ratio = min($width / $this->width, $height / $this->height);
$newWidth = $this->width * $ratio;
$newHeight = $this->height * $ratio;
$newImage = imagecreatetruecolor($newWidth, $newHeight);
if ($this->type == IMAGETYPE_PNG) {
imagealphablending($newImage, false);
imagesavealpha($newImage, true);
}
imagecopyresampled($newImage, $this->image, 0, 0, 0, 0,
$newWidth, $newHeight, $this->width, $this->height);
imagedestroy($this->image);
$this->image = $newImage;
$this->width = $newWidth;
$this->height = $newHeight;
return $this;
}
public function crop($x, $y, $width, $height) {
$cropped = imagecrop($this->image, [
'x' => $x, 'y' => $y,
'width' => $width, 'height' => $height
]);
imagedestroy($this->image);
$this->image = $cropped;
$this->width = $width;
$this->height = $height;
return $this;
}
public function save($path, $quality = 90) {
switch ($this->type) {
case IMAGETYPE_JPEG:
imagejpeg($this->image, $path, $quality);
break;
case IMAGETYPE_PNG:
imagepng($this->image, $path, 9);
break;
case IMAGETYPE_GIF:
imagegif($this->image, $path);
break;
}
return $this;
}
public function __destruct() {
if ($this->image) {
imagedestroy($this->image);
}
}
}
// الاستخدام
$img = new ImageProcessor('original.jpg');
$img->resize(800, 600)->save('resized.jpg');
$img2 = new ImageProcessor('photo.jpg');
$img2->crop(100, 100, 400, 400)->resize(200, 200)->save('thumbnail.jpg');
?>
⚠️ نصائح أمنية للملفات:
- تحقق من نوع الملف الحقيقي (MIME) وليس الامتداد فقط
- استخدم أسماء عشوائية للملفات
- احفظ الملفات خارج المجلد العام أو أضف .htaccess
- حدد حجم أقصى للملفات
- لا تثق بأسماء الملفات من المستخدم
🌐 APIs - REST API الكامل
1. إنشاء REST API
false, 'message' => $message], $statusCode);
}
// Users API
if ($segments[1] === 'users') {
switch ($method) {
case 'GET':
// GET /api/users - جلب كل المستخدمين
// GET /api/users/123 - جلب مستخدم محدد
if (isset($segments[2])) {
$id = (int)$segments[2];
$user = $db->getOne("SELECT id, name, email, city FROM users WHERE id = ?", [$id]);
if ($user) {
sendResponse(['success' => true, 'data' => $user]);
} else {
sendError('المستخدم غير موجود', 404);
}
} else {
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 10;
$offset = ($page - 1) * $limit;
$users = $db->getAll(
"SELECT id, name, email, city FROM users LIMIT ? OFFSET ?",
[$limit, $offset]
);
$total = $db->getValue("SELECT COUNT(*) FROM users");
sendResponse([
'success' => true,
'data' => $users,
'pagination' => [
'total' => $total,
'page' => $page,
'limit' => $limit,
'pages' => ceil($total / $limit)
]
]);
}
break;
case 'POST':
// POST /api/users - إضافة مستخدم جديد
if (empty($input['name']) || empty($input['email'])) {
sendError('الاسم والبريد مطلوبان');
}
// التحقق من البريد
if (!filter_var($input['email'], FILTER_VALIDATE_EMAIL)) {
sendError('البريد الإلكتروني غير صحيح');
}
// التحقق من التكرار
$exists = $db->getValue("SELECT COUNT(*) FROM users WHERE email = ?", [$input['email']]);
if ($exists > 0) {
sendError('البريد موجود مسبقاً', 409);
}
try {
$userId = $db->insert('users', [
'name' => $input['name'],
'email' => $input['email'],
'age' => $input['age'] ?? null,
'city' => $input['city'] ?? null,
'created_at' => date('Y-m-d H:i:s')
]);
sendResponse([
'success' => true,
'message' => 'تم إضافة المستخدم',
'id' => $userId
], 201);
} catch (Exception $e) {
sendError('فشل إضافة المستخدم', 500);
}
break;
case 'PUT':
// PUT /api/users/123 - تحديث مستخدم
if (!isset($segments[2])) {
sendError('ID مطلوب');
}
$id = (int)$segments[2];
$user = $db->getOne("SELECT id FROM users WHERE id = ?", [$id]);
if (!$user) {
sendError('المستخدم غير موجود', 404);
}
$updateData = [];
if (isset($input['name'])) $updateData['name'] = $input['name'];
if (isset($input['email'])) $updateData['email'] = $input['email'];
if (isset($input['age'])) $updateData['age'] = $input['age'];
if (isset($input['city'])) $updateData['city'] = $input['city'];
if (empty($updateData)) {
sendError('لا توجد بيانات للتحديث');
}
$updateData['updated_at'] = date('Y-m-d H:i:s');
$affected = $db->update('users', $updateData, 'id = ?', [$id]);
sendResponse([
'success' => true,
'message' => 'تم التحديث',
'affected' => $affected
]);
break;
case 'DELETE':
// DELETE /api/users/123 - حذف مستخدم
if (!isset($segments[2])) {
sendError('ID مطلوب');
}
$id = (int)$segments[2];
$deleted = $db->delete('users', 'id = ?', [$id]);
if ($deleted > 0) {
sendResponse([
'success' => true,
'message' => 'تم الحذف'
]);
} else {
sendError('المستخدم غير موجود', 404);
}
break;
default:
sendError('طريقة الطلب غير مدعومة', 405);
}
} else {
sendError('Endpoint غير موجود', 404);
}
?>
2. JWT Authentication
'JWT', 'alg' => 'HS256']);
$header = base64UrlEncode($header);
$payload = base64UrlEncode(json_encode($payload));
$signature = hash_hmac('sha256', "$header.$payload", $secret, true);
$signature = base64UrlEncode($signature);
return "$header.$payload.$signature";
}
function verifyJWT($token, $secret) {
$parts = explode('.', $token);
if (count($parts) !== 3) {
return false;
}
list($header, $payload, $signature) = $parts;
$validSignature = base64UrlEncode(
hash_hmac('sha256', "$header.$payload", $secret, true)
);
if ($signature !== $validSignature) {
return false;
}
$payload = json_decode(base64UrlDecode($payload), true);
// التحقق من انتهاء الصلاحية
if (isset($payload['exp']) && time() > $payload['exp']) {
return false;
}
return $payload;
}
// auth.php - نظام المصادقة
$secret = 'your-secret-key-change-this';
// Login
if ($_SERVER['REQUEST_URI'] === '/api/auth/login' && $_SERVER['REQUEST_METHOD'] === 'POST') {
$input = json_decode(file_get_contents('php://input'), true);
$email = $input['email'] ?? '';
$password = $input['password'] ?? '';
$user = $db->getOne("SELECT * FROM users WHERE email = ?", [$email]);
if ($user && password_verify($password, $user['password'])) {
$payload = [
'user_id' => $user['id'],
'email' => $user['email'],
'role' => $user['role'],
'iat' => time(),
'exp' => time() + (3600 * 24) // 24 ساعة
];
$token = createJWT($payload, $secret);
sendResponse([
'success' => true,
'token' => $token,
'user' => [
'id' => $user['id'],
'name' => $user['name'],
'email' => $user['email']
]
]);
} else {
sendError('البريد أو الباسورد خطأ', 401);
}
}
// Middleware للتحقق من Token
function requireAuth($secret) {
$headers = getallheaders();
$authHeader = $headers['Authorization'] ?? '';
if (!preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
sendError('Token مطلوب', 401);
}
$token = $matches[1];
$payload = verifyJWT($token, $secret);
if (!$payload) {
sendError('Token غير صحيح أو منتهي الصلاحية', 401);
}
return $payload;
}
// استخدام في API محمي
$user = requireAuth($secret);
// الآن $user يحتوي على بيانات المستخدم من Token
?>
3. استهلاك APIs خارجية
$httpCode,
'data' => json_decode($response, true)
];
}
// POST Request
function apiPost($url, $data, $headers = []) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge([
'Content-Type: application/json'
], $headers));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'status' => $httpCode,
'data' => json_decode($response, true)
];
}
// PUT Request
function apiPut($url, $data, $headers = []) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge([
'Content-Type: application/json'
], $headers));
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// DELETE Request
function apiDelete($url, $headers = []) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// API Class احترافي
class APIClient {
private $baseUrl;
private $headers = [];
public function __construct($baseUrl) {
$this->baseUrl = rtrim($baseUrl, '/');
}
public function setHeader($key, $value) {
$this->headers[] = "$key: $value";
return $this;
}
public function setToken($token) {
$this->setHeader('Authorization', "Bearer $token");
return $this;
}
public function get($endpoint, $params = []) {
$url = $this->baseUrl . '/' . ltrim($endpoint, '/');
if (!empty($params)) {
$url .= '?' . http_build_query($params);
}
return apiGet($url, $this->headers);
}
public function post($endpoint, $data) {
$url = $this->baseUrl . '/' . ltrim($endpoint, '/');
return apiPost($url, $data, $this->headers);
}
public function put($endpoint, $data) {
$url = $this->baseUrl . '/' . ltrim($endpoint, '/');
return apiPut($url, $data, $this->headers);
}
public function delete($endpoint) {
$url = $this->baseUrl . '/' . ltrim($endpoint, '/');
return apiDelete($url, $this->headers);
}
}
// الاستخدام
$api = new APIClient('https://api.example.com');
$api->setToken('your-token-here');
// GET
$result = $api->get('/users', ['page' => 1, 'limit' => 10]);
print_r($result['data']);
// POST
$result = $api->post('/users', [
'name' => 'أحمد',
'email' => 'ahmed@example.com'
]);
// PUT
$result = $api->put('/users/123', [
'name' => 'أحمد المحدث'
]);
// DELETE
$result = $api->delete('/users/123');
?>
✅ تمام! الآن عندك:
- REST API كامل مع CRUD
- JWT Authentication
- استهلاك APIs خارجية
- Classes احترافية جاهزة
🛡️ الأمان (Security) - كامل
1. SQL Injection Protection
prepare($sql); $stmt->execute([$id]); $user = $stmt->fetch(); // Named Parameters (أفضل للقراءة) $sql = "SELECT * FROM users WHERE email = :email AND status = :status"; $stmt = $pdo->prepare($sql); $stmt->execute([':email' => $email, ':status' => 'active']); ?>
2. XSS Protection (Cross-Site Scripting)
alert('XSS')";
// ✅ استخدم htmlspecialchars دائماً
echo htmlspecialchars($username, ENT_QUOTES, 'UTF-8');
// النتيجة: <script>alert('XSS')</script>
// دوال مساعدة
function escape($string) {
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
}
function escapeJS($string) {
return json_encode($string, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
}
// في HTML
echo '';
// في JavaScript
echo '';
// للـ HTML الغني (Rich Text)
function sanitizeHTML($html) {
// السماح ببعض Tags الآمنة فقط
$allowed = '
3. CSRF Protection (كامل)
self::$tokenExpiry) {
$_SESSION[self::$tokenName] = bin2hex(random_bytes(32));
$_SESSION[self::$tokenName . '_time'] = time();
}
return $_SESSION[self::$tokenName];
}
public static function verify($token) {
if (!isset($_SESSION[self::$tokenName]) ||
!isset($_SESSION[self::$tokenName . '_time'])) {
return false;
}
// التحقق من انتهاء الصلاحية
if ((time() - $_SESSION[self::$tokenName . '_time']) > self::$tokenExpiry) {
return false;
}
// التحقق من Token
$valid = hash_equals($_SESSION[self::$tokenName], $token);
if ($valid) {
self::regenerate();
}
return $valid;
}
public static function regenerate() {
$_SESSION[self::$tokenName] = bin2hex(random_bytes(32));
$_SESSION[self::$tokenName . '_time'] = time();
}
public static function field() {
return '';
}
public static function meta() {
return '';
}
}
// استخدام
?>
4. Password Security (كامل)
12]; // زيادة القوة (default: 10)
$password = password_hash($_POST['password'], PASSWORD_DEFAULT, $options);
// حفظ في قاعدة البيانات
$db->insert('users', [
'email' => $email,
'password' => $password
]);
// التحقق من الباسورد
$user = $db->getOne("SELECT * FROM users WHERE email = ?", [$email]);
if ($user && password_verify($_POST['password'], $user['password'])) {
// صحيح
echo "تم تسجيل الدخول!";
// إعادة تشفير إذا احتاج
if (password_needs_rehash($user['password'], PASSWORD_DEFAULT)) {
$newHash = password_hash($_POST['password'], PASSWORD_DEFAULT);
$db->update('users', ['password' => $newHash], 'id = ?', [$user['id']]);
}
} else {
echo "البريد أو الباسورد خطأ!";
}
// التحقق من قوة الباسورد
function isStrongPassword($password) {
$errors = [];
if (strlen($password) < 8) {
$errors[] = 'يجب أن يكون 8 أحرف على الأقل';
}
if (!preg_match('/[A-Z]/', $password)) {
$errors[] = 'يجب أن يحتوي على حرف كبير';
}
if (!preg_match('/[a-z]/', $password)) {
$errors[] = 'يجب أن يحتوي على حرف صغير';
}
if (!preg_match('/[0-9]/', $password)) {
$errors[] = 'يجب أن يحتوي على رقم';
}
if (!preg_match('/[^A-Za-z0-9]/', $password)) {
$errors[] = 'يجب أن يحتوي على رمز خاص (!@#$%^&*)';
}
return empty($errors) ? true : $errors;
}
// Password Reset (آمن)
function generatePasswordResetToken($userId, $db) {
$token = bin2hex(random_bytes(32));
$hashedToken = hash('sha256', $token);
$expires = date('Y-m-d H:i:s', time() + 3600); // ساعة واحدة
$db->update('users',
['reset_token' => $hashedToken, 'reset_expires' => $expires],
'id = ?',
[$userId]
);
return $token; // أرسله للبريد
}
function verifyPasswordResetToken($token, $db) {
$hashedToken = hash('sha256', $token);
$user = $db->getOne(
"SELECT * FROM users WHERE reset_token = ? AND reset_expires > NOW()",
[$hashedToken]
);
return $user;
}
?>
5. Session Security (شامل)
0,
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Strict',
'use_strict_mode' => true,
'sid_length' => 48,
'sid_bits_per_character' => 6
]);
// Session Timeout
function checkTimeout($timeout = 1800) {
if (isset($_SESSION['last_activity']) &&
(time() - $_SESSION['last_activity'] > $timeout)) {
session_unset();
session_destroy();
return false;
}
$_SESSION['last_activity'] = time();
return true;
}
// Session Fingerprinting
function getFingerprint() {
return hash('sha256',
($_SERVER['HTTP_USER_AGENT'] ?? '') .
($_SERVER['REMOTE_ADDR'] ?? '') .
'your-secret-salt'
);
}
function validateFingerprint() {
if (!isset($_SESSION['fingerprint'])) {
$_SESSION['fingerprint'] = getFingerprint();
}
return $_SESSION['fingerprint'] === getFingerprint();
}
// IP Validation
function validateIP() {
if (!isset($_SESSION['ip'])) {
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}
return $_SESSION['ip'] === $_SERVER['REMOTE_ADDR'];
}
// Session Manager Class
class SessionManager {
public static function start() {
if (session_status() === PHP_SESSION_NONE) {
session_start([
'cookie_lifetime' => 0,
'cookie_httponly' => true,
'cookie_secure' => true,
'cookie_samesite' => 'Strict'
]);
}
if (!self::validate()) {
self::destroy();
return false;
}
self::regenerateIfNeeded();
return true;
}
private static function validate() {
return checkTimeout() && validateFingerprint();
}
private static function regenerateIfNeeded() {
if (!isset($_SESSION['regenerated'])) {
$_SESSION['regenerated'] = time();
}
// تجديد كل 30 دقيقة
if (time() - $_SESSION['regenerated'] > 1800) {
session_regenerate_id(true);
$_SESSION['regenerated'] = time();
}
}
public static function destroy() {
session_unset();
session_destroy();
setcookie(session_name(), '', time() - 3600, '/');
}
}
?>
6. Security Headers
7. Input Validation (شامل)
') { return strip_tags($html, $allowedTags); } } // استخدام if (!SecurityValidator::email($_POST['email'])) { die('البريد غير صحيح'); } if (!SecurityValidator::saudiPhone($_POST['phone'])) { die('رقم الجوال غير صحيح'); } ?>
⚠️ قائمة الأمان الكاملة:
- ✅ استخدم Prepared Statements دائماً
- ✅ استخدم htmlspecialchars() للـ Output
- ✅ طبق CSRF Protection
- ✅ استخدم password_hash() للباسوردات
- ✅ فعّل HTTPS
- ✅ أضف Security Headers
- ✅ نظف جميع المدخلات
- ✅ استخدم Sessions آمنة
- ✅ أخفي الأخطاء في Production
- ✅ حدّث PHP والمكتبات بانتظام
🎯 Object-Oriented PHP (OOP) - كامل
1. Classes & Objects الأساسيات
<?php
class User {
// Properties - الخصائص
public $name;
public $email;
private $password;
protected $role;
// Constructor - المنشئ
public function __construct($name, $email, $password) {
$this->name = $name;
$this->email = $email;
$this->password = password_hash($password, PASSWORD_DEFAULT);
$this->role = 'user';
}
// Methods - الدوال
public function introduce() {
return "مرحباً، أنا {$this->name}";
}
// Getter - جلب البيانات
public function getRole() {
return $this->role;
}
// Setter - تعديل البيانات
public function setRole($role) {
$allowedRoles = ['user', 'admin', 'moderator'];
if (in_array($role, $allowedRoles)) {
$this->role = $role;
return true;
}
return false;
}
public function verifyPassword($password) {
return password_verify($password, $this->password);
}
// Static Method - دالة ثابتة
public static function validateEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
}
// إنشاء Objects
$user1 = new User("أحمد", "ahmed@example.com", "password123");
$user2 = new User("فاطمة", "fatima@example.com", "pass456");
echo $user1->introduce(); // مرحباً، أنا أحمد
$user1->setRole('admin');
echo $user1->getRole(); // admin
// Static Method
if (User::validateEmail("test@example.com")) {
echo "البريد صحيح";
}
?>
2. Inheritance الوراثة
<?php
// Parent Class - الكلاس الأساسي
class Person {
protected $name;
protected $age;
protected $email;
public function __construct($name, $age, $email) {
$this->name = $name;
$this->age = $age;
$this->email = $email;
}
public function introduce() {
return "أنا {$this->name}، عمري {$this->age} سنة";
}
}
// Child Class - الكلاس الابن
class Student extends Person {
private $studentId;
private $grade;
public function __construct($name, $age, $email, $studentId, $grade) {
parent::__construct($name, $age, $email);
$this->studentId = $studentId;
$this->grade = $grade;
}
// Override Method - تعديل الدالة
public function introduce() {
return parent::introduce() . "، طالب في الصف {$this->grade}";
}
public function study($subject) {
return "{$this->name} يدرس {$subject}";
}
}
class Teacher extends Person {
private $subject;
private $salary;
public function __construct($name, $age, $email, $subject, $salary) {
parent::__construct($name, $age, $email);
$this->subject = $subject;
$this->salary = $salary;
}
public function teach() {
return "{$this->name} يدرّس {$this->subject}";
}
}
// استخدام
$student = new Student("أحمد", 16, "ahmed@school.com", "S12345", "العاشر");
echo $student->introduce(); // أنا أحمد، عمري 16 سنة، طالب في الصف العاشر
$teacher = new Teacher("فاطمة", 32, "fatima@school.com", "الفيزياء", 8000);
echo $teacher->teach(); // فاطمة يدرّس الفيزياء
?>
3. Abstract Classes & Interfaces
<?php
// Abstract Class - كلاس مجرد
abstract class Animal {
protected $name;
protected $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
// Abstract Method - يجب تطبيقه في الأبناء
abstract public function makeSound();
abstract public function move();
// Method عادي
public function sleep() {
return "{$this->name} ينام";
}
}
class Dog extends Animal {
public function makeSound() {
return "نباح!";
}
public function move() {
return "{$this->name} يركض";
}
}
class Cat extends Animal {
public function makeSound() {
return "مواء!";
}
public function move() {
return "{$this->name} يتسلق";
}
}
// Interface - واجهة
interface PaymentInterface {
public function processPayment($amount);
public function refund($transactionId);
public function getBalance();
}
class CreditCard implements PaymentInterface {
private $balance = 10000;
public function processPayment($amount) {
if ($this->balance >= $amount) {
$this->balance -= $amount;
return "تم الدفع {$amount} ريال بالبطاقة";
}
return "الرصيد غير كافٍ";
}
public function refund($transactionId) {
return "تم استرجاع المبلغ";
}
public function getBalance() {
return $this->balance;
}
}
// استخدام
$dog = new Dog("ريكس", 3);
echo $dog->makeSound(); // نباح!
echo $dog->move(); // ريكس يركض
$card = new CreditCard();
echo $card->processPayment(500);
?>
4. Traits السمات
<?php
// Trait للميزات المشتركة
trait Timestampable {
public $createdAt;
public $updatedAt;
public function setCreatedAt() {
$this->createdAt = date('Y-m-d H:i:s');
}
public function setUpdatedAt() {
$this->updatedAt = date('Y-m-d H:i:s');
}
}
trait Sluggable {
public function generateSlug($text) {
$text = strtolower($text);
$text = preg_replace('/[^a-z0-9\s-]/', '', $text);
$text = preg_replace('/[\s-]+/', '-', $text);
return trim($text, '-');
}
}
// استخدام أكثر من Trait
class Article {
use Timestampable, Sluggable;
public $title;
public $content;
public $slug;
public function __construct($title, $content) {
$this->title = $title;
$this->content = $content;
$this->slug = $this->generateSlug($title);
$this->setCreatedAt();
$this->setUpdatedAt();
}
}
// استخدام
$article = new Article("مقال عن PHP", "محتوى المقال...");
echo $article->slug; // مقال-عن-php
echo $article->createdAt; // 2025-01-20 10:30:00
?>
5. Static Methods & Properties الثوابت
<?php
class Config {
private static $settings = [];
public static function set($key, $value) {
self::$settings[$key] = $value;
}
public static function get($key, $default = null) {
return self::$settings[$key] ?? $default;
}
}
// Singleton Pattern
class Database {
private static $instance = null;
private $pdo;
private function __construct() {
$this->pdo = new PDO("mysql:host=localhost;dbname=mydb", "root", "");
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// منع النسخ
private function __clone() {}
private function __wakeup() {}
}
// استخدام
Config::set('app_name', 'تطبيقي');
echo Config::get('app_name'); // تطبيقي
$db = Database::getInstance();
?>
✅ ملخص الـ OOP:
- Classes & Objects - الفئات والكائنات
- Inheritance - الوراثة
- Abstract Classes - الفئات المجردة
- Interfaces - الواجهات
- Traits - السمات
- Static Methods - الدوال الثابتة
- Design Patterns - أنماط التصميم
⚡ الدوال (Functions) - أهم 50 دالة
1. دوال النصوص (Strings)
<?php
// الطول والقص
strlen("مرحباً"); // 6
mb_strlen("مرحباً"); // 6 (لللغات العربية)
substr("Hello World", 0, 5); // "Hello"
mb_substr("مرحباً بالعالم", 0, 6); // "مرحباً"
// البحث والاستبدال
strpos("Hello World", "World"); // 6
str_replace("World", "PHP", "Hello World"); // "Hello PHP"
str_ireplace("world", "PHP", "Hello World"); // استبدال غير حساس لحالة الأحرف
// التحويل
strtolower("HELLO"); // "hello"
strtoupper("hello"); // "HELLO"
ucfirst("hello"); // "Hello"
ucwords("hello world"); // "Hello World"
// التنظيف والتنسيق
trim(" hello "); // "hello"
ltrim(" hello"); // "hello"
rtrim("hello "); // "hello"
htmlspecialchars("<script>"); // "<script>"
// المقارنة
strcmp("hello", "hello"); // 0 (متساويين)
strcasecmp("HELLO", "hello"); // 0 (غير حساس لحالة الأحرف)
// تقسيم ودمج
explode(" ", "hello world"); // ["hello", "world"]
implode(", ", ["a", "b", "c"]); // "a, b, c"
// التشفير
md5("password"); // تشفير MD5
sha1("password"); // تشفير SHA1
password_hash("password", PASSWORD_DEFAULT); // تشفير آمن
?>
2. دوال المصفوفات (Arrays)
<?php
// الإضافة والحذف
array_push($arr, "value"); // إضافة للنهاية
array_pop($arr); // حذف من النهاية
array_unshift($arr, "value"); // إضافة للبداية
array_shift($arr); // حذف من البداية
// البحث والتحقق
in_array("value", $arr); // true إذا موجود
array_search("value", $arr); // يرجع المفتاح
array_key_exists("key", $arr); // true إذا المفتاح موجود
// الدمج والترتيب
array_merge($arr1, $arr2); // دمج مصفوفتين
array_slice($arr, 2, 5); // قطع جزء
sort($arr); // ترتيب تصاعدي
rsort($arr); // ترتيب تنازلي
// العد والمعالجة
count($arr); // عدد العناصر
array_sum([1, 2, 3]); // 6
array_map(function($x) { return $x * 2; }, [1, 2, 3]); // [2, 4, 6]
?>
3. دوال التاريخ والوقت (Date & Time)
<?php
// التواريخ الأساسية
date('Y-m-d'); // 2025-01-20
date('d/m/Y'); // 20/01/2025
date('H:i:s'); // 14:30:25
time(); // الطابع الزمني الحالي
// DateTime Class
$date = new DateTime();
$date->format('Y-m-d H:i:s'); // 2025-01-20 14:30:25
$date->modify('+1 day'); // إضافة يوم
$date->modify('-2 weeks'); // طرح أسبوعين
// الفرق بين تاريخين
$date1 = new DateTime('2025-01-01');
$date2 = new DateTime('2025-01-20');
$diff = $date1->diff($date2);
echo $diff->days; // 19 يوم
// المنطقة الزمنية
date_default_timezone_set('Asia/Riyadh');
$date = new DateTime('now', new DateTimeZone('Asia/Riyadh'));
// التحويل من نص
strtotime('next Monday'); // الطابع الزمني للإثنين القادم
strtotime('+1 month'); // الطابع الزمني لشهر من الآن
?>
4. دوال الملفات (Files)
<?php
// القراءة والكتابة
file_get_contents('file.txt'); // قراءة الملف كامل
file_put_contents('file.txt', 'data'); // كتابة للملف
file_put_contents('file.txt', 'data', FILE_APPEND); // إضافة للنهاية
// المعلومات
file_exists('file.txt'); // التحقق من الوجود
filesize('file.txt'); // حجم الملف
is_readable('file.txt'); // قابل للقراءة؟
is_writable('file.txt'); // قابل للكتابة؟
// المجلدات
is_dir('folder'); // تحقق إذا مجلد
mkdir('new_folder'); // إنشاء مجلد
rmdir('folder'); // حذف مجلد
scandir('folder'); // عرض محتويات المجلد
// المسارات
basename('/path/to/file.txt'); // file.txt
dirname('/path/to/file.txt'); // /path/to
pathinfo('/path/to/file.txt'); // معلومات المسار
?>
5. دوال الرياضيات (Math)
<?php // العمليات الأساسية abs(-10); // 10 (قيمة مطلقة) round(3.7); // 4 (تقريب) ceil(3.2); // 4 (تقريب لأعلى) floor(3.8); // 3 (تقريب لأسفل) // الأسس والجذور pow(2, 3); // 8 (2^3) sqrt(16); // 4 (جذر تربيعي) exp(1); // e^1 // العشوائي rand(1, 100); // رقم عشوائي بين 1 و 100 mt_rand(1, 100); // أسرع وأفضل random_int(1, 100); // آمن للتشفير // الثوابت M_PI; // 3.1415926535898 M_E; // 2.718281828459 // اللوغاريتمات log(10); // ln(10) log10(100); // log10(100) = 2 // التنسيق number_format(1234567.89, 2, '.', ','); // 1,234,567.89 ?>
6. دوال JSON
<?php
// تحويل لـ JSON
$data = ['name' => 'أحمد', 'age' => 25];
$json = json_encode($data);
$json_pretty = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
// تحويل من JSON
$json = '{"name":"أحمد","age":25}';
$data = json_decode($json, true); // كمصفوفة
$obj = json_decode($json); // ككائن
// التحقق من الأخطاء
if (json_last_error() === JSON_ERROR_NONE) {
echo "JSON صحيح";
} else {
echo "خطأ في JSON: " . json_last_error_msg();
}
// خيارات متقدمة
json_encode($data,
JSON_PRETTY_PRINT |
JSON_UNESCAPED_UNICODE |
JSON_UNESCAPED_SLASHES |
JSON_NUMERIC_CHECK
);
?>
7. دوال متنوعة مهمة
<?php
// التحقق من الأنواع
is_int($var); // رقم صحيح؟
is_string($var); // نص؟
is_array($var); // مصفوفة؟
is_object($var); // كائن؟
is_null($var); // فارغ؟
// المتغيرات
isset($var); // موجودة وغير فارغة؟
empty($var); // فارغة؟
unset($var); // حذف المتغير
// الطباعة
echo "نص"; // طباعة
print "نص"; // طباعة
printf("اسمي %s وعمري %d", "أحمد", 25); // طباعة منسقة
// التضمين
include 'file.php'; // تضمين ملف
require 'file.php'; // تضمين ملف (مطلوب)
include_once 'file.php'; // تضمين مرة واحدة
require_once 'file.php'; // تضمين مرة واحدة (مطلوب)
// النظام
exec('ls -la', $output); // تنفيذ أمر نظام
shell_exec('whoami'); // تنفيذ أمر نظام
phpinfo(); // معلومات PHP
// الذاكرة والوقت
memory_get_usage(); // استخدام الذاكرة
memory_get_peak_usage(); // ذروة استخدام الذاكرة
microtime(true); // وقت دقيق
// التشفير
md5('text'); // MD5
sha1('text'); // SHA1
hash('sha256', 'text'); // SHA256
password_hash('pass', PASSWORD_DEFAULT); // تشفير آمن
password_verify('pass', $hash); // التحقق من الباسوورد
?>
✅ ملخص أهم الدوال:
- 50+ دالة أساسية ومهمة
- دوال النصوص والمصفوفات
- دوال التاريخ والوقت
- دوال الملفات والمجلدات
- دوال الرياضيات والتشفير
- دوال JSON والتحويل
❌ Error Handling - معالجة الأخطاء
1. Try-Catch (Exceptions)
<?php
// Try-Catch أساسي
try {
$pdo = new PDO("mysql:host=localhost;dbname=mydb", "root", "wrong");
} catch (PDOException $e) {
echo "خطأ في الاتصال: " . $e->getMessage();
} catch (Exception $e) {
echo "خطأ عام: " . $e->getMessage();
} finally {
echo "يتم تنفيذه دائماً";
}
// رمي Exception
function divide($a, $b) {
if ($b == 0) {
throw new Exception("لا يمكن القسمة على صفر");
}
return $a / $b;
}
try {
echo divide(10, 0);
} catch (Exception $e) {
echo $e->getMessage();
}
// Exception مخصص
class DatabaseException extends Exception {
public function errorMessage() {
return "خطأ في قاعدة البيانات [{$this->getCode()}]: {$this->getMessage()}";
}
}
class ValidationException extends Exception {}
try {
throw new DatabaseException("فشل الاتصال", 1001);
} catch (DatabaseException $e) {
echo $e->errorMessage();
}
// معلومات Exception
$e->getMessage(); // الرسالة
$e->getCode(); // الكود
$e->getFile(); // الملف
$e->getLine(); // رقم السطر
$e->getTrace(); // Stack trace
?>
2. Error Handler مخصص
<?php
// Error Handler
function customErrorHandler($errno, $errstr, $errfile, $errline) {
$errors = [
E_ERROR => 'خطأ فادح',
E_WARNING => 'تحذير',
E_NOTICE => 'ملاحظة',
E_USER_ERROR => 'خطأ مستخدم',
E_USER_WARNING => 'تحذير مستخدم',
E_USER_NOTICE => 'ملاحظة مستخدم'
];
$type = $errors[$errno] ?? 'خطأ';
$message = sprintf(
"[%s] %s في %s السطر %d\n%s\n",
date('Y-m-d H:i:s'),
$type,
$errfile,
$errline,
$errstr
);
// تسجيل في ملف
error_log($message, 3, 'errors.log');
// عرض في Development
if (ini_get('display_errors')) {
echo "<div style='background:#f8d7da;padding:10px;border:1px solid #dc3545;margin:10px 0'>";
echo "<strong>$type:</strong> $errstr<br>";
echo "<small>في $errfile السطر $errline</small>";
echo "</div>";
}
return true;
}
set_error_handler('customErrorHandler');
// Exception Handler
function customExceptionHandler($exception) {
$message = sprintf(
"[%s] Exception: %s في %s السطر %d\n",
date('Y-m-d H:i:s'),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
error_log($message, 3, 'exceptions.log');
http_response_code(500);
if (ini_get('display_errors')) {
echo "<h1>حدث خطأ</h1>";
echo "<p>" . htmlspecialchars($exception->getMessage()) . "</p>";
} else {
echo "<h1>عذراً، حدث خطأ</h1>";
}
}
set_exception_handler('customExceptionHandler');
?>
3. Logger Class (احترافي)
<?php
class Logger {
private $logFile;
private $levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'];
public function __construct($logFile = 'app.log') {
$this->logFile = $logFile;
// إنشاء المجلد إذا غير موجود
$dir = dirname($logFile);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
private function write($level, $message, $context = []) {
$timestamp = date('Y-m-d H:i:s');
$contextStr = !empty($context) ? ' ' . json_encode($context, JSON_UNESCAPED_UNICODE) : '';
$logMessage = "[$timestamp] $level: $message$contextStr\n";
file_put_contents($this->logFile, $logMessage, FILE_APPEND);
}
public function debug($message, $context = []) {
$this->write('DEBUG', $message, $context);
}
public function info($message, $context = []) {
$this->write('INFO', $message, $context);
}
public function warning($message, $context = []) {
$this->write('WARNING', $message, $context);
}
public function error($message, $context = []) {
$this->write('ERROR', $message, $context);
}
public function critical($message, $context = []) {
$this->write('CRITICAL', $message, $context);
}
public function exception(Exception $e) {
$this->error($e->getMessage(), [
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString()
]);
}
}
// استخدام
$logger = new Logger('logs/app.log');
$logger->info('بدء التطبيق');
$logger->debug('قيمة المتغير', ['var' => $value]);
$logger->warning('تحذير: الذاكرة منخفضة');
try {
// كود
} catch (Exception $e) {
$logger->exception($e);
}
?>
💡 أفضل الممارسات:
- استخدم Try-Catch للعمليات الحرجة
- سجّل جميع الأخطاء في ملفات
- أخفِ تفاصيل الأخطاء في Production
- استخدم Error Levels المناسبة
- راقب ملفات الأخطاء بانتظام
🐛 Debugging & Troubleshooting - التصحيح
1. أساسيات التصحيح (Debugging Basics)
<?php
// 1. var_dump() - لعرض معلومات مفصلة
var_dump($variable);
var_dump($_POST, $_GET, $_SESSION);
// 2. print_r() - لعرض المصفوفات بشكل منظم
echo "<pre>";
print_r($array);
echo "</pre>";
// 3. error_log() - تسجيل الأخطاء
error_log("حدث خطأ: " . $errorMessage);
error_log(print_r($data, true));
// 4. display_errors - إظهار الأخطاء
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// 5. التحقق من القيم
isset($variable); // إذا المتغير موجود
empty($variable); // إذا المتغير فارغ
is_null($variable); // إذا القيمة null
// 6. تتبع التنفيذ
debug_backtrace(); // تتبع مسار التنفيذ
debug_print_backtrace(); // طباعة مسار التنفيذ
?>
2. Debugging Class (احترافي)
<?php
class Debugger {
private static $startTime;
private static $queries = [];
private static $memoryUsage = [];
public static function start() {
self::$startTime = microtime(true);
self::log('بدء التصحيح');
}
public static function log($message, $data = null) {
$timestamp = date('Y-m-d H:i:s');
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$caller = $backtrace[1]['file'] . ':' . $backtrace[1]['line'];
$logMessage = "[$timestamp] $message | Caller: $caller";
if ($data !== null) {
$logMessage .= " | Data: " . print_r($data, true);
}
error_log($logMessage);
}
public static function dump($variable, $label = '') {
echo "<div style='background:#f8f9fa;border:1px solid #dee2e6;padding:15px;margin:10px 0;border-radius:5px;'>";
if ($label) {
echo "<h4 style='margin-top:0;color:#667eea;'>{$label}</h4>";
}
echo "<pre style='margin:0;'>";
var_dump($variable);
echo "</pre>";
echo "</div>";
}
public static function logQuery($sql, $params = []) {
self::$queries[] = [
'sql' => $sql,
'params' => $params,
'time' => microtime(true)
];
}
public static function getPerformanceStats() {
$endTime = microtime(true);
$executionTime = $endTime - self::$startTime;
$memoryPeak = memory_get_peak_usage(true) / 1024 / 1024; // MB
$queryCount = count(self::$queries);
return [
'execution_time' => round($executionTime, 4) . ' seconds',
'memory_peak' => round($memoryPeak, 2) . ' MB',
'query_count' => $queryCount,
'queries' => self::$queries
];
}
public static function showStats() {
$stats = self::getPerformanceStats();
self::dump($stats, 'Performance Statistics');
}
public static function benchmark($callback, $name = 'Benchmark') {
$start = microtime(true);
$startMemory = memory_get_usage();
$result = $callback();
$end = microtime(true);
$endMemory = memory_get_usage();
$time = $end - $start;
$memory = $endMemory - $startMemory;
self::log("$name - Time: " . round($time, 4) . "s, Memory: " . round($memory / 1024, 2) . "KB");
return $result;
}
}
// استخدام
Debugger::start();
// تسجيل استعلامات قاعدة البيانات
Debugger::logQuery("SELECT * FROM users", ['status' => 'active']);
Debugger::logQuery("UPDATE products SET stock = ?", [50]);
// عرض إحصائيات الأداء
Debugger::showStats();
// قياس أداء دالة
Debugger::benchmark(function() {
// كود تبي تقيس وقته
for ($i = 0; $i < 1000; $i++) {
$x = $i * $i;
}
}, "Loop Benchmark");
?>
3. الأخطاء الشائعة وحلولها
<?php
// 1. خطأ: Undefined variable
// ❌ خطأ
echo $undefinedVar;
// ✅ حل
echo isset($undefinedVar) ? $undefinedVar : 'القيمة الافتراضية';
echo $undefinedVar ?? 'القيمة الافتراضية'; // PHP 7+
// 2. خطأ: Undefined index
// ❌ خطأ
echo $_POST['username'];
// ✅ حل
echo $_POST['username'] ?? '';
echo isset($_POST['username']) ? $_POST['username'] : '';
// 3. خطأ: Call to undefined function
// ❌ خطأ
undefined_function();
// ✅ حل
if (function_exists('undefined_function')) {
undefined_function();
} else {
echo 'الدالة غير موجودة';
}
// 4. خطأ: Division by zero
// ❌ خطأ
echo 10 / 0;
// ✅ حل
if ($divisor != 0) {
echo 10 / $divisor;
} else {
echo 'لا يمكن القسمة على صفر';
}
// 5. خطأ: Maximum execution time exceeded
// ❌ حل مؤقت
set_time_limit(60); // زيادة الوقت
// ✅ حل حقيقي
// - تحسين الخوارزميات
// - استخدام Pagination للبيانات الكبيرة
// - تقليل تعقيد الكود
// 6. خطأ: Memory limit exceeded
// ❌ حل مؤقت
ini_set('memory_limit', '256M');
// ✅ حل حقيقي
// - unset() للمتغيرات الكبيرة
// - استخدام generators بدل arrays
// - تقسيم البيانات
// 7. خطأ في قاعدة البيانات
try {
$pdo = new PDO($dsn, $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
error_log("فشل الاتصال: " . $e->getMessage());
echo "خطأ في قاعدة البيانات";
}
// 8. خطأ في الـ JSON
$json = '{"name":"ahmed",}'; // JSON غير صحيح
$data = json_decode($json);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "خطأ في JSON: " . json_last_error_msg();
}
?>
4. أدوات متقدمة للتصحيح
<?php
// 1. Xdebug functions
if (function_exists('xdebug_break')) {
xdebug_break(); // نقطة توقف
}
// 2. Profiling
function startProfile() {
return [
'time' => microtime(true),
'memory' => memory_get_usage()
];
}
function endProfile($start, $label = 'Profile') {
$endTime = microtime(true);
$endMemory = memory_get_usage();
$time = $endTime - $start['time'];
$memory = $endMemory - $start['memory'];
echo "<div style='background:#e3f2fd;padding:10px;margin:5px 0;'>";
echo "<strong>{$label}:</strong> ";
echo "الوقت: " . round($time, 4) . "s | ";
echo "الذاكرة: " . round($memory / 1024, 2) . "KB";
echo "</div>";
}
// استخدام
$profile = startProfile();
// كود تبي تقيسه
endProfile($profile, 'My Code');
// 3. Query Logger
class QueryLogger {
private static $queries = [];
public static function log($sql, $params = [], $time = null) {
self::$queries[] = [
'sql' => $sql,
'params' => $params,
'time' => $time ?: microtime(true),
'backtrace' => debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5)
];
}
public static function getQueries() {
return self::$queries;
}
public static function showQueries() {
echo "<div style='background:#fff3cd;padding:15px;margin:10px 0;'>";
echo "<h4>استعلامات قاعدة البيانات (" . count(self::$queries) . ")</h4>";
foreach (self::$queries as $index => $query) {
echo "<div style='background:white;padding:10px;margin:5px 0;border:1px solid #ddd;'>";
echo "<strong>استعلام #" . ($index + 1) . "</strong><br>";
echo "SQL: " . htmlspecialchars($query['sql']) . "<br>";
echo "Params: " . print_r($query['params'], true) . "<br>";
echo "</div>";
}
echo "</div>";
}
}
// 4. Memory Debugger
class MemoryDebugger {
public static function getMemoryUsage() {
return [
'current' => memory_get_usage(true) / 1024 / 1024,
'peak' => memory_get_peak_usage(true) / 1024 / 1024
];
}
public static function logMemory($label = '') {
$memory = self::getMemoryUsage();
error_log("Memory {$label} - Current: {$memory['current']}MB, Peak: {$memory['peak']}MB");
}
public static function trackVariable($var, $label = 'Variable') {
$size = strlen(serialize($var));
error_log("{$label} size: " . round($size / 1024, 2) . "KB");
}
}
// استخدام
MemoryDebugger::logMemory('قبل العملية');
$bigArray = range(1, 10000);
MemoryDebugger::trackVariable($bigArray, 'Big Array');
MemoryDebugger::logMemory('بعد العملية');
?>
5. Debugging في JavaScript
// 1. console.log الأساسي
console.log('قيمة المتغير:', variable);
console.table(data); // لعرض البيانات كجدول
// 2. console.group للمجموعات
console.group('مجموعة التصحيح');
console.log('بيان 1');
console.log('بيان 2');
console.groupEnd();
// 3. console.time لقياس الوقت
console.time('عملية');
// كود تبي تقيسه
console.timeEnd('عملية');
// 4. console.trace لتتبع الاستدعاءات
function myFunction() {
console.trace('تتبع الاستدعاء');
}
// 5. breakpoints متقدمة
debugger; // نقطة توقف في الكود
// 6. التحقق من القيم
console.assert(condition, 'رسالة الخطأ');
// 7. تصفح البيانات المعقدة
console.dir(object); // لعرض الكائن بشكل مفصل
// 8. Debugging للـ AJAX
fetch('/api/data')
.then(response => {
console.log('الاستجابة:', response);
return response.json();
})
.then(data => {
console.log('البيانات:', data);
})
.catch(error => {
console.error('الخطأ:', error);
});
// 9. Performance API
const startTime = performance.now();
// كود تبي تقيسه
const endTime = performance.now();
console.log(`الوقت المستغرق: ${endTime - startTime} مللي ثانية`);
// 10. Event debugging
function addDebugListeners() {
document.addEventListener('click', function(e) {
console.log('نقر على:', e.target);
});
document.addEventListener('submit', function(e) {
console.log('إرسال فورم:', e.target);
e.preventDefault(); // لمنع الإرسال أثناء التصحيح
});
}
🐛 نصائح مهمة للتصحيح:
- استخدم
var_dump()وprint_r()لعرض البيانات - سجل الأخطاء في ملف باستخدام
error_log() - فعل
display_errorsفي بيئة التطوير فقط - استخدم
try-catchللعمليات الحرجة - تحقق من وجود المتغيرات قبل استخدامها
- استخدم أدوات المطور في المتصفح لتصحيح JavaScript
✅ أدوات التصحيح الموصى بها:
- Xdebug - لأدوات تصحيح متقدمة في PHP
- Chrome DevTools - لتصحيح JavaScript
- Postman - لاختبار الـ APIs
- MySQL Workbench - لتصحيح استعلامات قاعدة البيانات
- Visual Studio Code Debugger - لتصحيح متكامل