تصميم موقع الويب الخاص بك مع PHP و MySQL


الدرس: قراءة البيانات


الصفحة السابقة
في هذا الفصل ، نعود إلى صفحات PHP الخاصة بنا. من الآن فصاعدًا ، سوف نتعلم كيفية التواصل مع قاعدة بيانات عبر PHP . ستكون هذه فرصة لاكتشاف لغة SQL ، والتي سنقوم بدراستها خلال الفصول التالية.
سنقوم هنا بممارسة قراءة البيانات من جدول. يُنصح بشدة بمعالجة phpMyAdmin مسبقًا قليلًا: ستتيح لك هذه الأداة التحقق مما إذا كانت عمليات المُعالجات التي تقوم بها في PHP لها التأثير الذي تتوقعه في قاعدة البيانات الخاصة بك.

الاتصال بقاعدة البيانات في PHP


لتكون قادرًا على العمل مع قاعدة البيانات في PHP ، يجب عليك أولاً الاتصال به.
سنتعلم في هذا الفصل قراءة البيانات في قاعدة بيانات (Database). ومع ذلك ، أذكرك بأن PHP يجب أن يكون وسيطًا بينك وبين MySQL . المشكلة: لا يمكن لـ PHP إخبار MySQL منذ البداية "احصل على هذه القيم" . في الواقع ، يطلب MySQL أولاً اسم مستخدم وكلمة مرور. إذا لم تفعل ذلك ، يمكن للجميع الوصول إلى قاعدة البيانات الخاصة بك وقراءة المعلومات (سرية في بعض الأحيان!) تحتويها.
لذلك سيكون من الضروري لمصادقة PHP : نقول إنها تنشئ اتصالًا بـ MySQL . بمجرد إنشاء الاتصال ، يمكنك القيام بجميع العمليات التي تريدها في قاعدة البيانات الخاصة بك!
كيف يمكنك الاتصال بقاعدة البيانات في PHP؟
سؤال جيد ! في الواقع ، يوفر PHP عدة طرق للاتصال بقاعدة بيانات MySQL .
  • الامتداد mysql_  : هذه هي الوظائف التي تسمح بالوصول إلى قاعدة بيانات MySQL وبالتالي للتواصل مع MySQL . اسمائهم دائما تبدأ بـ  mysql_ . ومع ذلك ، فإن هذه الوظائف قديمة ويوصى بعدم استخدامها اليوم.
  • التمديد mysqli_  : هذه وظائف محسّنة للوصول إلى MySQL . أنها توفر المزيد من الميزات وأكثر محدثة.
  • امتداد PDO : أداة كاملة تتيح الوصول إلى أي نوع من قواعد البيانات. لذلك يمكننا استخدامه للاتصال بـ MySQL وكذلك PostgreSQL أو Oracle .
هذه كلها امتدادات لأن PHP معيارية للغاية. يمكنك بسهولة إضافة عناصر أو إزالتها إلى PHP ، لأنه ليس كل شخص يحتاج بالضرورة إلى جميع الميزات.
وهو ما يعني أن تختار من بين كل هذه؟
كما ترون ، فإن الوظائف mysql_ لم تعد تستخدم (يقال إنها "قديمة") . يبقى أن تختار بين mysqli_ و PDO . سنستخدم PDO هنا لأن هذه الطريقة للوصول إلى قواعد البيانات هي الأكثر استخدامًا في الإصدارات المستقبلية من PHP . من ناحية أخرى ، تتمثل الميزة الكبيرة لشركة PDO في أنه يمكنك استخدامها بنفس الطريقة للاتصال بأي نوع آخر من قواعد البيانات ( PostgreSQL ، Oracle ...) الشكل التالي .
web dynamique php
تسمح لك PDO بالاتصال بأي نوع من قواعد البيانات
يمكنك بالتالي إعادة استخدام ما ستتعلمه إذا اخترت استخدام قاعدة بيانات أخرى غير MySQL .
تنشيط PDO
يتم تمكين PDO عادةً بشكل تلقائي. للتحقق من ذلك (انظر الشكل التالي) ، انقر بزر الماوس الأيسر على أيقونة WAMP في شريط المهام ، ثم انتقل إلى القائمة PHP / Extensions PHP وتحقق من php_pdo_mysql تحديده.
web dynamique php
تأكد من تمكين امتداد PDO
ماذا لو لم أستخدم WAMP؟
يمكنك فتح ملف إعدادات PHP ( الذي يسمى عادة php.ini ) . إذا كنت تستخدم MAMP على Mac ، فيمكنك العثور عليها في:
/Applications/MAMP/conf/PHP5XXX/php.ini
... PHP5XXX هو رقم إصدار PHP الذي تستخدمه ، على الأرجح آخر رقم. يمكنك العثور على إصدار PHP الذي تستخدمه في قسم " Preferences " في MAMP ، علامة التبويب "PHP" .
في php.ini ، ابحث عن السطر الذي يحتوي على pdo_mysql ( كما في السطر 3 في المثال أدناه) . أزل الفاصلة المنقوطة في المقدمة إذا كان هناك واحد لتنشيط الامتداد:

