الأساسيات

مبتدئ

أساسيات PHP

PHP هي لغة برمجة نصية مفتوحة المصدر تُستخدم بشكل أساسي لتطوير تطبيقات الويب. إليك المفاهيم الأساسية التي تحتاج إلى معرفتها:

  • ✅ المتغيرات والمصفوفات
  • ✅ الحلقات والشروط
  • ✅ الدوال والوظائف
  • ✅ التعامل مع النصوص
  • ✅ التواريخ والأوقات

المتغيرات والمصفوفات

المتغيرات الأساسية
<?php // المتغيرات الأساسية $name = "أحمد"; // نص $age = 25; // رقم صحيح $price = 19.99; // رقم عشري $is_active = true; // منطقي $colors = ["أحمر", "أخضر", "أزرق"]; // مصفوفة // مصفوفة ترابطية $user = [ "name" => "أحمد", "email" => "ahmed@example.com", "age" => 25 ]; // طباعة المتغيرات echo "الاسم: " . $name . "<br>"; print_r($user); var_dump($colors);

الحلقات والشروط

الحلقات والشروط
<?php // الشروط $age = 20; if ($age >= 18) { echo "أنت بالغ"; } elseif ($age >= 13) { echo "أنت مراهق"; } else { echo "أنت طفل"; } // switch case $day = "الاثنين"; switch ($day) { case "السبت": case "الأحد": echo "عطلة نهاية الأسبوع"; break; default: echo "يوم عمل"; } // حلقة for for ($i = 1; $i <= 5; $i++) { echo "الرقم: " . $i . "<br>"; } // حلقة foreach للمصفوفات $colors = ["أحمر", "أخضر", "أزرق"]; foreach ($colors as $color) { echo "اللون: " . $color . "<br>"; } // حلقة while $counter = 1; while ($counter <= 3) { echo "العد: " . $counter . "<br>"; $counter++; }

الدوال والوظائف

الدوال في PHP
<?php // دالة بسيطة function greet($name) { return "مرحباً " . $name . "!"; } echo greet("أحمد"); // إخراج: مرحباً أحمد! // دالة مع قيمة افتراضية function multiply($a, $b = 2) { return $a * $b; } echo multiply(5); // إخراج: 10 echo multiply(5, 3); // إخراج: 15 // دالة مجهولة (closure) $square = function($n) { return $n * $n; }; echo $square(4); // إخراج: 16 // دالة مع عدد متغير من المعاملات function sum(...$numbers) { return array_sum($numbers); } echo sum(1, 2, 3, 4); // إخراج: 10

قواعد البيانات

متوسط

التعامل مع قواعد البيانات

PHP تدعم التعامل مع قواعد البيانات من خلال امتدادات مختلفة. أشهرها MySQLi و PDO:

  • ✅ الاتصال بقاعدة البيانات
  • ✅ تنفيذ استعلامات SQL
  • ✅ استخدام Prepared Statements
  • ✅ معاملات البيانات (Transactions)
  • ✅ إدارة الأخطاء

MySQLi و PDO

الاتصال باستخدام MySQLi
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // إنشاء الاتصال $conn = new mysqli($servername, $username, $password, $dbname); // التحقق من الاتصال if ($conn->connect_error) { die("فشل الاتصال: " . $conn->connect_error); } echo "تم الاتصال بنجاح"; // إغلاق الاتصال $conn->close();
الاتصال باستخدام PDO
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // ضبط وضع الخطأ لـ PDO ليظهر الاستثناءات $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "تم الاتصال بنجاح"; } catch(PDOException $e) { echo "فشل الاتصال: " . $e->getMessage(); }

عمليات CRUD الكاملة

عمليات CRUD باستخدام PDO
<?php // إنشاء (INSERT) $sql = "INSERT INTO users (name, email, age) VALUES (:name, :email, :age)"; $stmt = $conn->prepare($sql); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email); $stmt->bindParam(':age', $age); $name = "أحمد"; $email = "ahmed@example.com"; $age = 25; $stmt->execute(); // قراءة (SELECT) $sql = "SELECT id, name, email FROM users"; $stmt = $conn->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($result as $row) { echo "الاسم: " . $row["name"] . " - البريد: " . $row["email"] . "<br>"; } // تحديث (UPDATE) $sql = "UPDATE users SET name=:name WHERE id=:id"; $stmt = $conn->prepare($sql); $stmt->bindParam(':name', $name); $stmt->bindParam(':id', $id); $name = "محمد"; $id = 1; $stmt->execute(); // حذف (DELETE) $sql = "DELETE FROM users WHERE id=:id"; $stmt = $conn->prepare($sql); $stmt->bindParam(':id', $id); $id = 2; $stmt->execute();
نصيحة: دائماً استخدم Prepared Statements لحماية تطبيقك من هجمات SQL Injection.

فئة مساعدة لقاعدة البيانات

فئة Database Helper
<?php class Database { private $host = "localhost"; private $db_name = "myDB"; private $username = "username"; private $password = "password"; public $conn; public function getConnection() { $this->conn = null; try { $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password); $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->conn->exec("set names utf8"); } catch(PDOException $exception) { echo "خطأ في الاتصال: " . $exception->getMessage(); } return $this->conn; } public function query($sql, $params = []) { $stmt = $this->conn->prepare($sql); $stmt->execute($params); return $stmt; } public function fetchAll($sql, $params = []) { $stmt = $this->query($sql, $params); return $stmt->fetchAll(PDO::FETCH_ASSOC); } public function fetchOne($sql, $params = []) { $stmt = $this->query($sql, $params); return $stmt->fetch(PDO::FETCH_ASSOC); } } // استخدام الفئة $database = new Database(); $db = $database->getConnection(); // جلب جميع المستخدمين $users = $database->fetchAll("SELECT * FROM users"); // جلب مستخدم واحد $user = $database->fetchOne("SELECT * FROM users WHERE id = ?", [1]);

