انتقل إلى محتوى الدرس
الدرس 79
دورة PHP

إنشاء قواعد البيانات والجداول وإدارة الهيكلة عبر PDO في PHPPDO Creating Databases Tables and Schema Setup

نفّذ أوامر بناء الهيكلة DDL بأمان في PHP 8 عبر PDO::exec لإنشاء قواعد البيانات وجداول UTF8MB4 والمفاتيح الأساسية والفهارس.
أقسام الدرس
6
الأمثلة
6
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

أوامر تعريف وهيكلة البيانات (DDL) مثل CREATE DATABASE وCREATE TABLE وALTER TABLE لا تُرجع صفوف نتائج، ولذلك تُنفذ مباشرة عبر الدالة $pdo->exec($sql).

  • تنفذ $pdo->exec($sql) أمر SQL واحداً لا يُرجع صفوفاً، وتُرجع الرقم 0 لأوامر الهيكلة (أو false عند الفشل).
  • لا تدمج مدخلات المستخدم أبداً داخل $pdo->exec()؛ فأسماء الجداول والأعمدة في ملفات التهجير يجب أن تكون ثابتة في الكود المصدري.
  • أضف العبارة IF NOT EXISTS في CREATE TABLE IF NOT EXISTS لتتمكن من تشغيل سكريبت التهجير بأمان دون خطأ وجود الجدول مسبقاً.

تنفذ $pdo->exec($sql) أمر إنشاء جدول settings في الذاكرة وتُرجع 0 دلالةً على نجاح أمر الهيكلة.

مخطط توضيحي: محاكي إنشاء قواعد البيانات والجداول والمفاتيح عبر PDO في PHP
PHP
<?php
$pdo = new PDO('sqlite::memory:');
$sql = 'CREATE TABLE IF NOT EXISTS settings (
    key_name VARCHAR(64) PRIMARY KEY,
    key_value TEXT NOT NULL
)';
$res = $pdo->exec($sql);
echo "DDL executed, return: $res\n";

عند إنشاء قاعدة بيانات MySQL أو MariaDB جديدة عبر PDO، اتصل بالخادم أولاً بدون تحديد dbname في نص DSN، ثم حدد الترميز CHARACTER SET utf8mb4.

  • ترميز MySQL القديم utf8 (أو utf8mb3) يدعم حتى 3 بايتات فقط للحرف ويفشل عند تخزين الرموز ذات الـ 4 بايتات.
  • استخدم دائماً CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci لضمان تخزين النصوص العربية والرموز التعبيرية بدقة كاملة.
  • بعد إنشاء قاعدة البيانات، انتقل إليها بالأمر $pdo->exec("USE app_db") أو أعد الاتصال مع تضمين dbname=app_db;charset=utf8mb4.

تحديد CHARACTER SET utf8mb4 مع المقارنة utf8mb4_unicode_ci يضمن دعم الترميز الرباعي والترتيب الأبجدي الصحيح.

PHP
<?php
$dbName = 'closetag_store';
$ddl = "CREATE DATABASE IF NOT EXISTS $dbName
        CHARACTER SET utf8mb4
        COLLATE utf8mb4_unicode_ci";
echo str_contains($ddl, 'utf8mb4_unicode_ci') ? "UTF8MB4 DDL Ready\n" : "Missing\n";

يجب أن يحتوي كل جدول علائقي على عمود مفتاح أساسي (PRIMARY KEY) يميز كل سجل بشكل فريد ويسرّع عمليات البحث والربط.

  • في MySQL، استخدم BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY لتوليد أرقام تعريف موجبة تتزايد تلقائياً مع كل سجل جديد.
  • حدد الأعمدة الإلزامية بالقيد NOT NULL وأضف قيماً افتراضية مثل DEFAULT CURRENT_TIMESTAMP لتاريخ الإنشاء.
  • استخدم النوع DECIMAL(10, 2) بدلاً من FLOAT للمبالغ المالية لتفادي أخطاء التقريب الثنائي في الكسور العشرية.

يعرّف جدول products مفتاحاً أساسياً متزايداً تلقائياً، وعنواناً إلزامياً VARCHAR(150)، وسعراً مالياً دقيقاً DECIMAL(10,2).

PHP
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE products (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title VARCHAR(150) NOT NULL,
    price DECIMAL(10,2) NOT NULL DEFAULT 0.00
)');
$pdo->exec("INSERT INTO products (title, price) VALUES ('Keyboard', 249.50)");
echo "Created ID: " . $pdo->lastInsertId() . "\n";