;extension=php_pdo_firebird.dll
;extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
أوصي بأنه طالما أنت موجود ، لتمرير display_errors إلى "on" حتى تظهر الأخطاء ، فهذا سيساعدنا إلى حد كبير:

display_errors = On
إذا كنت تستخدم نظام Linux وتستخدم XAMPP ، فابحث عن السطر الذي يبدأ بـ pdo_mysql.default_socket واستكمله كما يلي:

pdo_mysql.default_socket = /opt/lampp/var/mysql/mysql.sock
احفظ الملف وأعد تشغيل PHP . للقيام بذلك ، ما عليك سوى إعادة تشغيل برنامجك المفضل ( WAMP ، MAMP ، XAMPP ، وما إلى ذلك) .
الاتصال بـ MySQL مع PDO
الآن بعد التأكد من تمكين PDO ، يمكننا الاتصال بـ MySQL . سنحتاج إلى أربعة أجزاء من المعلومات:
  • اسم المضيف  : هذا هو عنوان الكمبيوتر حيث تم تثبيت MySQL (مثل عنوان IP ) . في أغلب الأحيان ، يتم تثبيت MySQL على نفس الكمبيوتر مثل PHP : في هذه الحالة ، ضع القيمة localhost (تعني "على نفس الكمبيوتر" ) . ومع ذلك ، من الممكن أن يشير مضيف الويب الخاص بك إلى قيمة أخرى لإدخالها (والتي قد تبدو هكذا : sql.hebergeur.com) . في هذه الحالة ، ستحتاج إلى تغيير هذه القيمة عند إرسال موقعك إلى الويب ؛
  • قاعدة البيانات  : هذا هو اسم قاعدة البيانات التي تريد الاتصال بها. في حالتنا ، تسمى القاعدة   test  . لقد أنشأناها مع phpMyAdmin في الفصل السابق ؛
  • تسجيل الدخول  : إنه يحددك. اسأل مضيفك لمعرفة ذلك. في معظم الأحيان (مع مضيف مجاني) ، يكون تسجيل الدخول نفسه الذي تستخدمه لبروتوكول نقل الملفات ؛
  • كلمة المرور  : من المحتمل أن تكون كلمة المرور هي نفس كلمة المرور التي تستخدمها للوصول إلى FTP . تحقق مع المضيف الخاص بك.
في الوقت الحالي ، نجري اختبارات على الكمبيوتر المنزلي لدينا. يقولون أننا نعمل "محليا" . لذلك ، سيكون اسم المضيف localhost .
بالنسبة لتسجيل الدخول وكلمة المرور ، يكون تسجيل الدخول تلقائيا root ولا توجد كلمة مرور.
فيما يلي كيفية الاتصال بـ MySQL عبر PDO على الأساس test  :

<?php
// WAMP (Windows)
$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');

// MAMP (Mac)
$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
?>
لا أفهم شيئًا حول هذا الرمز ، هل هذا طبيعي؟
نعم ، يجب الاعتراف بأنه يحتوي على بعض الميزات الجديدة. في الواقع ، PDO هو ما يسمى امتداد  الموجه للكائنات . (object oriented extension)إنها طريقة للبرمجة تختلف قليلاً عن الوظائف الكلاسيكية التي تعلمنا استخدامها حتى الآن.
سيكون لدينا الفرصة لمعرفة المزيد عن البرمجة الموجهة للكائنات (OOP) في وقت لاحق من الدورة. في الوقت الحالي ، أدعوك إلى إعادة استخدام الرموز التي أقدمها باتباع أمثلتي. سوف تفهم تفاصيل كيفية عملها بعد ذلك بقليل.
سطر التعليمات البرمجية الذي رأيناه للتو يخلق ما يسمى كائن $bdd  . إنه ليس متغيرًا بالفعل (حتى لو كان يشبهه بشدة): إنه كائن يمثل الاتصال بقاعدة البيانات. يتم إنشاء الاتصال عن طريق الإشارة بالترتيب في المُدخلات:
  • اسم المضيف ( localhost) ؛
  • قاعدة البيانات ( test) ؛
  • تسجيل الدخول ( root) ؛
  • كلمة المرور (تحت WAMP لا توجد كلمة مرور ، لذلك وضعت سلسلة فارغة ، تحت MAMP كلمة المرور هي root ) .
عندما يكون موقعك متصلاً بالإنترنت ، سيكون لديك بالتأكيد اسم مضيف مختلف بالإضافة إلى تسجيل الدخول وكلمة المرور مثل هذا:

<?php
$bdd = new PDO('mysql:host=sql.hebergeur.com;dbname=mabase;charset=utf8', 'pierre.durand', 's3cr3t');
?>
لذلك يتعين عليك التفكير في تغيير هذا السطر لتكييفه مع مضيفك عن طريق تعديل المعلومات وفقًا لذلك عند إرسال موقعك إلى الويب.
المُدخل الأول الذي يبدأ بـ Mysql يسمى  (DSN: D ata S ource N ame ) . هو عموما الوحيد الذي يتغير تبعا لنوع قاعدة البيانات التي نتصل بها.
اختبار للأخطاء
إذا أدخلت المعلومات الصحيحة (اسم المضيف والقاعدة وتسجيل الدخول وكلمة المرور) ، فلن يظهر شيء على الشاشة. ومع ذلك ، إذا كان هناك خطأ (على سبيل المثال ، كلمة مرور خاطئة أو اسم قاعدة البيانات) ، فقد يعرض PHP السطر بالكامل مما تسبب في الخطأ ، والذي يتضمن كلمة المرور أيضا!
لن ترغب في أن يتمكن الزائرون من رؤية كلمة المرور إذا حدث خطأ أثناء اتصالك بالإنترنت. من الأفضل التعامل مع الخطأ. في حالة حدوث خطأ ، تقوم PDO بإرجاع ما يسمى بالاستثناء (exception) والذي يسمح "بالتقاط" الخطأ. إليك كيف أقترح عليك للقيام بذلك:

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch (Exception $e)
{
        die('Erreur : ' . $e->getMessage());
}
?>
هنا هو كود آخر جديد قليلا بالنسبة لنا. مرة أخرى ، دون الخوض في الكثير من التفاصيل ، يجب أن تدرك أن PHP يحاول تنفيذ التعليمات داخل الكتلة try . إذا كان هناك خطأ ، فإنه يدخل الكتلة catch  ويفعل ما هو مطلوب (هنا ، نوقف تنفيذ الصفحة عن طريق عرض رسالة تصف الخطأ).
على العكس من ذلك ، فإن PHP يواصل تنفيذ التعليمات البرمجية ولا يقرأ ما هو موجود في الكتلة catch . لذلك يجب ألا تعرض صفحة PHP أي شيء في الوقت الحالي.
اوه هناك! كل هذا يبدو معقدًا جدًا ، لا أفهم الكثير منه! هل هو خطير يا دكتور؟
لا ، ليس على الإطلاق! في الحقيقة ، وأنا أصر على ذلك ، فإن PDO تجعلنا نستخدم وظائف PHP التي لم ندرسها حتى الآن (البرمجة الموجهة للكائنات ، الاستثناءات ...). في الوقت الحالي ، ما عليك سوى إعادة استخدام الاكواد التي أقدمها لك ولا تقلق: سنعود إلى هذه الاكواد لاحقًا لشرحها بالتفصيل.
إذا كان لديك صفحة فارغة ، يمكنك المتابعة. إذا كان لديك خطأ ، فاقرأ الرسالة وحاول فهم معنى ذلك. إذا كنت عالقًا ، فلا تتردد في طلب المساعدة في المنتديات  ، وإلا فلن تتمكن من الذهاب إلى أبعد من ذلك.

استعادة البيانات


في البداية ، سوف نتعلم كيفية قراءة المعلومات في قاعدة البيانات ، ثم سنرى في الفصل التالي كيفية إضافة وتعديل البيانات.
للعمل هنا ، نحتاج إلى قاعدة بيانات "جاهزة" تعمل كدعم. أدعوك لتنزيل الجدول الذي أنشأته من أجلك:
بالاسم فقط ، يمكنك أن تتخيل أن هذا الجدول يحتوي على شيء متعلق بألعاب الفيديو. في الحقيقة ، كما سترى ، يحتوي هذا الجدول على قائمة تضم حوالي خمسين لعبة.
في هذا المثال ، أراد العديد من الأصدقاء سرد جميع ألعاب الفيديو التي يمتلكونها. قاعدة البيانات هي طريقة عملية للغاية بالنسبة لهم لتصنيف وتنظيم كل هذا ؛ سترى السبب.
أه ، ماذا أفعل بهذا الملف  jeux_video.sql ؟
لا حاجة لمحاولة فتحه ، ليس له أهمية. يجب استيراده عبر علامة التبويب "استيراد Import" من phpMyAdmin . لقد تعلمنا القيام بذلك في الفصل السابق. تذكر أن تختار قاعدة البيانات الخاصة بك  test  مسبقا.
ها أنت ذا! يجب أن ترى جدولًا جديدًا يظهر على اليسار :  jeux_video  (الشكل التالي). يمكنك الاستمتاع بالاطلاع على ما يحتوي عليه ، للحصول على فكرة.
web dynamique php
يظهر الجدول jeux_video الآن في phpMyAdmin
فيما يلي الإدخالات الخمسة الأولى التي يحتوي عليها (هناك خمسون في الكل!):
ID nom possesseur console prix nbre_joueurs_max commentaires
1 Super Mario Bros Florent NES 4 1 Un jeu d'anthologie !
2 Sonic Patrick Megadrive 2 1Pour moi, le meilleur jeu au monde !
3 Zelda : ocarina of time Florent Nintendo 64 15 1Un jeu grand, beau et complet comme on en voit rarement de nos jours
4 Mario Kart 64 Florent Nintendo 64 25 4 Un excellent jeu de kart !
5 Super Smash Bros Melee Michel GameCube 55 4 Un jeu de baston délirant !
في الوقت الحالي ، لا تقم بتعديل هذا الجدول. هدفنا هو إنشاء صفحة PHP تعرض ما يحتويه الجدول  jeux_video .
تقديم طلب
الآن تأتي اللحظة الكبيرة التي كنا ننتظرها جميعًا: سنتحدث إلى MySQL . لذلك دعونا نبدأ الحديث بـ SQL !  للقيام بذلك ، سنفعل ما يسمى طلب (request) . سوف نطلب من MySQL بأدب إخبارنا بكل شيء في الجدول  jeux_video .
لاسترداد المعلومات من قاعدة البيانات ، نحتاج إلى كائننا الذي يمثل الاتصال بقاعدة البيانات. تتذكر ، هذا هو  $bdd . سنقوم بإجراء الاستعلام مثل هذا:

$reponse = $bdd->query('Tapez votre requête SQL ici');
لذلك يطلب منا إجراء استعلام في قاعدة البيانات.
الاستعلام باللغة الإنجليزية يعني Request" ".
نستعيد ما أرسلته قاعدة البيانات إلينا في كائن آخر أطلقنا عليه هنا $reponse .
استعلام SQL الأول
كما قلت لك ، لغة SQL   هي التي تسمح لنا بالتواصل مع MySQL .
هنا هو أول استعلام SQL سوف نستخدمه:

SELECT * FROM jeux_video
هذا يمكن ترجمته كـ: "خذ كل شيء في الجدول jeux_video  " .
دعنا نحلل كل مصطلح من هذا الاستعلام.
  • SELECT   : في لغة SQL ، تشير الكلمة الأولى إلى نوع العملية التي يجب أن يقوم بها MySQL . في هذا الفصل ، سوف نرى فقط SELECT . تطلب هذه الكلمة الأساسية من MySQL عرض ما يحتوي عليه الجدول.
  • *   : بعد SELECT، يجب الإشارة إلى حقول MySQL التي يجب استردادها من الجدول. إذا كنت مهتمًا فقط بحقل "الاسم" و "المالك" ، فسيتعين عليك كتابة:
    
    SELECT nom, possesseur FROM jeux_video
    
    إذا كنت تريد أن تأخذ جميع الحقول ، فضع * . يمكن ترجمة هذا النجم الصغير كـ "كل شيء": "خذ كل شيء هناك ...".
  • From  : إنها كلمة متصلة تترجم كـ "من " . FROMيجعل الاتصال بين اسم الحقول واسم الجدول.
  • jeux_video : هذا هو اسم الجدول الذي يجب أن تبحث فيه.
فلنقدم الطلب بالطريقة التي اكتشفناها للتو:

<?php
$reponse = $bdd->query('SELECT * FROM jeux_video');
?>
يحتوي$reponse الآن على استجابة من MySQL .
عرض نتيجة الاستعلام
المشكلة هي أنه  $reponse يحتوي على شيء غير قابل للاستخدام. يقوم MySQL بإرجاع الكثير من المعلومات إلينا والتي تحتاج إلى تنظيم.
هل يمكنك تخيل كل المعلومات الموجودة هناك؟ إذا كان جدولًا يحتوي على 10 حقول ، مع 200 إدخال ، فإن هذا يمثل أكثر من 2000 معلومة! حتى لا نتعامل مع كل شيء في وقت واحد ، فإننا نأخذ الاستجابة هذه سطراً بسطر ، أي الإدخالا بإدخال.
لاسترداد إدخال ، نأخذ استجابة من MySQL وننفذها fetch() ، والتي تُرجع السطر الأول.

<?php
$donnees = $reponse->fetch();
?>
fetch باللغة الإنجليزية يعني "اذهب وابحث " .
$donnees  هو صفيف يحتوي على قيم حقل الإدخال الأول حسب الحقل. على سبيل المثال ، إذا كنت مهتمًا بالمجال   console ، فستستخدم الصفيف  $donnees['console'] .
عليك إنشاء حلقة من خلال الإدخالات واحدا تلو الآخر. في كل مرة تتصل  $reponse->fetch()، تذهب إلى الإدخال التالي. وبالتالي يتم تكرار الحلقة عدة مرات حيث توجد إدخالات في الجدول الخاص بك.
اه! هذا كثير من المعلومات في وقت واحد. أقترح عليك تلخيص كل ما تعلمناه للتو ، من الاتصال عبر PDO إلى عرض نتيجة الاستعلام:

<?php
try
{
    //  MySQL الاتصال بـ 
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
    // في حالة الخطأ ، نعرض رسالة ونوقف كل شيء
        die('Erreur : '.$e->getMessage());
}

// إذا سارت الأمور على ما يرام ، يمكننا الاستمرار

// jeux_video نحصل على جميع محتويات الجدول 
$reponse = $bdd->query('SELECT * FROM jeux_video');

// نعرض كل ادخال واحدا تلو الآخر
while ($donnees = $reponse->fetch())
{
?>
    <p>
    <strong>Jeu</strong> : <?php echo $donnees['nom']; ?><br />
    صاحب هذه اللعبة هو: <?php echo $donnees['possesseur']; ?>, ويبيعها بـ <?php echo $donnees['prix']; ?> دولار !<br />
    هذه اللعبة تعمل على <?php echo $donnees['console']; ?> ويمكننا تشغيلها <?php echo $donnees['nbre_joueurs_max']; ?> إلى الحد الأقصى <br />
    <?php echo $donnees['possesseur']; ?> ترك هذه التعليقات على <?php echo $donnees['nom']; ?> : <em><?php echo $donnees['commentaires']; ?></em>
   </p>
<?php
}