المعاملات (Transactions)

استخدام المعاملات
<?php try { $conn->beginTransaction(); // تنفيذ عدة استعلامات $stmt1 = $conn->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); $stmt1->execute([100, 1]); $stmt2 = $conn->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); $stmt2->execute([100, 2]); // تأكيد المعاملة $conn->commit(); echo "تمت المعاملة بنجاح"; } catch(PDOException $e) { // التراجع عن المعاملة في حالة الخطأ $conn->rollBack(); echo "فشلت المعاملة: " . $e->getMessage(); }

الجلسات والمصادقة

متوسط

نظام الجلسات والمصادقة

نظام المصادقة يسمح للمستخدمين بتسجيل الدخول إلى التطبيق بشكل آمن. يستخدم الجلسات (Sessions) وتشفير كلمات المرور:

  • ✅ جلسات آمنة مع تجديد معرف الجلسة
  • ✅ تشفير كلمات المرور باستخدام Bcrypt
  • ✅ نظام تذكرني باستخدام الكوكيز الآمنة
  • ✅ حماية من هجمات CSRF
  • ✅ إدارة الصلاحيات والمستخدمين

فئة المصادقة Auth الكاملة

فئة Auth.php - نظام المصادقة الكامل
<?php class Auth { private $db; private $session_name = 'user_id'; public function __construct($database) { $this->db = $database; $this->startSession(); } // بدء الجلسة بشكل آمن private function startSession() { if (session_status() == PHP_SESSION_NONE) { session_start(); } session_regenerate_id(true); } // تسجيل دخول المستخدم public function login($email, $password, $remember = false) { $user = $this->getUserByEmail($email); if ($user && password_verify($password, $user['password'])) { $_SESSION[$this->session_name] = $user['id']; if ($remember) { $this->setRememberToken($user['id']); } return true; } return false; } // تسجيل خروج المستخدم public function logout() { unset($_SESSION[$this->session_name]); $this->clearRememberToken(); session_destroy(); } // التحقق من تسجيل الدخول public function isLoggedIn() { if (isset($_SESSION[$this->session_name])) { return true; } // التحقق من كوكيز التذكر return $this->loginFromRememberToken(); } // الحصول على بيانات المستخدم الحالي public function getCurrentUser() { if (!$this->isLoggedIn()) { return null; } $user_id = $_SESSION[$this->session_name]; return $this->getUserById($user_id); } // تسجيل مستخدم جديد public function register($name, $email, $password) { if ($this->getUserByEmail($email)) { return "البريد الإلكتروني مسجل مسبقاً"; } $hashed_password = password_hash($password, PASSWORD_DEFAULT); $sql = "INSERT INTO users (name, email, password, created_at) VALUES (?, ?, ?, NOW())"; $stmt = $this->db->prepare($sql); $stmt->execute([$name, $email, $hashed_password]); return $this->db->lastInsertId(); } // دوال مساعدة خاصة private function getUserByEmail($email) { $sql = "SELECT * FROM users WHERE email = ?"; $stmt = $this->db->prepare($sql); $stmt->execute([$email]); return $stmt->fetch(PDO::FETCH_ASSOC); } private function getUserById($id) { $sql = "SELECT id, name, email, created_at FROM users WHERE id = ?"; $stmt = $this->db->prepare($sql); $stmt->execute([$id]); return $stmt->fetch(PDO::FETCH_ASSOC); } private function setRememberToken($user_id) { $token = bin2hex(random_bytes(32)); $expires = date('Y-m-d H:i:s', strtotime('+30 days')); $sql = "INSERT INTO remember_tokens (user_id, token, expires_at) VALUES (?, ?, ?)"; $stmt = $this->db->prepare($sql); $stmt->execute([$user_id, $token, $expires]); setcookie('remember_token', $token, strtotime('+30 days'), '/', '', true, true); } private function loginFromRememberToken() { if (!isset($_COOKIE['remember_token'])) { return false; } $token = $_COOKIE['remember_token']; $sql = "SELECT user_id FROM remember_tokens WHERE token = ? AND expires_at > NOW()"; $stmt = $this->db->prepare($sql); $stmt->execute([$token]); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result) { $_SESSION[$this->session_name] = $result['user_id']; return true; } return false; } private function clearRememberToken() { if (isset($_COOKIE['remember_token'])) { $token = $_COOKIE['remember_token']; $sql = "DELETE FROM remember_tokens WHERE token = ?"; $stmt = $this->db->prepare($sql); $stmt->execute([$token]); setcookie('remember_token', '', time() - 3600, '/'); } } }
💡 نصائح أمنية:
  • استخدم session_regenerate_id(true) لمنع هجمات Session Fixation
  • استخدم password_hash() و password_verify() دائماً
  • ضبط إعدادات الكوكيز مع HttpOnly و Secure
  • استخدم Prepared Statements لمنع هجمات SQL Injection

طريقة الاستخدام

استخدام فئة Auth
<?php // تضمين الفئة require_once 'Auth.php'; require_once 'Database.php'; // إنشاء كائن الاتصال بقاعدة البيانات $database = new Database(); $db = $database->getConnection(); // إنشاء كائن المصادقة $auth = new Auth($db); // مثال: تسجيل الدخول if ($_POST['action'] == 'login') { $email = $_POST['email']; $password = $_POST['password']; $remember = isset($_POST['remember']); if ($auth->login($email, $password, $remember)) { echo "تم تسجيل الدخول بنجاح!"; header("Location: dashboard.php"); } else { echo "البريد الإلكتروني أو كلمة المرور غير صحيحة"; } } // مثال: التحقق من تسجيل الدخول if (!$auth->isLoggedIn()) { header("Location: login.php"); exit; } // الحصول على بيانات المستخدم الحالي $user = $auth->getCurrentUser(); echo "مرحباً, " . $user['name'];

جداول قاعدة البيانات

جداول قاعدة البيانات
-- جدول المستخدمين CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- جدول تذكرني CREATE TABLE remember_tokens ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, token VARCHAR(64) UNIQUE NOT NULL, expires_at DATETIME NOT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );

النماذج والإدخال

متوسط

معالجة النماذج في PHP

PHP تتعامل مع بيانات النماذج من خلال المتغيرات الخاصة $_POST, $_GET, و $_REQUEST:

  • ✅ التحقق من صحة البيانات (Validation)
  • ✅ تنقية الإدخال (Sanitization)
  • ✅ حماية من هجمات XSS
  • ✅ رفع الملفات والتعامل معها
  • ✅ إعادة تعبئة النماذج تلقائياً

معالجة النماذج الأساسية

معالجة نموذج تسجيل الدخول
<?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { // تنظيف الإدخال $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); $password = trim($_POST['password']); // التحقق من الصحة $errors = []; if (empty($email)) { $errors[] = "البريد الإلكتروني مطلوب"; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors[] = "صيغة البريد الإلكتروني غير صحيحة"; } if (empty($password)) { $errors[] = "كلمة المرور مطلوبة"; } if (strlen($password) < 6) { $errors[] = "كلمة المرور يجب أن تكون 6 أحرف على الأقل"; } if (empty($errors)) { // معالجة النموذج بنجاح $success = "تم إرسال النموذج بنجاح!"; // هنا يمكنك إضافة المستخدم إلى قاعدة البيانات // أو تنفيذ أي عملية أخرى } }

فئة التحقق من الصحة (Validation Class)

فئة Validation المتقدمة
<?php class Validator { private $data; private $errors = []; public function __construct($post_data) { $this->data = $post_data; } public function validateField($field, $rules) { $value = $this->data[$field] ?? ''; foreach ($rules as $rule) { switch ($rule) { case 'required': if (empty(trim($value))) { $this->addError($field, "حقل {$field} مطلوب"); } break; case 'email': if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { $this->addError($field, "صيغة البريد الإلكتروني غير صحيحة"); } break; case 'min:6': if (strlen($value) < 6) { $this->addError($field, "يجب أن يكون {$field} 6 أحرف على الأقل"); } break; case 'numeric': if (!is_numeric($value)) { $this->addError($field, "يجب أن يكون {$field} رقماً"); } break; } } } private function addError($field, $message) { $this->errors[$field][] = $message; } public function getErrors() { return $this->errors; } public function isValid() { return empty($this->errors); } } // استخدام الفئة $validator = new Validator($_POST); $validator->validateField('email', ['required', 'email']); $validator->validateField('password', ['required', 'min:6']); if ($validator->isValid()) { // النموذج صحيح } else { $errors = $validator->getErrors(); }

رفع الملفات

رفع الملفات بشكل آمن
<?php if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) { $uploadDir = 'uploads/'; $allowedTypes = ['image/jpeg', 'image/png', 'image/gif']; $maxSize = 2 * 1024 * 1024; // 2MB $file = $_FILES['file']; $fileName = basename($file['name']); $fileTmp = $file['tmp_name']; $fileSize = $file['size']; $fileType = $file['type']; // التحقق من نوع الملف if (!in_array($fileType, $allowedTypes)) { die("نوع الملف غير مسموح به"); } // التحقق من حجم الملف if ($fileSize > $maxSize) { die("حجم الملف كبير جداً"); } // إنشاء اسم فريد للملف $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION); $newFileName = uniqid() . '.' . $fileExtension; $uploadPath = $uploadDir . $newFileName; // رفع الملف if (move_uploaded_file($fileTmp, $uploadPath)) { echo "تم رفع الملف بنجاح: " . $newFileName; } else { echo "فشل في رفع الملف"; } }

الملفات

متوسط

التعامل مع الملفات في PHP

PHP توفر دوال متعددة للتعامل مع نظام الملفات:

  • ✅ قراءة وكتابة الملفات
  • ✅ رفع الملفات بشكل آمن
  • ✅ التعامل مع المجلدات
  • ✅ معالجة الصور (resize, crop, watermark)
  • ✅ إنشاء وتحميل الملفات

قراءة وكتابة الملفات

العمليات الأساسية على الملفات
<?php // كتابة إلى ملف $filename = 'example.txt'; $content = "مرحباً بالعالم!\nهذا مثال على كتابة ملف."; if (file_put_contents($filename, $content) !== false) { echo "تم كتابة الملف بنجاح"; } else { echo "فشل في كتابة الملف"; } // قراءة من ملف if (file_exists($filename)) { $content = file_get_contents($filename); echo $content; } // إضافة محتوى إلى ملف موجود $newContent = "\nهذا سطر جديد تم إضافته."; file_put_contents($filename, $newContent, FILE_APPEND); // قراءة الملف سطراً سطراً $lines = file($filename, FILE_IGNORE_NEW_LINES); foreach ($lines as $line) { echo $line . "<br>"; }

معالجة الصور

معالجة الصور باستخدام GD Library
<?php class ImageProcessor { private $image; private $imageType; public function load($filename) { $imageInfo = getimagesize($filename); $this->imageType = $imageInfo[2]; switch ($this->imageType) { case IMAGETYPE_JPEG: $this->image = imagecreatefromjpeg($filename); break; case IMAGETYPE_PNG: $this->image = imagecreatefrompng($filename); break; case IMAGETYPE_GIF: $this->image = imagecreatefromgif($filename); break; default: throw new Exception("نوع الصورة غير مدعوم"); } } public function resize($width, $height) { $newImage = imagecreatetruecolor($width, $height); // الحفاظ على الشفافية للصور PNG و GIF if ($this->imageType == IMAGETYPE_PNG || $this->imageType == IMAGETYPE_GIF) { imagecolortransparent($newImage, imagecolorallocatealpha($newImage, 0, 0, 0, 127)); imagealphablending($newImage, false); imagesavealpha($newImage, true); } imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $width, $height, imagesx($this->image), imagesy($this->image)); $this->image = $newImage; } public function save($filename, $compression = 75) { switch ($this->imageType) { case IMAGETYPE_JPEG: imagejpeg($this->image, $filename, $compression); break; case IMAGETYPE_PNG: imagepng($this->image, $filename); break; case IMAGETYPE_GIF: imagegif($this->image, $filename); break; } } public function __destruct() { if ($this->image) { imagedestroy($this->image); } } } // استخدام الفئة $processor = new ImageProcessor(); $processor->load('input.jpg'); $processor->resize(800, 600); $processor->save('output.jpg');

APIs

متقدم

تطوير واستهلاك APIs في PHP

PHP تدعم إنشاء واستهلاك واجهات برمجة التطبيقات (APIs):

  • ✅ إنشاء REST API كامل
  • ✅ JWT Authentication
  • ✅ استهلاك APIs خارجية
  • ✅ Rate Limiting
  • ✅ التوثيق باستخدام Swagger/OpenAPI

إنشاء REST API

REST API بسيط للمستخدمين
<?php class UserAPI { private $db; public function __construct() { $this->db = new Database(); $this->handleRequest(); } private function handleRequest() { $method = $_SERVER['REQUEST_METHOD']; $endpoint = str_replace('/api/', '', $_SERVER['REQUEST_URI']); switch ($method) { case 'GET': $this->handleGet($endpoint); break; case 'POST': $this->handlePost($endpoint); break; case 'PUT': $this->handlePut($endpoint); break; case 'DELETE': $this->handleDelete($endpoint); break; default: $this->sendResponse(405, ['error' => 'Method not allowed']); } } private function handleGet($endpoint) { if ($endpoint == 'users') { $users = $this->db->fetchAll("SELECT id, name, email FROM users"); $this->sendResponse(200, $users); } elseif (preg_match('/^users\/(\d+)$/', $endpoint, $matches)) { $userId = $matches[1]; $user = $this->db->fetchOne("SELECT id, name, email FROM users WHERE id = ?", [$userId]); if ($user) { $this->sendResponse(200, $user); } else { $this->sendResponse(404, ['error' => 'User not found']); } } else { $this->sendResponse(404, ['error' => 'Endpoint not found']); } } private function sendResponse($statusCode, $data) { http_response_code($statusCode); header('Content-Type: application/json'); echo json_encode($data); exit; } } // تشغيل الـ API new UserAPI();

JWT Authentication للـ API

JWT Authentication
<?php class JWT { private $secret_key = "your-secret-key"; public function generate($payload) { $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']); $payload = json_encode($payload); $base64UrlHeader = $this->base64UrlEncode($header); $base64UrlPayload = $this->base64UrlEncode($payload); $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $this->secret_key, true); $base64UrlSignature = $this->base64UrlEncode($signature); return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature; } public function verify($token) { $parts = explode('.', $token); if (count($parts) != 3) { return false; } $signature = hash_hmac('sha256', $parts[0] . "." . $parts[1], $this->secret_key, true); $base64UrlSignature = $this->base64UrlEncode($signature); return hash_equals($base64UrlSignature, $parts[2]); } public function decode($token) { $parts = explode('.', $token); $payload = json_decode($this->base64UrlDecode($parts[1]), true); return $payload; } private function base64UrlEncode($data) { return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data)); } private function base64UrlDecode($data) { return base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); } } // استخدام JWT $jwt = new JWT(); $token = $jwt->generate([ 'user_id' => 123, 'exp' => time() + (60 * 60) // expires in 1 hour ]); if ($jwt->verify($token)) { $payload = $jwt->decode($token); echo "User ID: " . $payload['user_id']; }

الأمان

متقدم

أمان تطبيقات PHP

حماية تطبيقك من الهجمات الأمنية أمر بالغ الأهمية:

  • ✅ الحماية من SQL Injection
  • ✅ الحماية من XSS Attacks
  • ✅ الحماية من CSRF Attacks
  • ✅ تشفير كلمات المرور
  • ✅ تأمين الجلسات والكوكيز
  • ✅ Security Headers

الحماية من SQL Injection

استخدام Prepared Statements
<?php // ❌ خطأ - عرضة لـ SQL Injection $user_id = $_GET['id']; $sql = "SELECT * FROM users WHERE id = $user_id"; $result = mysqli_query($conn, $sql); // ✅ صحيح - استخدام Prepared Statements $user_id = $_GET['id']; $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param("i", $user_id); $stmt->execute(); $result = $stmt->get_result(); // مع PDO $stmt = $conn->prepare("SELECT * FROM users WHERE id = :id"); $stmt->bindParam(':id', $user_id, PDO::PARAM_INT); $stmt->execute();

الحماية من XSS Attacks

تنقية الإخراج
<?php class Security { // تنقية الإدخال من XSS public static function sanitizeInput($input) { if (is_array($input)) { return array_map([self::class, 'sanitizeInput'], $input); } $input = trim($input); $input = stripslashes($input); $input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8'); return $input; } // تنقية الإخراج للعرض في HTML public static function escapeOutput($data) { if (is_array($data)) { return array_map([self::class, 'escapeOutput'], $data); } return htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); } // توليد CSRF Token public static function generateCSRFToken() { if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } return $_SESSION['csrf_token']; } // التحقق من CSRF Token public static function verifyCSRFToken($token) { return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token); } } // استخدام الفئة $clean_input = Security::sanitizeInput($_POST['user_input']); $safe_output = Security::escapeOutput($data); // في النموذج $csrf_token = Security::generateCSRFToken(); echo '<input type="hidden" name="csrf_token" value="' . $csrf_token . '">'; // عند معالجة النموذج if (!Security::verifyCSRFToken($_POST['csrf_token'])) { die("طلب غير مصرح به"); }

تأمين الجلسات

إعدادات الجلسات الآمنة
<?php ini_set('session.cookie_httponly', 1); ini_set('session.cookie_secure', 1); ini_set('session.use_strict_mode', 1); ini_set('session.cookie_samesite', 'Strict'); class SecureSession { public static function start() { session_start(); // تجديد معرف الجلسة لمنع fixation attacks if (empty($_SESSION['created'])) { session_regenerate_id(true); $_SESSION['created'] = time(); } elseif (time() - $_SESSION['created'] > 1800) { // تجديد كل 30 دقيقة session_regenerate_id(true); $_SESSION['created'] = time(); } } public static function destroy() { $_SESSION = []; if (ini_get("session.use_cookies")) { $params = session_get_cookie_params(); setcookie( session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly'] ); } session_destroy(); } } SecureSession::start();

Security Headers

رؤوس الأمان
<?php class SecurityHeaders { public static function setHeaders() { // منع XSS header("X-XSS-Protection: 1; mode=block"); // منع MIME sniffing header("X-Content-Type-Options: nosniff"); // منع clickjacking header("X-Frame-Options: DENY"); // سياسة أمان المحتوى header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"); // إحالة آمنة header("Referrer-Policy: strict-origin-when-cross-origin"); // ميزات المتصفح header("Feature-Policy: geolocation 'none'; microphone 'none'; camera 'none'"); } } SecurityHeaders::setHeaders();

OOP

متقدم

البرمجة كائنية التوجه في PHP

PHP تدعم البرمجة كائنية التوجه بشكل كامل:

  • ✅ الكلاسات والكائنات
  • ✅ الوراثة والتعددية
  • ✅ الواجهات والكلاسات المجردة
  • ✅ الـ Traits
  • ✅ الطرق الساكنة والثوابت
  • ✅ الطرق السحرية
  • ✅ الـ Namespaces

الكلاسات والكائنات

إنشاء واستخدام الكلاسات
<?php class User { // الخصائص private $id; public $name; protected $email; public static $count = 0; // الكونستركتور public function __construct($name, $email) { $this->name = $name; $this->email = $email; $this->id = uniqid(); self::$count++; } // الديستركتور public function __destruct() { self::$count--; } // Methods public function getEmail() { return $this->email; } public function setEmail($email) { if (filter_var($email, FILTER_VALIDATE_EMAIL)) { $this->email = $email; return true; } return false; } // Static method public static function getCount() { return self::$count; } // Magic methods public function __toString() { return "User: {$this->name} ({$this->email})"; } public function __get($property) { if (property_exists($this, $property)) { return $this->$property; } } public function __set($property, $value) { if (property_exists($this, $property)) { $this->$property = $value; } } } // استخدام الكلاس $user1 = new User("أحمد", "ahmed@example.com"); $user2 = new User("محمد", "mohamed@example.com"); echo $user1->name; // أحمد echo $user1->getEmail(); // ahmed@example.com echo User::getCount(); // 2 echo $user1; // User: أحمد (ahmed@example.com)

الوراثة والتعددية

الوراثة والواجهات
<?php // واجهة interface Authenticatable { public function login($credentials); public function logout(); } // كلاس مجرد abstract class Model { protected $table; abstract public function save(); public function getTable() { return $this->table; } } // كلاس يرث من Model وينفذ Authenticatable class Admin extends Model implements Authenticatable { protected $table = 'admins'; private $username; private $password; public function __construct($username, $password) { $this->username = $username; $this->password = $password; } // تنفيذ الواجهة public function login($credentials) { return $credentials['username'] === $this->username && password_verify($credentials['password'], $this->password); } public function logout() { // تنفيذ عملية تسجيل الخروج return true; } // تنفيذ الدالة المجردة public function save() { // حفظ البيانات في قاعدة البيانات return true; } // Override public function getTable() { return "admin_" . parent::getTable(); } } $admin = new Admin("admin", password_hash("123456", PASSWORD_DEFAULT)); echo $admin->getTable(); // admin_admins

Traits

استخدام Traits
<?php trait Loggable { public function log($message) { $timestamp = date('Y-m-d H:i:s'); $logMessage = "[$timestamp] $message\n"; file_put_contents('app.log', $logMessage, FILE_APPEND); } } trait Timestampable { public function setTimestamps() { $this->created_at = date('Y-m-d H:i:s'); $this->updated_at = date('Y-m-d H:i:s'); } public function updateTimestamp() { $this->updated_at = date('Y-m-d H:i:s'); } } class Product { use Loggable, Timestampable; private $name; private $price; public $created_at; public $updated_at; public function __construct($name, $price) { $this->name = $name; $this->price = $price; $this->setTimestamps(); $this->log("Product created: $name"); } public function updatePrice($newPrice) { $this->price = $newPrice; $this->updateTimestamp(); $this->log("Product price updated: $newPrice"); } } $product = new Product("Laptop", 1000); $product->updatePrice(900);

Namespaces والـ Autoloading

Namespaces و Autoloading
<?php // autoload.php spl_autoload_register(function ($className) { $file = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; if (file_exists($file)) { require_once $file; } }); // App/Models/User.php namespace App\Models; class User { private $name; private $email; public function __construct($name, $email) { $this->name = $name; $this->email = $email; } } // App/Services/EmailService.php namespace App\Services; use App\Models\User; class EmailService { public function sendWelcomeEmail(User $user) { // إرسال بريد ترحيبي return true; } } // index.php require_once 'autoload.php'; use App\Models\User; use App\Services\EmailService; $user = new User("أحمد", "ahmed@example.com"); $emailService = new EmailService(); $emailService->sendWelcomeEmail($user);

دوال مهمة

جميع المستويات

أهم دوال PHP

PHP توفر المئات من الدوال الجاهزة للاستخدام:

  • ✅ دوال النصوص والسلاسل
  • ✅ دوال المصفوفات
  • ✅ دوال التاريخ والوقت
  • ✅ دوال الملفات
  • ✅ دوال الرياضيات
  • ✅ دوال JSON
  • ✅ دوال URLs

دوال النصوص والسلاسل

أهم دوال النصوص
<?php $text = " مرحباً بالعالم! "; // إزالة المسافات $trimmed = trim($text); // "مرحباً بالعالم!" // طول النص $length = strlen($text); // 23 $mb_length = mb_strlen($trimmed); // 15 (للنصوص العربية) // تحويل الحروف $upper = strtoupper("hello"); // "HELLO" $lower = strtolower("HELLO"); // "hello" // البحث والاستبدال $new_text = str_replace("العالم", "PHP", $text); // " مرحباً بـ PHP! " $position = strpos($text, "مرحباً"); // 3 // تقسيم النص $words = explode(" ", $trimmed); // ["مرحباً", "بالعالم!"] $sentence = implode("-", $words); // "مرحباً-بالعالم!" // أخذ جزء من النص $substring = substr($text, 3, 7); // "مرحباً" $mb_substring = mb_substr($text, 3, 7); // "مرحباً" (للنصوص العربية) // تنسيق النص $name = "أحمد"; $age = 25; $formatted = sprintf("اسمي %s وعمري %d سنة", $name, $age); // التعامل مع النصوص متعددة البايت $arabic_text = "اللغة العربية"; $reversed = mb_strrev($arabic_text); // "ةيبرعا ةغلا" // دالة عكس النص للغة العربية function mb_strrev($string) { $chars = mb_str_split($string); return implode('', array_reverse($chars)); }

دوال المصفوفات

أهم دوال المصفوفات
<?php $numbers = [1, 2, 3, 4, 5]; $users = [ ['name' => 'أحمد', 'age' => 25], ['name' => 'محمد', 'age' => 30], ['name' => 'فاطمة', 'age' => 22] ]; // إضافة وعرض العناصر array_push($numbers, 6); // [1,2,3,4,5,6] $last = array_pop($numbers); // 6 array_unshift($numbers, 0); // [0,1,2,3,4,5] $first = array_shift($numbers); // 0 // البحث في المصفوفات $hasThree = in_array(3, $numbers); // true $key = array_search(3, $numbers); // 2 $keys = array_keys($users[0]); // ['name', 'age'] $values = array_values($users[0]); // ['أحمد', 25] // تصفية المصفوفات $even = array_filter($numbers, function($n) { return $n % 2 == 0; }); // [2,4] $adults = array_filter($users, function($user) { return $user['age'] >= 18; }); // تحويل المصفوفات $squared = array_map(function($n) { return $n * $n; }, $numbers); // [1,4,9,16,25] $names = array_map(function($user) { return $user['name']; }, $users); // ['أحمد', 'محمد', 'فاطمة'] // دمج وفرز المصفوفات $merged = array_merge($numbers, [6, 7, 8]); sort($numbers); rsort($numbers); // دوال رياضية للمصفوفات $sum = array_sum($numbers); // 15 $product = array_product($numbers); // 120 $count = count($numbers); // 5 // مصفوفات متعددة الأبعاد $matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; $column = array_column($matrix, 1); // [2,5,8]

دوال التاريخ والوقت

دوال التاريخ والوقت
<?php // التاريخ والوقت الحالي $now = date('Y-m-d H:i:s'); // "2024-01-15 14:30:25" $timestamp = time(); // 1705339825 // تنسيق التواريخ $today = date('l, j F Y'); // "Monday, 15 January 2024" $time = date('h:i A'); // "02:30 PM" // التعامل مع DateTime $datetime = new DateTime(); $datetime->modify('+1 day'); $tomorrow = $datetime->format('Y-m-d'); $birthday = DateTime::createFromFormat('d/m/Y', '15/01/1990'); $age = $birthday->diff(new DateTime())->y; // المناطق الزمنية $utc = new DateTimeZone('UTC'); $ksa = new DateTimeZone('Asia/Riyadh'); $date = new DateTime('now', $utc); $date->setTimezone($ksa); // دوال مفيدة $is_leap = date('L'); // 1 if leap year, 0 otherwise $day_of_week = date('N'); // 1 (Monday) to 7 (Sunday) $week_number = date('W'); // Week number of year // التحقق من صحة التاريخ $is_valid = checkdate(2, 29, 2024); // true (leap year) $is_valid = checkdate(2, 29, 2023); // false // الوقت باللغة العربية function arabicDate($timestamp) { $months = [ 'January' => 'يناير', 'February' => 'فبراير', // ... باقي الأشهر ]; $english_date = date('F j, Y', $timestamp); return strtr($english_date, $months); } echo arabicDate(time()); // "يناير 15, 2024"
💡 ملاحظة: تم تضمين أهم الدوال في كل فئة. يمكنك استكشاف المزيد من الدوال في التوثيق الرسمي لـ PHP.

معالجة الأخطاء

متوسط

معالجة الأخطاء في PHP

إدارة الأخطاء بشكل صحيح يجعل تطبيقك أكثر استقراراً:

  • ✅ Try-Catch للاستثناءات
  • ✅ معالج الأخطاء المخصص
  • ✅ فئة التسجيل (Logging)
  • ✅ Assertions للاختبارات
  • ✅ تصنيف الأخطاء والاستثناءات

معالجة الاستثناءات

Try-Catch والاستثناءات المخصصة
<?php // استثناء مخصص class ValidationException extends Exception { private $errors; public function __construct($message, $errors = [], $code = 0, Throwable $previous = null) { $this->errors = $errors; parent::__construct($message, $code, $previous); } public function getErrors() { return $this->errors; } } class UserService { public function register($userData) { $errors = []; // التحقق من البيانات if (empty($userData['name'])) { $errors['name'] = "الاسم مطلوب"; } if (!filter_var($userData['email'], FILTER_VALIDATE_EMAIL)) { $errors['email'] = "البريد الإلكتروني غير صحيح"; } if (!empty($errors)) { throw new ValidationException("فشل في التحقق من البيانات", $errors); } // محاولة إنشاء المستخدم try { return $this->createUser($userData); } catch (PDOException $e) { throw new Exception("فشل في إنشاء المستخدم: " . $e->getMessage()); } } } // استخدام الخدمة مع معالجة الأخطاء $userService = new UserService(); try { $user = $userService->register([ 'name' => 'أحمد', 'email' => 'ahmed@example.com' ]); echo "تم إنشاء المستخدم بنجاح!"; } catch (ValidationException $e) { $errors = $e->getErrors(); echo "أخطاء التحقق: "; print_r($errors); } catch (Exception $e) { echo "حدث خطأ: " . $e->getMessage(); } finally { // هذا الكود سينفذ دائماً echo "تم الانتهاء من العملية"; }

معالج الأخطاء المخصص

معالج الأخطاء والتسجيل
<?php class ErrorHandler { public static function register() { // معالج الأخطاء set_error_handler([self::class, 'handleError']); // معالج الاستثناءات set_exception_handler([self::class, 'handleException']); // معالج الإغلاق register_shutdown_function([self::class, 'handleShutdown']); } public static function handleError($level, $message, $file = '', $line = 0) { throw new ErrorException($message, 0, $level, $file, $line); } public static function handleException(Throwable $exception) { self::logError( $exception->getMessage(), $exception->getFile(), $exception->getLine(), $exception->getTraceAsString() ); // عرض رسالة خطأ مناسبة للمستخدم if (ini_get('display_errors')) { self::displayError($exception); } else { self::displayFriendlyError(); } exit(1); } public static function handleShutdown() { $error = error_get_last(); if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { self::logError( $error['message'], $error['file'], $error['line'] ); self::displayFriendlyError(); } } private static function logError($message, $file, $line, $trace = '') { $logMessage = sprintf( "[%s] Error: %s in %s on line %d\nTrace: %s\n\n", date('Y-m-d H:i:s'), $message, $file, $line, $trace ); error_log($logMessage, 3, 'errors.log'); } private static function displayError(Throwable $exception) { echo "<div style='border: 1px solid #f00; padding: 10px; margin: 10px;'>"; echo "<h3>خطأ: </h3>"; echo "<p><strong>الرسالة:</strong> {$exception->getMessage()}</p>"; echo "<p><strong>الملف:</strong> {$exception->getFile()}</p>"; echo "<p><strong>السطر:</strong> {$exception->getLine()}</p>"; echo "<pre>{$exception->getTraceAsString()}</pre>"; echo "</div>"; } private static function displayFriendlyError() { http_response_code(500); echo "<h1>عذراً، حدث خطأ</h1>"; echo "<p>نواجه بعض المشاكل التقنية. الرجاء المحاولة لاحقاً.</p>"; } } // تسجيل معالج الأخطاء ErrorHandler::register();

فئة التسجيل (Logging)

فئة Logging متقدمة
<?php class Logger { const DEBUG = 100; const INFO = 200; const WARNING = 300; const ERROR = 400; const CRITICAL = 500; private $logFile; private $minLogLevel; public function __construct($logFile = 'app.log', $minLogLevel = self::DEBUG) { $this->logFile = $logFile; $this->minLogLevel = $minLogLevel; } public function debug($message, $context = []) { $this->log(self::DEBUG, $message, $context); } public function info($message, $context = []) { $this->log(self::INFO, $message, $context); } public function warning($message, $context = []) { $this->log(self::WARNING, $message, $context); } public function error($message, $context = []) { $this->log(self::ERROR, $message, $context); } public function critical($message, $context = []) { $this->log(self::CRITICAL, $message, $context); } private function log($level, $message, $context = []) { if ($level < $this->minLogLevel) { return; } $levelName = $this->getLevelName($level); $timestamp = date('Y-m-d H:i:s'); $logMessage = sprintf( "[%s] %s: %s", $timestamp, $levelName, $this->interpolate($message, $context) ); file_put_contents($this->logFile, $logMessage . PHP_EOL, FILE_APPEND | LOCK_EX); } private function getLevelName($level) { $levels = [ self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::WARNING => 'WARNING', self::ERROR => 'ERROR', self::CRITICAL => 'CRITICAL', ]; return $levels[$level] ?? 'UNKNOWN'; } private function interpolate($message, $context = []) { $replace = []; foreach ($context as $key => $val) { $replace['{' . $key . '}'] = is_scalar($val) ? $val : json_encode($val); } return strtr($message, $replace); } } // استخدام الـ Logger $logger = new Logger('application.log', Logger::INFO); $logger->info("User {username} logged in", ['username' => 'ahmed']); $logger->error("Database connection failed", ['error' => $e->getMessage()]);

متقدم

متقدم

مواضيع متقدمة في PHP

تقنيات متقدمة لتطوير تطبيقات PHP احترافية:

  • ✅ Composer و Autoloading
  • ✅ Dependency Injection
  • ✅ Design Patterns
  • ✅ Middleware Pattern
  • ✅ Caching System
  • ✅ Queue System
  • ✅ Events System
  • ✅ Database Migrations
  • ✅ Email Templating

Composer و Dependency Injection

Composer و DI Container
<?php // composer.json مثال { "name": "myproject/app", "type": "project", "autoload": { "psr-4": { "App\\": "src/" } }, "require": { "php": "^8.0" } } // DI Container بسيط class Container { private $bindings = []; private $instances = []; public function bind($abstract, $concrete = null) { if (is_null($concrete)) { $concrete = $abstract; } $this->bindings[$abstract] = $concrete; } public function singleton($abstract, $concrete = null) { $this->bind($abstract, $concrete); $this->instances[$abstract] = null; } public function make($abstract) { // إذا كان موجود في الـ instances if (isset($this->instances[$abstract])) { return $this->instances[$abstract]; } // الحصول على الـ concrete $concrete = $this->bindings[$abstract] ?? $abstract; // إذا كان callable if (is_callable($concrete)) { $object = call_user_func($concrete, $this); } else { $object = $this->build($concrete); } // إذا كان singleton if (array_key_exists($abstract, $this->instances)) { $this->instances[$abstract] = $object; } return $object; } private function build($concrete) { $reflector = new ReflectionClass($concrete); if (!$reflector->isInstantiable()) { throw new Exception("Class {$concrete} is not instantiable"); } $constructor = $reflector->getConstructor(); if (is_null($constructor)) { return new $concrete; } $parameters = $constructor->getParameters(); $dependencies = $this->getDependencies($parameters); return $reflector->newInstanceArgs($dependencies); } private function getDependencies($parameters) { $dependencies = []; foreach ($parameters as $parameter) { $dependency = $parameter->getType(); if (is_null($dependency)) { if ($parameter->isDefaultValueAvailable()) { $dependencies[] = $parameter->getDefaultValue(); } else { throw new Exception("Can not resolve dependency {$parameter->name}"); } } else { $dependencies[] = $this->make($dependency->getName()); } } return $dependencies; } } // استخدام الـ Container $container = new Container(); // ربط الـ dependencies $container->bind(Database::class); $container->singleton(Logger::class); // الحصول على instance $db = $container->make(Database::class); $logger = $container->make(Logger::class);

Design Patterns

أنماط التصميم الشائعة
<?php // 1. Singleton Pattern class DatabaseConnection { private static $instance = null; private $connection; private function __construct() { $this->connection = new PDO("mysql:host=localhost;dbname=test", "username", "password"); } public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } public function getConnection() { return $this->connection; } private function __clone() {} private function __wakeup() {} } // 2. Factory Pattern interface Notification { public function send($message); } class EmailNotification implements Notification { public function send($message) { echo "Sending email: $message\n"; } } class SMSNotification implements Notification { public function send($message) { echo "Sending SMS: $message\n"; } } class NotificationFactory { public static function create($type) { switch ($type) { case 'email': return new EmailNotification(); case 'sms': return new SMSNotification(); default: throw new Exception("Unknown notification type"); } } } // 3. Repository Pattern interface UserRepositoryInterface { public function find($id); public function findAll(); public function save(User $user); public function delete(User $user); } class UserRepository implements UserRepositoryInterface { private $db; public function __construct(DatabaseConnection $db) { $this->db = $db->getConnection(); } public function find($id) { $stmt = $this->db->prepare("SELECT * FROM users WHERE id = ?"); $stmt->execute([$id]); return $stmt->fetch(PDO::FETCH_ASSOC); } public function findAll() { $stmt = $this->db->prepare("SELECT * FROM users"); $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } public function save(User $user) { // حفظ المستخدم } public function delete(User $user) { // حذف المستخدم } } // استخدام الأنماط $db = DatabaseConnection::getInstance(); $notification = NotificationFactory::create('email'); $userRepo = new UserRepository($db);
🎯 ملخص شامل:

هذا التوثيق يغطي كل ما تحتاجه في PHP من الأساسيات إلى المستويات المتقدمة. يمكنك استخدامه كمرجع دائم والعودة إليه في أي وقت تحتاج فيه إلى أي شيء في PHP.