تمنع قيود عدم التكرار UNIQUE على مستوى قاعدة البيانات تسجيل بريد إلكتروني أو رمز منتج مكرر حتى مع الطلبات المتزامنة، بينما تسرّع الفهارس INDEX استعلامات البحث.

  • الاكتفاء بفحص عدم التكرار في كود PHP فقط عرضة لتعارض الطلبات المتزامنة؛ لذا يجب فرض قيد UNIQUE داخل تصميم الجدول نفسه.
  • أضف فهارس (Indexes) على الأعمدة التي تُستخدم بكثرة في شروط WHERE أو JOIN أو ORDER BY.
  • اختر أطوالاً مناسبة لأعمدة النصوص المفهرسة (مثل VARCHAR(190) للبريد الإلكتروني) للحفاظ على خفة الفهرس في الذاكرة.

يفرض عمود email عدم التكرار مباشرة عبر محرك قاعدة البيانات، ويفهرس idx_users_role عمود الصلاحية لتسريع التصفية.

مخطط تدفق التنفيذ العملي لقسم إضافة قيود عدم التكرار والفهارس في لغة PHP
PHP
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    email VARCHAR(190) NOT NULL UNIQUE,
    role VARCHAR(30) NOT NULL DEFAULT "member"
)');
$pdo->exec('CREATE INDEX idx_users_role ON users (role)');
echo "Users table + UNIQUE email + role INDEX ready\n";

تربط المفاتيح الأجنبية (FOREIGN KEY) السجلات الفرعية مثل الطلبات بسجل الأب في جدول المستخدمين، وتتطلب محرك التخزين InnoDB في MySQL.

  • يجب أن يطابق عمود المفتاح الأجنبي (user_id) نوع وإشارة المفتاح الأساسي الأب تماماً (مثل BIGINT UNSIGNED في كليهما).
  • استخدم ON DELETE CASCADE لحذف السجلات الفرعية تلقائياً مع الأب، أو ON DELETE RESTRICT لمنع حذف أب يمتلك سجلات مرتبطة.
  • ألحق دائماً ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci بنهاية جمل CREATE TABLE في MySQL.

تعريف المفتاح الأجنبي FOREIGN KEY (dept_id) REFERENCES depts(id) يمنع وجود موظفين مرتبطين بقسم غير موجود ويحفظ التكامل المرجعي.

PHP
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('PRAGMA foreign_keys = ON');
$pdo->exec('CREATE TABLE depts (id INTEGER PRIMARY KEY, name TEXT)');
$pdo->exec('CREATE TABLE staff (
    id INTEGER PRIMARY KEY,
    dept_id INTEGER NOT NULL,
    FOREIGN KEY (dept_id) REFERENCES depts(id) ON DELETE CASCADE
)');
echo "Foreign key constraint active\n";

اختيار نوع عمود SQL المناسب يضمن كفاءة التخزين على القرص ومطابقة الأنواع بدقة عند جلب الصفوف إلى PHP 8.4.

  • عطّل المحاكاة (PDO::ATTR_EMULATE_PREPARES => false) لكي تُرجع قاعدة البيانات أعمدة الأعداد الصحيحة كنوع int حقيقي في PHP.
  • انتبه إلى أن أعمدة DECIMAL(10, 2) تُرجع عمداً كنص string (مثل "249.50") للحفاظ على الدقة العشرية المالية دون فقدان.
  • لا تنفذ أوامر الهيكلة بمدخلات الزوار أبداً؛ بل شغّل ملفات التهجير عبر سطر الأوامر (CLI).

مع تفعيل الأنواع الأصلية، يعود عمود INTEGER مباشرة كعدد صحيح integer داخل PHP.

نوع عمود SQLأفضل استخدامنوع القيمة في PHPنصيحة التصميم
BIGINT UNSIGNEDPrimary & Foreign Key IDsint (on 64-bit PHP)Match signedness on FKs
VARCHAR(190) / TEXTEmails, slugs / Article bodystringAdd UNIQUE on emails/slugs
DECIMAL(10, 2)Money, prices, tax ratesstring (exact precision)Never use FLOAT for money
TINYINT(1) / TIMESTAMPBoolean flags / Audit timesint (0/1) / stringUse DEFAULT CURRENT_TIMESTAMP

PHP
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE metrics (id INTEGER PRIMARY KEY, hits INTEGER NOT NULL)');
$pdo->exec('INSERT INTO metrics (hits) VALUES (42)');
$row = $pdo->query('SELECT id, hits FROM metrics')->fetch(PDO::FETCH_ASSOC);
echo gettype($row['hits']) . ":" . $row['hits'] . "\n";
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