$reponse->closeCursor(); // الانتهاء من معالجة الطلب
?>
web dynamique php
عرض نتيجة الاستعلام
لذلك ، هل رأيت؟
يجعلها مجموعة من النصوص! يجب أن يقال إن الجدول الذي أعطيته يتضمن حوالي خمسين إدخالًا ، لذلك من الطبيعي أن يكون لديك الكثير من النتائج.
بشكل ملموس ، ماذا يحدث؟ نحن حلقة لكل إدخال في الجدول. نبدأ الإدخال رقم 1 ، ثم الإدخال رقم 2 ، إلخ. في كل مرة نصنع حلقة جديدة ، نراجع إدخالًا آخر.
ما هو الفرق بين $reponseو$donnees ?
$reponse احتوى على كل استجابة MySQL بكميات كبيرة ، ككائن.
$donnees هو مجموعة عادت بفضلfetch() . في كل مرة تقوم فيها بالحلقة ، fetch تنتقل إلى  $reponse و تأخذ الإدخال التالي وتقوم بتنظيم الحقول في الصفيف $donnees .
أنا لا أفهم خط while ($donnees = $reponse->fetch())...
في الواقع ، إنها غريبة بعض الشيء وجديدة بالنسبة لك. هذا الخط يقوم بأمرين في آن واحد:
  • يسترد إدخال جديد ويضع محتواه في $donnees ؛
  • يتحقق ما إذا كان $donneesصحيحًا أم خطأ.
و fetch ترجعُ ( false) في $donneesحين تصل إلى نهاية البيانات، وهذا يعني أن كل الادخالات تم استعراضها .  في هذه الحالة ، شرط القيمة whileغير صحيح وتتوقف الحلقة.
ستلاحظ في النهاية وجود السطر:

<?php
$reponse->closeCursor(); 
?>
يؤدي "إغلاق مؤشر تحليل النتائج" . هذا يُعني ، بمعنى آخر ، أنه يتعين عليك تنفيذ closeCursor() كل مرة تنتهي فيها من معالجة طلب الإرجاع ، لتجنب مشاكل في الطلب التالي. هذا يعني أنه قد تم الانتهاء من العمل على الطلب.
إظهار محتوى بعض الحقول فقط
مع ما قمت بتدريسه ، يجب أن تكون قادرًا على عرض ما تريد.
لا أحد يجبرك على عرض جميع الحقول! على سبيل المثال ، إذا أردت فقط سرد أسماء الألعاب ، كنت سأستخدم استعلام SQL التالي:

SELECT nom FROM jeux_video
لنأخذ الكود الكامل السابق ونعدله لعرض اسم لعبة في كل سطر:

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
        die('Erreur : '.$e->getMessage());
}

$reponse = $bdd->query('SELECT nom FROM jeux_video');

while ($donnees = $reponse->fetch())
{
    echo $donnees['nom'] . '
'; } $reponse->closeCursor(); ?>
web dynamique php
عرض اسم لعبة واحدة في كل سطر
هذا الرمز مشابه جدًا للرمز السابق ، ولكن هذه فرصة بالنسبة لك للتعرف على MySQL و PDO . على وجه الخصوص ، تذكر ما يلي:
  • يجب إجراء اتصال قاعدة البيانات مرة واحدة فقط ، في بداية الصفحة ؛
  • يجب عليك إغلاق نتائج البحث closeCursor() بعد معالجة كل طلب.

معايير الاختيار


تخيل أنني أريد فقط الحصول على قائمة الألعاب المتاحة من وحدة التحكم "Nintendo 64" وفرزها عن طريق زيادة السعر. هل يبدو الأمر معقدًا؟ ليس في SQL !
سترى أنه من خلال تعديل استعلامات SQL الخاصة بنا ، من الممكن تصفية بياناتك وفرزها بسهولة بالغة. سنركز هنا على الكلمات الأساسية التالية في لغة SQL :
  • WHERE  .
  • ORDER BY  .
  • LIMIT .
WHERE
بفضل الكلمة الرئيسية WHERE، ستتمكن من فرز بياناتك.
لنفترض على سبيل المثال أنني أريد فقط سرد الألعاب الخاصة بـ Patrick . سيكون الطلب في البداية هو نفسه كما كان من قبل ، لكنني سأضيفه في النهاية WHERE possesseur='Patrick' .
هذا يعطينا الطلب:

SELECT * FROM jeux_video WHERE possesseur='Patrick'
الترجمة: "  حدد جميع الحقول في جدول jeux_video عندما يكون حقل المالك مساوًا لـ Patrick   " .
ستلاحظ أنه لتحديد سلاسل الأحرف ، يجب وضعها بين الفواصل العليا ، كما هو الحال هنا 'Patrick' . ومع ذلك ، فهي ليست ضرورية للأرقام.
رمز صغير لرؤية ما يبدو؟

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
        die('Erreur : '.$e->getMessage());
}

$reponse = $bdd->query('SELECT nom, possesseur FROM jeux_video WHERE possesseur=\'Patrick\'');

