🏠 مرحباً بك في المرجع الكامل لـ 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 ?>
hasError('username')): ?> getFirstError('username') ?>

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)

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>"); // "&lt;script&gt;"

// المقارنة
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 - لتصحيح متكامل