اختيار نوع عمود SQL المناسب يضمن كفاءة التخزين على القرص ومطابقة الأنواع بدقة عند جلب الصفوف إلى PHP 8.4. عطّل المحاكاة (PDO::ATTR_EMULATE_PREPARES => false) لكي تُرجع قاعدة البيانات أعمدة الأعداد الصحيحة كنوع int حقيقي في PHP. انتبه إلى أن أعمدة DECIMAL(10, 2) تُرجع عمداً كنص string (مثل "249.50") للحفاظ على الدقة العشرية المالية دون فقدان. لا تنفذ أوامر الهيكلة بمدخلات الزوار أبداً؛ بل شغّل ملفات التهجير عبر سطر الأوامر (CLI).

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 PDO Create Tables إنشاء الجداول بـ PDO
نفّذ أوامر بناء الهيكلة DDL بأمان في PHP 8 عبر PDO::exec لإنشاء قواعد البيانات وجداول UTF8MB4 والمفاتيح الأساسية والفهارس.
للمراجعة
02 Running DDL Statements with PDO exec تنفيذ أوامر الهيكلة عبر PDO::exec
المفهوم الأساسي لقسم تنفيذ أوامر الهيكلة عبر PDO::exec في لغة PHP الحديثة.
للمراجعة
03 Creating a UTF8MB4 Database in PDO إنشاء قاعدة بيانات بترميز UTF8MB4
الصياغة البرمجية والتطبيق العملي المباشر لقسم إنشاء قاعدة بيانات بترميز UTF8MB4.
للمراجعة
04 Creating Tables with Primary Keys إنشاء الجداول والمفاتيح الأساسية التلقائية
قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم إنشاء الجداول والمفاتيح الأساسية التلقائية.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 PHP PHP
PHP: Hypertext Preprocessor
لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
للمراجعة
02 CLI CLI
Command-Line Interface
واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
للمراجعة
03 FPM FPM
FastCGI Process Manager
مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
للمراجعة
04 HTML HTML
HyperText Markup Language
لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم تنفيذ أوامر الهيكلة عبر PDO::exec للتحقق من المخرجات.

  2. بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم إنشاء قاعدة بيانات بترميز UTF8MB4 وقارن مخرجات التنفيذ.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

8أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي8 أسئلة تنتظرك
01

ما دالة PDO المخصصة لتنفيذ أوامر الهيكلة (DDL) مثل CREATE TABLE التي لا تُرجع صفوف نتائج؟

تنفذ الدالة $pdo->exec($sql) الأمر مباشرة وتُرجع عدد الصفوف المتأثرة (0 لأوامر الهيكلة).

02

ما الترميز والمقارنة القياسية الواجب تحديدهما عند إنشاء قاعدة بيانات MySQL لدعم العربية والرموز ذات الـ 4 بايتات بالكامل؟

يدعم utf8mb4 محارف UTF-8 الكاملة ذات الـ 4 بايتات.

03

ما نوع عمود SQL الذي يجب استخدامه لتخزين أسعار المنتجات والأرصدة المالية بدقة؟

يخزن DECIMAL الأرقام العشرية بدقة تامة دون أخطاء التقريب الثنائي.

04

ما محرك التخزين المطلوب في MySQL لدعم المفاتيح الأجنبية (FOREIGN KEY) والمعاملات (Transactions)؟

يدعم محرك InnoDB المفاتيح الأجنبية والمعاملات وقفل الصفوف.

05

لماذا يجب فرض قيد UNIQUE (مثل البريد الإلكتروني) داخل جدول قاعدة البيانات نفسه وليس الاكتفاء بفحصه في كود PHP؟

فهرس UNIQUE في قاعدة البيانات هو الضمان الذري الوحيد لمنع التكرار تحت الضغط المتزامن.

06

ماذا يفعل الخيار ON DELETE CASCADE عند إضافته لتعريف المفتاح الأجنبي FOREIGN KEY (user_id) REFERENCES users(id)؟

يقوم CASCADE بحذف السجلات التابعة تلقائياً للحفاظ على التكامل المرجعي.

07

لماذا يُرجع PDO أعمدة DECIMAL(10, 2) كنصوص string في PHP (مثل "149.95") حتى عند تعطيل المحاكاة؟

الاحتفاظ بها كنص يحمي الأرقام المالية الدقيقة من أخطاء الفاصلة العائمة.

08

ما فائدة إضافة العبارة IF NOT EXISTS في الأمر CREATE TABLE IF NOT EXISTS users (...)؟

تتخطى إنشاء الجدول بسلام إذا كان موجوداً بالفعل دون إيقاف السكريبت.