while ($donnees = $reponse->fetch())
{
    echo $donnees['nom'] . ' appartient à ' . $donnees['possesseur'] . '
'; } $reponse->closeCursor(); ?>
web dynamique php
قائمة الألعاب التي تنتمي إلى باتريك
إذا كان لديك متعة في تغيير اسم المالك (  WHERE possesseur='Michel'على سبيل المثال ) ، فلن يعرض سوى الألعاب التي تنتمي إلى ميشيل.  جربه ، سترى!
من الممكن أيضًا الجمع بين عدة شروط. على سبيل المثال ، إذا أردت سرد ألعاب Patrick التي يبيعها بأقل من 20 دولار ، فسوف أقوم بدمج معايير الاختيار باستخدام الكلمة الأساسية AND (والتي تعني " و " ) :

SELECT * FROM jeux_video WHERE possesseur='Patrick' AND prix < 20
الترجمة: "  حدد جميع حقول jeux_video عندما يكون المالك هو Patrick AND عندما يكون السعر أقل من 20  " .
هناك أيضًا الكلمة الأساسية OR التي تعني "أو" .
ORDER BY
ORDER BY يسمح لنا أن ننظم نتائجنا. يمكننا تصنيف النتائج وفقًا لسعرها ! سيكون استعلام SQL :

SELECT * FROM jeux_video ORDER BY prix
الترجمة: "  حدد جميع مجالات jeux_video وتنظيم النتائج حسب الأسعار  ".
التطبيق:

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
        die('Erreur : '.$e->getMessage());
}

$reponse = $bdd->query('SELECT nom, prix FROM jeux_video ORDER BY prix');

while ($donnees = $reponse->fetch())
{
    echo $donnees['nom'] . ' coûte ' . $donnees['prix'] . ' EUR
'; } $reponse->closeCursor(); ?>
web dynamique php
حدد جميع مجالات jeux_video ونظّم النتائج حسب الأسعار
ماذا لو أردت الفرز بترتيب تنازلي؟
سهلة. فقط أضف الكلمة الرئيسية DESCفي النهاية:

SELECT * FROM jeux_video ORDER BY prix DESC
الترجمة: "  حدد جميع مجالات jeux_video ، ونظّم النتائج حسب الأسعار بترتيب تنازلي  ".
ملاحظة: إذا استخدمنا ORDER BY في حقل يحتوي على نص ، فسيتم التصنيف حسب الترتيب الأبجدي.
LIMIT
LIMIT يسمح لنا بتحديد جزء فقط من النتائج (على سبيل المثال أول 20). يعد هذا مفيدًا جدًا عندما يكون هناك الكثير من النتائج وتريد ترقيمها (على سبيل المثال عرض النتائج الثلاثين الأولى في الصفحة 1 ، والنتائج الثلاثين التالية في الصفحة 2 ، إلخ).
في نهاية الاستعلام ، أضف الكلمة الأساسية LIMIT متبوعة برقمين مفصولين بفاصلة.  مثلا :

SELECT * FROM jeux_video LIMIT 0, 20
هذان الرقمان لهما معنى دقيق للغاية.
  • نشير أولاً من أي إدخال نبدأ في قراءة الجدول. هنا ، أضع "0" ، والذي يتوافق مع الإدخال الأول. يرجى ملاحظة أن هذا ليس له علاقة بحقل الهوية! تخيل أن الاستعلام يُرجع 100 نتيجة: سيتم LIMIT اقتطاعه من النتيجة الأولى إذا أشرت إلى 0 ، من 21 إذا أشرت إلى 20 ، إلخ.
  • ثم يشير الرقم الثاني إلى عدد الإدخالات المراد تحديدها. هنا ، وضعت "20" ، لذلك سوف نأخذ عشرين مشاركة.
بعض الأمثلة :
  • LIMIT 0, 20  : يعرض الإدخالات العشرين الأولى ؛
  • LIMIT 5, 10  : من المدخل السادس إلى الخامس عشر ؛
  • LIMIT 10, 2  : يعرض الإدخالات الحادية عشرة والثانية عشرة.
الرسم التخطيطي التالي يلخص عمل LIMIT .
web dynamique php
عرض لكيفية عمل LIMIT
هيا ، مثال صغير! إذا أردنا عرض أول 10 ألعاب ، فسنستخدم الكود التالي:

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
        die('Erreur : '.$e->getMessage());
}

$reponse = $bdd->query('SELECT nom FROM jeux_video LIMIT 0, 10');

echo '

Voici les 10 premières entrées de la table jeux_video :

'; while ($donnees = $reponse->fetch()) { echo $donnees['nom'] . '
'; } $reponse->closeCursor(); ?>
web dynamique php
عرض أول 10 ألعاب على الطاولة
وهذه هي المهمة!
مرحبًا ، أنا مازوشي وقبل الانتهاء من هذا القسم ، أود خلط جميع استعلامات SQL التي تعلمتها للتو في واحد. ممكن ؟
لكن بالطبع يا صغيرتي.
إليك ما تحتاج إلى التفكير فيه:

