🏠 مرحباً بك في دليل PHP الشامل
هذا المرجع الكامل يغطي كل ما تحتاجه في تطوير PHP من الأساسيات إلى المواضيع المتقدمة.
✨ ما الذي ستجده هنا:
- شرح مفصل لجميع مفاهيم PHP المهمة
- أمثلة عملية وجاهزة للاستخدام
- أفضل الممارسات والنصائح الأمنية
- كود قابل للنسخ واللصق مباشرة
📋 المحتويات:
1. الأساسيات
Variables, Arrays, Loops, Conditions
Variables, Arrays, Loops, Conditions
2. قواعد البيانات
MySQLi, PDO, CRUD Operations
MySQLi, PDO, CRUD Operations
3. Sessions & Forms
Authentication, POST/GET, Validation
Authentication, POST/GET, Validation
4. APIs & Security
REST APIs, Security Best Practices
REST APIs, Security Best Practices
💡 نصيحة: استخدم البحث في الأعلى للوصول السريع لأي موضوع تحتاجه!
📖 أساسيات PHP
1. المتغيرات (Variables)
1 [1] => 2 [2] => 3 ) var_dump($integer); // int(42) // التحقق من نوع المتغير is_string($string); // true is_int($integer); // true is_array($array); // true isset($string); // true - يتحقق إذا المتغير موجود empty($null); // true - يتحقق إذا المتغير فاضي ?>
2. المصفوفات (Arrays)
"أحمد",
"age" => 25,
"city" => "الرياض"
];
echo $person["name"]; // أحمد
// مصفوفة متعددة الأبعاد
$users = [
["name" => "أحمد", "age" => 25],
["name" => "فاطمة", "age" => 22],
["name" => "محمد", "age" => 30]
];
echo $users[1]["name"]; // فاطمة
// دوال مهمة للمصفوفات
count($fruits); // 3 - عدد العناصر
array_push($fruits, "مانجو"); // إضافة عنصر للنهاية
array_pop($fruits); // حذف آخر عنصر
array_shift($fruits); // حذف أول عنصر
array_unshift($fruits, "عنب"); // إضافة عنصر للبداية
in_array("تفاح", $fruits); // true - البحث في المصفوفة
array_search("موز", $fruits); // يرجع المفتاح
array_keys($person); // ["name", "age", "city"]
array_values($person); // ["أحمد", 25, "الرياض"]
// دمج مصفوفات
$merged = array_merge($fruits, ["كيوي", "فراولة"]);
// فلترة المصفوفة
$numbers = [1, 2, 3, 4, 5];
$even = array_filter($numbers, function($n) {
return $n % 2 == 0;
}); // [2, 4]
// تحويل المصفوفة
$doubled = array_map(function($n) {
return $n * 2;
}, $numbers); // [2, 4, 6, 8, 10]
?>
3. الحلقات (Loops)
"أحمد", "age" => 25];
foreach ($person as $key => $value) {
echo "$key: $value "; // name: أحمد age: 25
}
// Break & Continue
for ($i = 0; $i < 10; $i++) {
if ($i == 5) break; // يوقف الحلقة
if ($i == 3) continue; // يتخطى هذه الدورة
echo $i;
}
?>
4. الشروط (Conditions)
= 18 && $age < 60) {
echo "بالغ";
} else {
echo "كبير السن";
}
// Switch Statement
$day = "الاثنين";
switch ($day) {
case "السبت":
case "الأحد":
echo "عطلة";
break;
case "الاثنين":
echo "بداية الأسبوع";
break;
default:
echo "يوم عادي";
}
// Ternary Operator
$result = ($age >= 18) ? "بالغ" : "قاصر";
// Null Coalescing
$name = $_GET['name'] ?? 'ضيف'; // إذا ما موجود يرجع 'ضيف'
// مقارنات مهمة
$a == $b; // يساوي (قيمة فقط)
$a === $b; // يساوي تماماً (قيمة ونوع)
$a != $b; // لا يساوي
$a !== $b; // لا يساوي تماماً
$a > $b; // أكبر من
$a < $b; // أصغر من
$a >= $b; // أكبر أو يساوي
$a <= $b; // أصغر أو يساوي
?>
5. الدوال (Functions)
$x * 2;
echo $double(5); // 10
// Variable Functions
function operation($callback, $a, $b) {
return $callback($a, $b);
}
echo operation($multiply, 10, 5); // 50
?>
💡 نصيحة مهمة: استخدم strict types في بداية الملف
لتجنب الأخطاء:
declare(strict_types=1);
🗄️ قواعد البيانات
1. الاتصال بقاعدة البيانات
أ) باستخدام MySQLi (Procedural)
ب) باستخدام MySQLi (Object-Oriented)
connect_error) {
die("فشل الاتصال: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
// استخدام الاتصال...
$conn->close();
?>
ج) باستخدام PDO (موصى به!) 🌟
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $user, $password, $options);
echo "الاتصال ناجح!";
} catch (PDOException $e) {
die("فشل الاتصال: " . $e->getMessage());
}
?>
2. عمليات CRUD
أ) Create - إضافة بيانات (PDO)
prepare($sql);
$stmt->execute([$name, $email, $age]);
echo "تم الإضافة بنجاح! ID: " . $pdo->lastInsertId();
// طريقة 2: باستخدام Named Parameters
$sql = "INSERT INTO users (name, email, age) VALUES (:name, :email, :age)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':name' => $name,
':email' => $email,
':age' => $age
]);
// إضافة أكثر من سطر
$users = [
['أحمد', 'ahmed@example.com', 25],
['فاطمة', 'fatima@example.com', 22],
['محمد', 'mohamed@example.com', 30]
];
$sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
foreach ($users as $user) {
$stmt->execute($user);
}
?>
ب) Read - قراءة البيانات
query($sql);
$users = $stmt->fetchAll();
foreach ($users as $user) {
echo $user['name'] . " - " . $user['email'] . "
";
}
// جلب سجل واحد
$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();
// مع ORDER BY و LIMIT
$sql = "SELECT * FROM users ORDER BY created_at DESC LIMIT 10";
$stmt = $pdo->query($sql);
$latestUsers = $stmt->fetchAll();
// JOIN بين جدولين
$sql = "SELECT users.*, orders.total
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE users.id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([1]);
$result = $stmt->fetch();
?>
ج) Update - تحديث البيانات
prepare($sql);
$stmt->execute(['أحمد المحدث', 'newemail@example.com', 1]);
echo "تم التحديث! عدد السجلات: " . $stmt->rowCount();
// تحديث أكثر من عمود
$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@example.com',
':age' => 26,
':id' => 1
]);
// تحديث بشرط
$sql = "UPDATE users SET status = 'active' WHERE last_login > DATE_SUB(NOW(), INTERVAL 30 DAY)";
$pdo->exec($sql);
?>
د) Delete - حذف البيانات
prepare($sql); $stmt->execute([1]); echo "تم الحذف! عدد السجلات المحذوفة: " . $stmt->rowCount(); // حذف بشرط $sql = "DELETE FROM users WHERE status = 'inactive' AND last_login < DATE_SUB(NOW(), INTERVAL 1 YEAR)"; $pdo->exec($sql); // حذف جميع السجلات (احذر!) $sql = "DELETE FROM users"; $pdo->exec($sql); // Soft Delete - حذف منطقي (موصى به) $sql = "UPDATE users SET deleted_at = NOW() WHERE id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([1]); ?>
3. Transactions - المعاملات
beginTransaction();
// العمليات
$sql1 = "INSERT INTO orders (user_id, total) VALUES (?, ?)";
$stmt1 = $pdo->prepare($sql1);
$stmt1->execute([1, 500]);
$orderId = $pdo->lastInsertId();
$sql2 = "INSERT INTO order_items (order_id, product_id, quantity) VALUES (?, ?, ?)";
$stmt2 = $pdo->prepare($sql2);
$stmt2->execute([$orderId, 10, 2]);
$sql3 = "UPDATE products SET stock = stock - 2 WHERE id = ?";
$stmt3 = $pdo->prepare($sql3);
$stmt3->execute([10]);
// إذا كل شي تمام، نحفظ التغييرات
$pdo->commit();
echo "تمت العملية بنجاح!";
} catch (Exception $e) {
// إذا صار خطأ، نلغي كل التغييرات
$pdo->rollBack();
echo "فشلت العملية: " . $e->getMessage();
}
?>
4. Database Helper Class (موصى به!) 🌟
PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$this->pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
throw new Exception("Database connection failed: " . $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 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();
}
// تحديث
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();
}
// حذف
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;
}
}
// الاستخدام
$db = new Database('localhost', 'mydb', 'root', '');
// إضافة
$userId = $db->insert('users', [
'name' => 'أحمد',
'email' => 'ahmed@example.com',
'age' => 25
]);
// قراءة
$users = $db->getAll("SELECT * FROM users WHERE age > ?", [20]);
$user = $db->getOne("SELECT * FROM users WHERE id = ?", [1]);
// تحديث
$db->update('users',
['name' => 'أحمد المحدث', 'email' => 'new@example.com'],
'id = :id',
[':id' => 1]
);
// حذف
$db->delete('users', 'id = ?', [1]);
?>
⚠️ تحذير أمني مهم:
- لا تستخدم أبداً string concatenation مع SQL
- استخدم دائماً Prepared Statements
- نظف وفلتر جميع المدخلات
- استخدم PDO بدلاً من MySQLi
🔐 Sessions & Cookies
1. Sessions
2. نظام تسجيل دخول كامل
prepare($sql);
$stmt->execute([$email]);
$user = $stmt->fetch();
// التحقق من وجود المستخدم والباسورد
if ($user && password_verify($password, $user['password'])) {
// تخزين بيانات المستخدم في الجلسة
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['email'] = $user['email'];
$_SESSION['role'] = $user['role'];
// تجديد Session ID للأمان
session_regenerate_id(true);
// تحديث آخر تسجيل دخول
$sql = "UPDATE users SET last_login = NOW() WHERE id = ?";
$stmt = $db->prepare($sql);
$stmt->execute([$user['id']]);
return true;
}
return false;
}
// register.php
function register($username, $email, $password, $db) {
// تشفير الباسورد
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// إضافة المستخدم
$sql = "INSERT INTO users (username, email, password, created_at)
VALUES (?, ?, ?, NOW())";
$stmt = $db->prepare($sql);
try {
$stmt->execute([$username, $email, $hashedPassword]);
return $db->lastInsertId();
} catch (PDOException $e) {
// Email مكرر
return false;
}
}
// logout.php
function logout() {
session_unset();
session_destroy();
setcookie(session_name(), '', time() - 3600, '/');
header("Location: login.php");
exit();
}
// check_auth.php
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;
}
// الاستخدام
if (login('ahmed@example.com', 'password123', $db)) {
echo "تم تسجيل الدخول بنجاح!";
header("Location: dashboard.php");
} else {
echo "البريد أو الباسورد خطأ!";
}
?>
3. Cookies
time() + 3600, // ساعة واحدة
'path' => '/',
'domain' => 'example.com',
'secure' => true, // HTTPS فقط
'httponly' => true, // JavaScript لا يقدر يوصله
'samesite' => 'Strict' // حماية من CSRF
]);
// قراءة Cookie
if (isset($_COOKIE['username'])) {
echo $_COOKIE['username'];
}
// حذف Cookie
setcookie('username', '', time() - 3600, '/');
// Remember Me Functionality
function rememberUser($userId, $db) {
// إنشاء token عشوائي
$token = bin2hex(random_bytes(32));
// تخزين الـ token في قاعدة البيانات
$sql = "UPDATE users SET remember_token = ? WHERE id = ?";
$stmt = $db->prepare($sql);
$stmt->execute([hash('sha256', $token), $userId]);
// حفظه في Cookie
setcookie('remember_token', $token, time() + (86400 * 30), '/', '', true, true);
}
function checkRememberToken($db) {
if (isset($_COOKIE['remember_token'])) {
$token = $_COOKIE['remember_token'];
$hashedToken = hash('sha256', $token);
$sql = "SELECT * FROM users WHERE remember_token = ?";
$stmt = $db->prepare($sql);
$stmt->execute([$hashedToken]);
$user = $stmt->fetch();
if ($user) {
// تسجيل دخول تلقائي
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
return true;
}
}
return false;
}
?>
✅ أفضل الممارسات للـ Sessions:
- استخدم
session_regenerate_id()بعد تسجيل الدخول - احفظ أقل قدر ممكن من البيانات في الجلسة
- استخدم HTTPS دائماً
- ضع timeout للجلسة
- شفر البيانات الحساسة
📝 Forms & Input Handling
1. التعامل مع POST و GET
2. تنظيف وفلترة المدخلات (مهم جداً!) 🛡️
'); // دالة شاملة للتنظيف function cleanInput($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); return $data; } // استخدام $username = cleanInput($_POST['username']); ?>
3. Validation - التحقق من البيانات
$error";
}
}
?>
4. Validation Class (احترافي)
$rule) {
$ruleList = explode('|', $rule);
foreach ($ruleList as $r) {
$this->applyRule($field, $data[$field] ?? '', $r, $data);
}
}
return empty($this->errors);
}
private function applyRule($field, $value, $rule, $data) {
if (strpos($rule, ':') !== false) {
list($rule, $param) = explode(':', $rule);
}
switch ($rule) {
case 'required':
if (empty($value)) {
$this->errors[$field][] = "$field مطلوب";
}
break;
case 'email':
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->errors[$field][] = "$field يجب أن يكون بريد إلكتروني صحيح";
}
break;
case 'min':
if (strlen($value) < $param) {
$this->errors[$field][] = "$field يجب أن يكون $param أحرف على الأقل";
}
break;
case 'max':
if (strlen($value) > $param) {
$this->errors[$field][] = "$field يجب ألا يتجاوز $param حرف";
}
break;
case 'same':
if ($value !== ($data[$param] ?? '')) {
$this->errors[$field][] = "$field يجب أن يطابق $param";
}
break;
case 'unique':
// التحقق من قاعدة البيانات
global $pdo;
list($table, $column) = explode(',', $param);
$sql = "SELECT COUNT(*) FROM $table WHERE $column = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$value]);
if ($stmt->fetchColumn() > 0) {
$this->errors[$field][] = "$field موجود مسبقاً";
}
break;
}
}
public function getErrors() {
return $this->errors;
}
}
// الاستخدام
$validator = new Validator();
$isValid = $validator->validate($_POST, [
'username' => 'required|min:3|max:20|unique:users,username',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8',
'confirm_password' => 'required|same:password',
'age' => 'required'
]);
if ($isValid) {
echo "البيانات صحيحة!";
} else {
print_r($validator->getErrors());
}
?>
💡 نصائح مهمة:
- نظف وفلتر جميع المدخلات من المستخدم
- استخدم POST للبيانات الحساسة
- استخدم CSRF Token للحماية
- لا تثق أبداً بمدخلات المستخدم
📁 التعامل مع الملفات
1. رفع الملفات (File Upload)
$tmpName) {
$fileName = $_FILES['files']['name'][$key];
$fileSize = $_FILES['files']['size'][$key];
// نفس الخطوات السابقة لكل ملف
}
?>
2. File Upload Class (احترافي)
uploadDir = rtrim($dir, '/') . '/';
if (!is_dir($this->uploadDir)) {
mkdir($this->uploadDir, 0755, true);
}
return $this;
}
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;
}
// إنشاء اسم فريد
$newName = uniqid('file_', true) . '.' . $extension;
$destination = $this->uploadDir . $newName;
// نقل الملف
if (move_uploaded_file($file['tmp_name'], $destination)) {
return [
'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 getErrors() {
return $this->errors;
}
}
// الاستخدام
$uploader = new FileUpload();
$uploader->setUploadDir('uploads/images/')
->setAllowedTypes(['jpg', 'png', 'gif'])
->setMaxSize(2 * 1024 * 1024); // 2MB
$result = $uploader->upload($_FILES['image']);
if ($result) {
echo "تم رفع الملف: " . $result['name'];
// حفظ في قاعدة البيانات
} else {
print_r($uploader->getErrors());
}
?>
3. قراءة وكتابة الملفات
4. التعامل مع الصور
$x,
'y' => $y,
'width' => $width,
'height' => $height
]);
imagejpeg($cropped, $destination, 90);
imagedestroy($image);
imagedestroy($cropped);
}
// الحصول على معلومات الصورة
$info = getimagesize('image.jpg');
echo "العرض: " . $info[0];
echo "الارتفاع: " . $info[1];
echo "النوع: " . $info[2];
echo "MIME: " . $info['mime'];
?>
⚠️ تحذيرات أمنية:
- تحقق دائماً من نوع الملف (لا تثق بالامتداد فقط)
- استخدم أسماء فريدة للملفات
- احفظ الملفات خارج المجلد الرئيسي للموقع
- تحقق من حجم الملف
- استخدم mime_content_type() للتحقق من النوع الحقيقي
🌐 التعامل مع APIs
1. إنشاء REST API
prepare($sql);
$stmt->execute([$_GET['id']]);
$user = $stmt->fetch();
if ($user) {
echo json_encode([
'success' => true,
'data' => $user
]);
} else {
http_response_code(404);
echo json_encode([
'success' => false,
'message' => 'المستخدم غير موجود'
]);
}
} else {
// جلب جميع العناصر
$sql = "SELECT * FROM users LIMIT 100";
$stmt = $pdo->query($sql);
$users = $stmt->fetchAll();
echo json_encode([
'success' => true,
'count' => count($users),
'data' => $users
]);
}
break;
case 'POST':
// إضافة عنصر جديد
if (empty($input['name']) || empty($input['email'])) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'البيانات غير كاملة'
]);
exit;
}
$sql = "INSERT INTO users (name, email, created_at) VALUES (?, ?, NOW())";
$stmt = $pdo->prepare($sql);
$stmt->execute([$input['name'], $input['email']]);
http_response_code(201);
echo json_encode([
'success' => true,
'message' => 'تم الإضافة بنجاح',
'id' => $pdo->lastInsertId()
]);
break;
case 'PUT':
// تحديث عنصر
if (!isset($_GET['id'])) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'ID مطلوب'
]);
exit;
}
$sql = "UPDATE users SET name = ?, email = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$input['name'], $input['email'], $_GET['id']]);
if ($stmt->rowCount() > 0) {
echo json_encode([
'success' => true,
'message' => 'تم التحديث بنجاح'
]);
} else {
http_response_code(404);
echo json_encode([
'success' => false,
'message' => 'المستخدم غير موجود'
]);
}
break;
case 'DELETE':
// حذف عنصر
if (!isset($_GET['id'])) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => 'ID مطلوب'
]);
exit;
}
$sql = "DELETE FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$_GET['id']]);
if ($stmt->rowCount() > 0) {
echo json_encode([
'success' => true,
'message' => 'تم الحذف بنجاح'
]);
} else {
http_response_code(404);
echo json_encode([
'success' => false,
'message' => 'المستخدم غير موجود'
]);
}
break;
default:
http_response_code(405);
echo json_encode([
'success' => false,
'message' => 'طريقة الطلب غير مدعومة'
]);
}
?>
2. API مع Authentication (JWT)
'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;
}
// login.php
if ($method === 'POST' && $_GET['action'] === 'login') {
$email = $input['email'];
$password = $input['password'];
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$payload = [
'user_id' => $user['id'],
'email' => $user['email'],
'iat' => time(),
'exp' => time() + (3600 * 24) // 24 ساعة
];
$token = createJWT($payload, 'your-secret-key');
echo json_encode([
'success' => true,
'token' => $token,
'user' => [
'id' => $user['id'],
'name' => $user['name'],
'email' => $user['email']
]
]);
} else {
http_response_code(401);
echo json_encode([
'success' => false,
'message' => 'البريد أو الباسورد خطأ'
]);
}
exit;
}
// Middleware للتحقق من Token
function requireAuth($secret) {
$headers = getallheaders();
$authHeader = $headers['Authorization'] ?? '';
if (empty($authHeader) || !preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
http_response_code(401);
echo json_encode([
'success' => false,
'message' => 'Token مطلوب'
]);
exit;
}
$token = $matches[1];
$payload = verifyJWT($token, $secret);
if (!$payload) {
http_response_code(401);
echo json_encode([
'success' => false,
'message' => 'Token غير صحيح أو منتهي الصلاحية'
]);
exit;
}
return $payload;
}
// استخدام الـ Middleware
$user = requireAuth('your-secret-key');
// الآن يمكنك استخدام $user['user_id'] للعمليات
?>
3. استهلاك APIs خارجية
$httpCode,
'data' => json_decode($response, true)
];
}
// GET Request مع معاملات
$params = http_build_query([
'page' => 1,
'limit' => 10,
'search' => 'keyword'
]);
$result = apiGet("https://api.example.com/users?$params");
print_r($result['data']);
// 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)
];
}
// استخدام
$result = apiPost('https://api.example.com/users', [
'name' => 'أحمد',
'email' => 'ahmed@example.com'
]);
// API مع Authentication
$result = apiGet('https://api.example.com/protected', [
'Authorization: Bearer YOUR_TOKEN_HERE'
]);
// 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);
}
// استخدام file_get_contents (للطلبات البسيطة)
$options = [
'http' => [
'method' => 'GET',
'header' => 'Authorization: Bearer TOKEN'
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/data', false, $context);
$data = json_decode($response, true);
?>
4. API Rate Limiting
pdo = $pdo;
$this->limit = $limit;
$this->window = $window;
}
public function check($identifier) {
$now = time();
$windowStart = $now - $this->window;
// حذف الطلبات القديمة
$sql = "DELETE FROM rate_limits
WHERE identifier = ? AND timestamp < ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$identifier, $windowStart]);
// عد الطلبات الحالية
$sql = "SELECT COUNT(*) FROM rate_limits
WHERE identifier = ? AND timestamp >= ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$identifier, $windowStart]);
$count = $stmt->fetchColumn();
if ($count >= $this->limit) {
return false;
}
// إضافة الطلب الحالي
$sql = "INSERT INTO rate_limits (identifier, timestamp)
VALUES (?, ?)";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$identifier, $now]);
return true;
}
public function getRemaining($identifier) {
$now = time();
$windowStart = $now - $this->window;
$sql = "SELECT COUNT(*) FROM rate_limits
WHERE identifier = ? AND timestamp >= ?";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$identifier, $windowStart]);
$count = $stmt->fetchColumn();
return max(0, $this->limit - $count);
}
}
// استخدام
$rateLimiter = new RateLimiter($pdo, 100, 3600); // 100 طلب كل ساعة
$identifier = $_SERVER['REMOTE_ADDR']; // IP Address
if (!$rateLimiter->check($identifier)) {
http_response_code(429);
echo json_encode([
'success' => false,
'message' => 'تجاوزت الحد المسموح من الطلبات'
]);
exit;
}
$remaining = $rateLimiter->getRemaining($identifier);
header("X-RateLimit-Remaining: $remaining");
?>
💡 أفضل الممارسات للـ APIs:
- استخدم HTTPS دائماً
- استخدم JWT أو OAuth للـ Authentication
- طبق Rate Limiting
- استخدم HTTP Status Codes الصحيحة
- وثق الـ API جيداً
- استخدم Versioning (v1, v2)
🛡️ الأمان (Security)
1. حماية من SQL Injection
prepare($sql); $stmt->execute([$id]); // أو استخدم Named Parameters $sql = "SELECT * FROM users WHERE id = :id AND status = :status"; $stmt = $pdo->prepare($sql); $stmt->execute([':id' => $id, ':status' => 'active']); ?>
2. حماية من XSS (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');
}
echo escape($username);
// للـ HTML attributes
function escapeAttr($string) {
return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
echo '';
// للـ JavaScript
function escapeJS($string) {
return json_encode($string);
}
echo '';
?>
3. حماية من CSRF (Cross-Site Request Forgery)
4. تشفير الباسورد
prepare($sql);
$stmt->execute([$email, $password]);
// التحقق من الباسورد
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$email]);
$user = $stmt->fetch();
if ($user && password_verify($_POST['password'], $user['password'])) {
echo "تم تسجيل الدخول!";
// إعادة تشفير إذا احتاج (للخوارزميات الجديدة)
if (password_needs_rehash($user['password'], PASSWORD_DEFAULT)) {
$newHash = password_hash($_POST['password'], PASSWORD_DEFAULT);
$sql = "UPDATE users SET password = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$newHash, $user['id']]);
}
} else {
echo "البريد أو الباسورد خطأ!";
}
// خيارات إضافية للتشفير
$options = [
'cost' => 12 // زيادة القوة (default: 10)
];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT, $options);
?>
5. حماية من Directory Traversal
6. 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 (حماية من Session Hijacking)
function getSessionFingerprint() {
return hash('sha256', $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']);
}
function validateSessionFingerprint() {
if (!isset($_SESSION['fingerprint'])) {
$_SESSION['fingerprint'] = getSessionFingerprint();
}
return $_SESSION['fingerprint'] === getSessionFingerprint();
}
// استخدام
session_start();
if (!checkSessionTimeout() || !validateSessionFingerprint()) {
session_destroy();
header('Location: login.php');
exit;
}
?>
7. Input Validation & Sanitization
150) {
die('عمر غير صحيح');
}
// فلترة النصوص
function sanitizeString($string) {
$string = trim($string);
$string = stripslashes($string);
$string = strip_tags($string);
return $string;
}
// Regex Validation
function validatePhone($phone) {
return preg_match('/^05[0-9]{8}$/', $phone);
}
function validateUsername($username) {
return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $username);
}
// Strong Password Validation
function validatePassword($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;
}
// دالة شاملة للتحقق والفلترة
function secureInput($data, $type = 'string') {
$data = trim($data);
$data = stripslashes($data);
switch ($type) {
case 'email':
return filter_var($data, FILTER_SANITIZE_EMAIL);
case 'url':
return filter_var($data, FILTER_SANITIZE_URL);
case 'int':
return filter_var($data, FILTER_SANITIZE_NUMBER_INT);
case 'float':
return filter_var($data, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
case 'string':
default:
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
}
?>
8. File Upload Security
'خطأ في رفع الملف'];
}
// التحقق من الحجم (5MB)
if ($file['size'] > 5 * 1024 * 1024) {
return ['error' => 'حجم الملف كبير جداً'];
}
// التحقق من النوع الحقيقي (ليس الامتداد فقط)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
$allowedMimes = [
'image/jpeg' => 'jpg',
'image/png' => 'png',
'application/pdf' => 'pdf'
];
if (!isset($allowedMimes[$mimeType])) {
return ['error' => 'نوع الملف غير مسموح'];
}
// إنشاء اسم عشوائي آمن
$extension = $allowedMimes[$mimeType];
$newName = bin2hex(random_bytes(16)) . '.' . $extension;
// حفظ خارج الـ web root أو في مجلد محمي
$uploadDir = '../uploads/'; // خارج المجلد العام
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// إضافة .htaccess لمنع تنفيذ PHP
$htaccess = $uploadDir . '.htaccess';
if (!file_exists($htaccess)) {
file_put_contents($htaccess, 'php_flag engine off');
}
$destination = $uploadDir . $newName;
if (move_uploaded_file($file['tmp_name'], $destination)) {
return [
'success' => true,
'filename' => $newName,
'path' => $destination
];
}
return ['error' => 'فشل في حفظ الملف'];
}
// استخدام
$result = secureFileUpload($_FILES['document']);
if (isset($result['success'])) {
echo "تم رفع الملف: " . $result['filename'];
} else {
echo "خطأ: " . $result['error'];
}
?>
9. Security Headers
🎯 Object-Oriented PHP (OOP)
1. Classes و Objects
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;
}
}
// Method للتحقق من الباسورد
public function verifyPassword($password) {
return password_verify($password, $this->password);
}
// Destructor
public function __destruct() {
// تنظيف عند حذف الكائن
}
}
// إنشاء Object
$user = new User("أحمد", "ahmed@example.com", "password123");
echo $user->introduce(); // مرحباً، أنا أحمد
echo $user->name; // أحمد
$user->setRole('admin');
echo $user->getRole(); // admin
// Access Modifiers:
// public: يمكن الوصول من أي مكان
// private: فقط داخل الـ Class
// protected: داخل الـ Class والـ Classes الوارثة
?>
2. Inheritance (الوراثة)
name = $name;
$this->age = $age;
}
public function introduce() {
return "أنا {$this->name}، عمري {$this->age}";
}
}
// Class يرث من Person
class Student extends Person {
private $grade;
public function __construct($name, $age, $grade) {
parent::__construct($name, $age); // استدعاء Constructor الأب
$this->grade = $grade;
}
// Override (تجاوز) Method
public function introduce() {
return parent::introduce() . "، في الصف {$this->grade}";
}
public function study() {
return "{$this->name} يدرس";
}
}
class Teacher extends Person {
private $subject;
public function __construct($name, $age, $subject) {
parent::__construct($name, $age);
$this->subject = $subject;
}
public function teach() {
return "{$this->name} يدرّس {$this->subject}";
}
}
// استخدام
$student = new Student("أحمد", 15, "العاشر");
echo $student->introduce(); // أنا أحمد، عمري 15، في الصف العاشر
echo $student->study(); // أحمد يدرس
$teacher = new Teacher("فاطمة", 30, "الرياضيات");
echo $teacher->teach(); // فاطمة يدرّس الرياضيات
?>
3. Abstract Classes & Interfaces
name = $name;
}
// Abstract Method (يجب تطبيقه في الـ Child Classes)
abstract public function makeSound();
// Method عادي
public function eat() {
return "{$this->name} يأكل";
}
}
class Dog extends Animal {
public function makeSound() {
return "نباح!";
}
}
class Cat extends Animal {
public function makeSound() {
return "مواء!";
}
}
$dog = new Dog("ريكس");
echo $dog->makeSound(); // نباح!
echo $dog->eat(); // ريكس يأكل
// Interface (عقد يجب تنفيذه)
interface PaymentInterface {
public function processPayment($amount);
public function refund($transactionId);
}
class CreditCard implements PaymentInterface {
public function processPayment($amount) {
return "تمت معالجة $amount ريال عبر البطاقة";
}
public function refund($transactionId) {
return "تم استرجاع المبلغ لـ $transactionId";
}
}
class PayPal implements PaymentInterface {
public function processPayment($amount) {
return "تمت معالجة $amount ريال عبر PayPal";
}
public function refund($transactionId) {
return "تم استرجاع المبلغ عبر PayPal";
}
}
// يمكن تطبيق أكثر من Interface
interface Loggable {
public function log($message);
}
class Order implements PaymentInterface, Loggable {
public function processPayment($amount) {
$this->log("تمت معالجة دفع بقيمة $amount");
return "تم الدفع بنجاح";
}
public function refund($transactionId) {
$this->log("تم استرجاع $transactionId");
return "تم الاسترجاع";
}
public function log($message) {
file_put_contents('orders.log', date('Y-m-d H:i:s') . " - $message\n", FILE_APPEND);
}
}
?>
4. Traits
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, '-');
}
}
class Article {
use Timestampable, Sluggable;
public $title;
public $slug;
public function __construct($title) {
$this->title = $title;
$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
connection = new PDO("mysql:host=localhost;dbname=mydb", "root", "");
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function query($sql) {
return $this->connection->query($sql);
}
// منع النسخ
private function __clone() {}
private function __wakeup() {}
}
// استخدام
$db = Database::getInstance();
$result = $db->query("SELECT * FROM users");
?>
6. Magic Methods
data[$name] ?? null;
}
// __set - عند تعيين قيمة لـ property غير موجود
public function __set($name, $value) {
$this->data[$name] = $value;
}
// __isset - عند استخدام isset() على property
public function __isset($name) {
return isset($this->data[$name]);
}
// __unset - عند استخدام unset() على property
public function __unset($name) {
unset($this->data[$name]);
}
// __call - عند استدعاء method غير موجود
public function __call($name, $arguments) {
return "Method $name لا يوجد";
}
// __toString - عند تحويل الكائن لنص
public function __toString() {
return json_encode($this->data);
}
// __invoke - عند استخدام الكائن كدالة
public function __invoke($x) {
return $x * 2;
}
}
$obj = new MagicExample();
$obj->name = "أحمد"; // __set
echo $obj->name; // __get: أحمد
echo isset($obj->name); // __isset: true
echo $obj; // __toString: {"name":"أحمد"}
echo $obj(5); // __invoke: 10
?>
7. Namespaces
save();
}
}
// استخدام
use App\Controllers\UserController;
use App\Models\User as UserModel; // alias
$controller = new UserController();
$user = new UserModel();
// أو استخدام الـ full namespace
$user = new \App\Models\User();
?>
✅ فوائد OOP:
- تنظيم أفضل للكود
- إعادة استخدام الكود
- سهولة الصيانة
- التغليف والأمان
- قابلية التوسع
⚡ دوال PHP مهمة
1. String Functions
2. Array Functions
'أحمد', 'age' => 25],
['name' => 'فاطمة', 'age' => 22],
['name' => 'محمد', 'age' => 30]
];
// الإضافة والحذف
array_push($arr, 6); // إضافة للنهاية
array_pop($arr); // حذف من النهاية
array_unshift($arr, 0); // إضافة للبداية
array_shift($arr); // حذف من البداية
array_splice($arr, 2, 1); // حذف من موضع معين
// البحث
in_array(3, $arr); // موجود؟
array_search(3, $arr); // رقم المفتاح
array_key_exists('name', $users[0]); // المفتاح موجود؟
// الترتيب
sort($arr); // ترتيب تصاعدي
rsort($arr); // ترتيب تنازلي
asort($arr); // حفظ المفاتيح
ksort($arr); // ترتيب حسب المفاتيح
usort($users, function($a, $b) { // ترتيب مخصص
return $a['age'] <=> $b['age'];
});
// التحويل
array_map(function($x) { // تطبيق دالة على كل عنصر
return $x * 2;
}, $arr);
array_filter($arr, function($x) { // فلترة
return $x > 2;
});
array_reduce($arr, function($carry, $item) { // تقليل لقيمة واحدة
return $carry + $item;
}, 0);
// العد والمجموع
count($arr); // عدد العناصر
array_sum($arr); // مجموع الأرقام
array_product($arr); // حاصل الضرب
// دمج وتقسيم
array_merge($arr1, $arr2); // دمج
array_slice($arr, 1, 3); // استخراج جزء
array_chunk($arr, 2); // تقسيم لأجزاء
// المفاتيح والقيم
array_keys($users[0]); // ['name', 'age']
array_values($users[0]); // ['أحمد', 25]
array_combine($keys, $values); // دمج مفاتيح وقيم
// الفريد والتكرار
array_unique($arr); // إزالة المكرر
array_count_values($arr); // عد التكرارات
// التقاطع والاختلاف
array_intersect($arr1, $arr2); // العناصر المشتركة
array_diff($arr1, $arr2); // الاختلاف
// عشوائي
shuffle($arr); // خلط عشوائي
array_rand($arr); // عنصر عشوائي
// تسطيح المصفوفات المتداخلة
array_walk_recursive($arr, function(&$value) {
$value = $value * 2;
});
// Column من مصفوفة متعددة الأبعاد
array_column($users, 'name'); // ['أحمد', 'فاطمة', 'محمد']
// Flip (عكس المفاتيح والقيم)
array_flip($arr);
?>
3. Date & Time Functions
format('Y-m-d H:i:s'); // 2025-01-20 10:30:00
$date->format('d F Y'); // 20 January 2025
// تحويل من نص لتاريخ
strtotime('2025-01-20'); // Unix timestamp
strtotime('+1 day'); // غداً
strtotime('-1 week'); // قبل أسبوع
strtotime('next Monday'); // الاثنين القادم
// إضافة وطرح الوقت
$date = new DateTime();
$date->add(new DateInterval('P1D')); // إضافة يوم
$date->sub(new DateInterval('P1M')); // طرح شهر
// الفرق بين تاريخين
$date1 = new DateTime('2025-01-01');
$date2 = new DateTime('2025-01-20');
$diff = $date1->diff($date2);
echo $diff->days; // 19 يوم
// مقارنة التواريخ
$date1 > $date2;
$date1 < $date2;
$date1 == $date2;
// تنسيق مخصص
$date->format('l, d F Y'); // Monday, 20 January 2025
$date->format('Y-m-d\TH:i:s\Z'); // ISO 8601
// المنطقة الزمنية
date_default_timezone_set('Asia/Riyadh');
$date = new DateTime('now', new DateTimeZone('Asia/Dubai'));
// أيام الشهر
cal_days_in_month(CAL_GREGORIAN, 2, 2024); // 29 (كبيسة)
// معلومات التاريخ
$info = getdate();
echo $info['year']; // 2025
echo $info['month']; // January
echo $info['weekday']; // Monday
// Carbon (مكتبة شائعة)
// composer require nesbot/carbon
use Carbon\Carbon;
$now = Carbon::now();
$now->addDays(5);
$now->subMonths(2);
$now->diffForHumans(); // "منذ 5 دقائق"
?>
4. File & Directory Functions
5. Math Functions
6. JSON Functions
'أحمد',
'age' => 25,
'email' => 'ahmed@example.com'
];
$json = json_encode($data);
// {"name":"أحمد","age":25,"email":"ahmed@example.com"}
// خيارات للتنسيق
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
// تحويل من JSON
$jsonString = '{"name":"أحمد","age":25}';
$data = json_decode($jsonString, true); // true = مصفوفة
// بدون true يرجع object
$data = json_decode($jsonString);
echo $data->name; // أحمد
// التحقق من الأخطاء
json_decode($jsonString);
if (json_last_error() !== JSON_ERROR_NONE) {
echo json_last_error_msg();
}
// قراءة JSON من ملف
$data = json_decode(file_get_contents('data.json'), true);
// كتابة JSON لملف
file_put_contents('data.json', json_encode($data, JSON_PRETTY_PRINT));
?>
7. URL & HTTP Functions
https
[host] => example.com
[port] => 8080
[user] => user
[pass] => pass
[path] => /path/to/page
[query] => q=search
[fragment] => section
)
*/
// بناء query string
$params = ['name' => 'أحمد', 'age' => 25, 'city' => 'الرياض'];
$query = http_build_query($params); // name=%D8%A3%D8%AD%D9%85%D8%AF&age=25&city=%D8%A7%D9%84%D8%B1%D9%8A%D8%A7%D8%B6
// تحليل query string
parse_str($query, $output);
// Headers
header('Content-Type: application/json');
header('Location: page.php');
header('HTTP/1.1 404 Not Found');
// Redirect
function redirect($url, $code = 302) {
header("Location: $url", true, $code);
exit;
}
// Get Request Headers
$headers = getallheaders();
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$ip = $_SERVER['REMOTE_ADDR'];
$method = $_SERVER['REQUEST_METHOD'];
// Base URL
function baseUrl($path = '') {
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
return "$protocol://$host/$path";
}
?>
8. Other Useful Functions
💡 نصيحة: استخدم
var_dump() و print_r() لفحص المتغيرات
أثناء التطوير.
❌ Error Handling
1. أنواع الأخطاء
2. Try-Catch (Exceptions)
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()}";
}
}
try {
throw new DatabaseException("فشل الاتصال", 1001);
} catch (DatabaseException $e) {
echo $e->errorMessage();
}
// معلومات Exception
$e->getMessage(); // رسالة الخطأ
$e->getCode(); // رمز الخطأ
$e->getFile(); // الملف
$e->getLine(); // رقم السطر
$e->getTrace(); // Stack trace
$e->getTraceAsString(); // Stack trace كنص
?>
3. Custom Error Handler
'خطأ فادح',
E_WARNING => 'تحذير',
E_NOTICE => 'ملاحظة',
E_USER_ERROR => 'خطأ مستخدم',
E_USER_WARNING => 'تحذير مستخدم',
E_USER_NOTICE => 'ملاحظة مستخدم'
];
$type = $errorTypes[$errno] ?? 'خطأ غير معروف';
$message = sprintf(
"[%s] %s في %s السطر %d\n",
date('Y-m-d H:i:s'),
$type,
$errfile,
$errline
);
// تسجيل في ملف
error_log($message . $errstr . "\n", 3, 'errors.log');
// عرض رسالة للمستخدم (في Development فقط)
if (ini_get('display_errors')) {
echo "";
echo "$type: $errstr
";
echo "في $errfile السطر $errline";
echo "";
}
// إذا خطأ فادح، أوقف التنفيذ
if ($errno === E_USER_ERROR) {
die('تم إيقاف التنفيذ بسبب خطأ فادح');
}
return true; // لا تنفذ Error Handler الافتراضي
}
// تفعيل Error Handler
set_error_handler('customErrorHandler');
// استخدام
trigger_error('هذا تحذير مخصص', E_USER_WARNING);
?>
4. Exception Handler
getMessage(),
$exception->getFile(),
$exception->getLine()
);
error_log($message, 3, 'exceptions.log');
// عرض صفحة خطأ للمستخدم
http_response_code(500);
if (ini_get('display_errors')) {
echo "حدث خطأ
";
echo "" . htmlspecialchars($exception->getMessage()) . "
";
echo "" . $exception->getTraceAsString() . "
";
} else {
echo "عذراً، حدث خطأ
";
echo "نعمل على حل المشكلة
";
}
}
// تفعيل Exception Handler
set_exception_handler('customExceptionHandler');
// الآن أي Exception غير معالج سيذهب للـ Handler
throw new Exception('خطأ غير معالج');
?>
5. Logging Class (احترافي)
logFile = $logFile;
}
private function write($level, $message, $context = []) {
if (!in_array($level, $this->levels)) {
$level = 'INFO';
}
$timestamp = date('Y-m-d H:i:s');
$contextStr = !empty($context) ? ' ' . json_encode($context) : '';
$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('app.log');
$logger->info('بدء تسجيل دخول المستخدم', ['user_id' => 123]);
$logger->warning('محاولة دخول فاشلة', ['ip' => $_SERVER['REMOTE_ADDR']]);
$logger->error('فشل الاتصال بقاعدة البيانات');
try {
// كود
} catch (Exception $e) {
$logger->exception($e);
}
?>
6. Assert للاختبارات
= 18, 'العمر يجب أن يكون 18 أو أكثر');
// Assert مع Exception
assert($age >= 18, new Exception('عمر غير صحيح'));
// Assert للتطوير فقط (تُزال في Production)
assert($user !== null, 'المستخدم يجب أن لا يكون null');
?>
⚠️ تذكر:
- لا تعرض تفاصيل الأخطاء في Production
- سجّل جميع الأخطاء في ملفات
- استخدم Try-Catch للعمليات الحرجة
- اختبر Error Handling جيداً
🚀 مواضيع متقدمة
1. Composer & Autoloading
pushHandler(new StreamHandler('app.log', Logger::WARNING));
$log->warning('هذا تحذير');
// PSR-4 Autoloading
// src/Controllers/UserController.php
namespace App\Controllers;
class UserController {
public function index() {
return "قائمة المستخدمين";
}
}
// استخدام
use App\Controllers\UserController;
$controller = new UserController();
?>
2. Dependency Injection
db = new Database(); // ارتباط قوي
}
}
// مع Dependency Injection (جيد)
class UserController {
private $db;
public function __construct(Database $db) {
$this->db = $db; // حقن الاعتماد
}
}
// DI Container بسيط
class Container {
private $bindings = [];
public function bind($key, $resolver) {
$this->bindings[$key] = $resolver;
}
public function resolve($key) {
if (isset($this->bindings[$key])) {
$resolver = $this->bindings[$key];
return $resolver($this);
}
throw new Exception("لا يمكن حل $key");
}
}
// استخدام
$container = new Container();
$container->bind('Database', function() {
return new Database('localhost', 'mydb', 'root', '');
});
$container->bind('UserRepository', function($c) {
return new UserRepository($c->resolve('Database'));
});
$userRepo = $container->resolve('UserRepository');
?>
3. Design Patterns
'أحمد']);
// 2. Repository Pattern
interface UserRepositoryInterface {
public function find($id);
public function all();
public function create($data);
}
class UserRepository implements UserRepositoryInterface {
private $db;
public function __construct($db) {
$this->db = $db;
}
public function find($id) {
return $this->db->getOne("SELECT * FROM users WHERE id = ?", [$id]);
}
public function all() {
return $this->db->getAll("SELECT * FROM users");
}
public function create($data) {
return $this->db->insert('users', $data);
}
}
// 3. Observer Pattern
interface Observer {
public function update($event);
}
class EmailNotifier implements Observer {
public function update($event) {
echo "إرسال بريد: " . $event;
}
}
class Subject {
private $observers = [];
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function notify($event) {
foreach ($this->observers as $observer) {
$observer->update($event);
}
}
}
$subject = new Subject();
$subject->attach(new EmailNotifier());
$subject->notify('تم إنشاء حساب جديد');
?>
4. Caching
cacheDir = $cacheDir;
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
public function set($key, $data, $ttl = 3600) {
$file = $this->cacheDir . md5($key);
$content = [
'data' => $data,
'expires' => time() + $ttl
];
file_put_contents($file, serialize($content));
}
public function get($key) {
$file = $this->cacheDir . md5($key);
if (!file_exists($file)) {
return null;
}
$content = unserialize(file_get_contents($file));
if (time() > $content['expires']) {
unlink($file);
return null;
}
return $content['data'];
}
public function delete($key) {
$file = $this->cacheDir . md5($key);
if (file_exists($file)) {
unlink($file);
}
}
}
// استخدام
$cache = new FileCache();
$cache->set('users_list', $users, 1800); // تخزين لمدة 30 دقيقة
$users = $cache->get('users_list');
?>
5. Queue System
queueFile = $queueFile;
}
public function push($job) {
$queue = $this->getQueue();
$queue[] = [
'job' => $job,
'created_at' => time()
];
$this->saveQueue($queue);
}
public function pop() {
$queue = $this->getQueue();
if (empty($queue)) {
return null;
}
$job = array_shift($queue);
$this->saveQueue($queue);
return $job['job'];
}
public function process($callback) {
while ($job = $this->pop()) {
call_user_func($callback, $job);
}
}
private function getQueue() {
if (!file_exists($this->queueFile)) {
return [];
}
return unserialize(file_get_contents($this->queueFile)) ?: [];
}
private function saveQueue($queue) {
file_put_contents($this->queueFile, serialize($queue));
}
}
// استخدام
$queue = new Queue();
// إضافة مهمة للطابور
$queue->push(['type' => 'email', 'to' => 'user@example.com', 'subject' => 'مرحباً']);
// معالجة المهام
$queue->process(function($job) {
if ($job['type'] === 'email') {
// إرسال البريد
echo "إرسال بريد إلى: " . $job['to'];
}
});
?>
✅ نصائح للتطوير المتقدم:
- استخدم Composer لإدارة المكتبات
- طبق Design Patterns المناسبة
- استخدم Caching لتحسين الأداء
- فصل الـ Business Logic عن الـ Presentation
- اكتب Unit Tests للكود