SELECT nom, possesseur, console, prix FROM jeux_video WHERE console='Xbox' OR console='PS2' ORDER BY prix DESC LIMIT 0,10
عليك استخدام الكلمات في الترتيب الذي أعطيته لك :  WHERE و  ORDER BY بعد ذلك LIMIT ، إذا لم تفعل سوف لن يفهم MySQL طلبك.
لذا حاول ترجمة هذا إلى العربية أولاً لمعرفة ما إذا كنت تفهم ، ثم اختبر هذا الاستعلام لمعرفة ما إذا كان هذا ما كنت تتوقعه.

بناء استعلامات بناء على المتغيرات


كانت الاستعلامات التي درسناها بسيطة حتى الآن وكانت تؤدي دائمًا نفس العملية. تصبح الأمور مثيرة للاهتمام عند استخدام متغيرات PHP في الاستعلامات.
الفكرة السيئة: تسلسل متغير مع استعلام
خذ هذا الطلب الذي يسترجع قائمة الألعاب الخاصة بـ Patrick:

<?php
$reponse = $bdd->query('SELECT nom FROM jeux_video WHERE possesseur=\'Patrick\'');
?>
بدلاً من عرض ألعاب Patrick دائمًا ، نود أن يكون هذا الاستعلام قادرًا على التكيف مع اسم الشخص المحدد في متغير ، على سبيل المثال $_GET['possesseur'] . وبالتالي يمكن تكييف الطلب وفقا لطلب المستخدم!
قد يتم إغراءنا بتسلسل المتغير في الاستعلام ، مثل هذا:

<?php
$reponse = $bdd->query('SELECT nom FROM jeux_video WHERE possesseur=\'' . $_GET['possesseur'] . '\'');
?>
من الضروري إحاطة سلسلة الأحرف بالفواصل العليا كما أشرت إليك سابقًا ، ومن هنا وجود خطوط مائلة للخلف لإدراج الفواصل العليا:\'
على الرغم من أن هذا الكود يعمل ، إلا أنه يمثل مثالًا نموذجيا على ما لا يجب فعله ، ومع ذلك لا يزال هناك العديد من المواقع تستعمله. في الواقع ، إذا  تم تعديل المتغير $_GET['possesseur'] بواسطة زائر (ونعرف كم يجب ألا نثق في المستخدم!) ، فهناك خطر كبير يتمثل في حدوث خرق أمني يسمى حقن SQL  . قد يستمتع الزائر بإدخال استعلام SQL في منتصف بياناتك ويحتمل أن يقرأ كل محتوى قاعدة البيانات الخاصة بك ، مثل قائمة كلمات مرور المستخدمين الخاصة بك.
موضوع حقن SQL معقد بعض الشيء ليكون مفصلا هنا. إذا كنت تريد معرفة المزيد حول هذا الموضوع ، أدعوك إلى الرجوع إلى ويكيبيديا  .
سنستخدم طريقة أكثر أمانًا لتكييف استفساراتنا وفقًا للمتغيرات: الاستعلامات المعدة.
الحل: الطلبات المعدة
يتمتع نظام الاستعلامات المعدة بميزة كونه أكثر أمانًا ولكنه أسرع أيضًا في قاعدة البيانات إذا تم تنفيذ الاستعلام عدة مرات. هذا ما أوصي باستخدامه إذا كنت تريد تكييف استعلام وفقًا لمتغير واحد أو أكثر.
مع علامات "؟ "
أولاً ، سنقوم "بإعداد" الطلب دون الجزء المتغير الخاص به ، والذي ستمثله علامة في شكل علامة استفهام:

<?php
$req = $bdd->prepare('SELECT nom FROM jeux_video WHERE possesseur = ?');
?>
بدلاً من تنفيذ الاستعلام query() مثل آخر مرة ، ندعو هنا prepare() .
الطلب جاهز ، بدون جزءه المتغير . الآن دعنا ننفذ الطلب عن طريق الاتصال execute بقائمة المُدخلات وتمريرها إليه:

<?php
$req = $bdd->prepare('SELECT nom FROM jeux_video WHERE possesseur = ?');
$req->execute(array($_GET['possesseur']));
?>
ثم يتم تنفيذ الاستعلام باستخدام المُدخلات التي تم تحديدها في شكل صفيف.
إذا كان هناك العديد من العلامات ، فيجب الإشارة إلى المُدخلات بالترتيب الصحيح:

<?php
$req = $bdd->prepare('SELECT nom FROM jeux_video WHERE possesseur = ? AND prix <= ?');
$req->execute(array($_GET['possesseur'], $_GET['prix_max']));
?>
سيتم استبدال علامة الاستفهام الأولى بالاستعلام بمحتوى المتغير $_GET['possesseur'] والثاني بمحتوى $_GET['prix_max'] . سيتم تأمين محتوى هذه المتغيرات تلقائيًا لمنع مخاطر حقن SQL .
دعونا نحاول إنشاء صفحة قادرة على إدراج الألعاب التي تخص شخصًا ولا يتجاوز سعره مبلغًا معينًا:

<?php
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
}
catch(Exception $e)
{
        die('Erreur : '.$e->getMessage());
}

$req = $bdd->prepare('SELECT nom, prix FROM jeux_video WHERE possesseur = ?  AND prix <= ? ORDER BY prix');
$req->execute(array($_GET['possesseur'], $_GET['prix_max']));

echo '
    '; while ($donnees = $req->fetch()) { echo '
  • ' . $donnees['nom'] . ' (' . $donnees['prix'] . ' EUR)
  • '; } echo '
'; $req->closeCursor(); ?>
على الرغم من أن الاستعلام "آمن" (مما يزيل مخاطر حقن SQL ) ، فسيظل من الضروري التحقق من $_GET['prix_max'] التي يجب ان تكود عددا و في فاصل صحيح. وبالتالي ، فأنت لست معفيًا من إجراء عمليات فحص إضافية إذا كنت تعتقد أن هذا ضروري.
حاول الاتصال بهذه الصفحة (والتي سنذكرها على سبيل المثال selection_jeux.php )عن طريق تعديل قيم المُدخلات. سترى أن قائمة الألعاب التي تظهر تتغير وفقًا للمعايير المرسلة!
مع علامات الاسم
إذا كان الاستعلام يحتوي على العديد من الأجزاء المتغيرة ، فقد يكون من الأكثر عملية تسمية العلامات بدلاً من استخدام علامات الاستفهام.
إليك كيف سنفعل ذلك:

<?php
$req = $bdd->prepare('SELECT nom, prix FROM jeux_video WHERE possesseur = :possesseur AND prix <= :prixmax');
$req->execute(array('possesseur' => $_GET['possesseur'], 'prixmax' => $_GET['prix_max']));
?>
وقد تم استبدال علامات استفهام من قبل علامات اسمية :possesseur و :prixmax (أنها تبدأ بنقطتين، كما ترون) .
هذه المرة ، يتم استبدال هذه العلامات بواسطة المتغيرات باستخدام مجموعة اقتران. عندما يكون هناك الكثير من المُدخلات ، يسمح هذا في بعض الأحيان بمزيد من الوضوح. بالإضافة إلى ذلك ، بخلاف علامات الاستفهام ، لم نعد ملزمين هذه المرة بإرسال المتغيرات بنفس ترتيب الاستعلام.

تعقب الأخطاء


عندما "يتعطل" استعلام SQL ، سيخبرك PHP في كثير من الأحيان أنه حدث خطأ في سطر fetch :

Fatal error: Call to a member function fetch() on a non-object in C:\wamp\www\tests\index.php on line 13
ليست محددة للغاية ، أعتقد أنك توافقني الرأي.
ليس سطر fetch هو موضوع المشكلة: غالبًا ما تكون أنت الذي كتبت استعلام SQL الخاص بك بشكل خاطئ بضعة أسطر أعلاه.
لعرض تفاصيل حول الخطأ ، يجب عليك تمكين الأخطاء عند الاتصال بقاعدة البيانات عبر PDO .
هل تتذكر هذا السطر؟

<?php
$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '');
?>
أضف مُدخلا في النهاية لتفعيل الأخطاء:

<?php
$bdd = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
?>
الآن جميع استعلامات SQL الخاصة بك التي تحتوي على أخطاء ستعرض عليها برسالة أوضح بكثير.
لنفترض ، على سبيل المثال ، أن أكتب اسم الحقل بشكل غير صحيح:

<?php
$reponse = $bdd->query('SELECT champinconnu FROM jeux_video');
?>
سيتم عرض الخطأ التالي:

Unknown column 'champinconnu' in 'field list'
إنها اللغة الإنجليزية ، بالطبع ، لكنها بالفعل أكثر دقة بكثير من الخطأ الذي ارتكبناه سابقًا. إذا ترجمنا ، فهذا يعني : "  لم يتم العثور على العمود في قائمة الحقول" . في الواقع ، لا يوجد مجال يسمى champinconnu .
عندما تكون لديك مشكلة في طلب وتريد طلب المساعدة في المنتديات ، تذكر دائمًا تنشيط الأخطاء عند الاتصال بقاعدة البيانات كما أوضحت للتو ، فهذا سيتيح لك أن يكون لديك رسالة خطأ مفصلة. تذكر ، لا يمكن لأحد مساعدتك إذا كنت تعطي الرسالة التلقائية فقط  Call to a member function fetch() on a non-object !

في الخلاصة


  • للتواصل مع MySQL من PHP ، نستخدم امتداد PDO لـ PHP .
  • قبل التفاعل مع MySQL ، يجب عليك الاتصال به. نحتاج إلى عنوان IP الخاص بالجهاز الذي يوجد به MySQL ، واسم قاعدة البيانات وكذلك تسجيل الدخول وكلمة المرور.
  • SELECT  تتيح لك استعلامات SQL التي تبدأ بـ استرداد المعلومات من قاعدة بيانات.
  • من الضروري عمل حلقة في PHP لاستعادة البيانات التي يتم إرجاعها بواسطة MySQL سطراً بسطر.
  • تقدم لغة SQL العديد من الأدوات لتحسين استفساراتنا ، وذلك باستخدام الكلمات الأساسية WHERE (عامل التصفية) و   ORDER BY (للتنظيم) و LIMIT ( لتحديد عدد النتائج ) بشكل خاص.
  • لإنشاء استعلام وفقًا لقيمة المتغير ، نذهب إلى نظام استعلام مُعد يتجنب العيوب الخطرة في حقن SQL .