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


الدرس: كتابة البيانات


الصفحة السابقة
لقد رأينا في الفصل السابق أنه يمكننا بسهولة استرجاع المعلومات من قاعدة البيانات الخاصة بنا. لقد وجدنا أيضا أن لغة SQL هي قوية جدا لأنها تقدم العديد من معايير الاختيار والفرز (  WHERE ،  ORDER BY، الخ) .
الآن هو الوقت المناسب لاكتشاف كيف يمكنك إضافة وتعديل البيانات في قاعدة البيانات. لهذا، سوف نتطرق الى كتابة استعلامات جديدة في SQL .الجديد هو معرفة ما يلي :  INSERT ، UPDATE و DELETE .

insert: إضافة البيانات


مهمتك ، إذا قبلتها: أضف إدخالًا جديدًا إلى الجدول "jeux_video" الذي عملنا عليه في الفصل السابق.
موهاها ، لكنها سهلة. يمكنك استخدام phpMyAdmin والمعزوفة! لقد تم ! ... ماذا ، قلت شيئا خاطئا؟
لا لا.
صحيح أن phpMyAdmin يسمح لك بإضافة إدخالات جديدة إلى الجدول. ولكن ما يهمنا هنا هو القيام بذلك باستخدام برنامج نصي PHP واستعلام SQL .
بادئ ذي بدء ، أذكرك بما يبدو عليه الجدول "jeux_video":
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 !
لإضافة إدخال ، ستحتاج إلى معرفة استعلام SQL . إليك واحدة على سبيل المثال تضيف لعبة:

INSERT INTO jeux_video(ID, nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES('', 'Battlefield 1942', 'Patrick', 'PC', 45, 50, '2nde guerre mondiale')
لا يلزم تضمين الأرقام (مثل 45 و 50 هنا) في علامات اقتباس مفردة. السلاسل فقط تتطلب ذلك.
دعونا نلقي نظرة على هذا الطلب.
  • أولاً ، عليك أن تبدأ بالكلمات الرئيسية INSERT INTO التي تشير إلى أنك تريد إدراج إدخال.
  • يمكنك بعد ذلك تحديد اسم الجدول ( هنا jeux_video ) ، ثم تدرج بين قوسين أسماء الحقول التي تريد وضع المعلومات فيها.
  • أخيرًا - وهذا لا يجب أن يكون مخطئًا - تقوم بالتسجيل VALUES متبوعًا بالقيم التي سيتم إدراجها بنفس الترتيب الذي أشرت إليه في الحقول التي أشرت إليها .
ستلاحظ أنه بالنسبة للحقل الأول (ID) ، تركت الفواصل العليا الفارغة. إنه مطلوب: يحتوي الحقل على ملكية auto_increment، لذلك فإن MySQL ستضع رقم المعرف نفسه. يمكننا حتى الاستغناء عن حقل الهوية في الطلب:

INSERT INTO jeux_video(nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES('Battlefield 1942', 'Patrick', 'PC', 45, 50, '2nde guerre mondiale')
الأمر أسهل! سيتم ملء حقل المعرف تلقائيًا بواسطة MySQL على أي حال ، لذلك ليست هناك حاجة لإدراجه.
أخيرًا ، إذا كنت ترغب في ذلك ، فاعلم أنك غير ملزم بإدراج أسماء الحقول أولاً ؛ يعمل هذا الاستعلام تمامًا (ولكنه أقل وضوحًا):

INSERT INTO jeux_video VALUES('', 'Battlefield 1942', 'Patrick', 'PC', 45, 50, 
'2nde guerre mondiale')
يجب أن تسرد قيم جميع الحقول دون استثناء (معرف مضمن) بالترتيب الصحيح.
التطبيق في PHP دعنا نستخدم استعلام SQL هذا داخل نص PHP . هذه المرة ، بدلاً من الاتصال query() (الذي استخدمناه في الفصل السابق لاسترداد البيانات) ، سوف نستخدم exec() الغرض منه هو تنفيذ التعديلات على قاعدة البيانات:

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

// On ajoute une entrée dans la table jeux_video
$bdd->exec('INSERT INTO jeux_video(nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES(\'Battlefield 1942\', \'Patrick\', \'PC\', 45, 50, \'2nde guerre mondiale\')');

echo لقد تمت إضافة اللعبة!';
?>
ماذا يفعل هذا الكود؟ انه يضيف مدخلاً في BDD للعبة "Battlefield 1942" ، التي تنتمي إلى "Patrick" ، والتي تعمل على "PC" ، والتي تكلف 45 دولار ، إلخ.
يجعل وجود الفواصل العليا متعددة الطلب صعوبة في القراءة والكتابة قليلاً بسبب خطوط مائلة عكسية \التي يجب إضافتها في المقدمة. بالإضافة إلى ذلك ، يقوم هذا الاستعلام دائمًا بإدراج نفس البيانات. كما رأينا في الفصل السابق ، إذا أردنا أن نجعل جزءًا من متغير الاستعلام ، فإن الطريقة الأسرع والأكثر أمانًا هي استخدام الاستعلامات المعدة.
إدراج البيانات المتغيرة بفضل استعلام معد
إذا اخترت استخدام استعلام مُعد (الذي أوصي به إذا كنت تريد إدراج متغيرات) ، فستكون العملية هي نفسها تمامًا كما في الفصل السابق:

<?php
$req = $bdd->prepare('INSERT INTO jeux_video(nom, possesseur, console, prix, nbre_joueurs_max, commentaires) VALUES(:nom, :possesseur, :console, :prix, :nbre_joueurs_max, :commentaires)');
$req->execute(array(
    'nom' => $nom,
    'possesseur' => $possesseur,
    'console' => $console,
    'prix' => $prix,
    'nbre_joueurs_max' => $nbre_joueurs_max,
    'commentaires' => $commentaires
    ));

echo لقد تمت إضافة اللعبة!';
?>
الآن لم أعد أضع خطوة الاتصال بـ MySQL مع PDO في الاكواد لتبسيطها. بالطبع ، يجب عليك دائمًا الاتصال مسبقًا إذا كنت تريد أن يعمل الطلب.
من أجل الوضوح ، لقد استخدمت علامات الأسماء هنا. كما ترون ، لقد قمتُ بإنشاء المصفوفة على عدة أسطر: مُصرح بها ، وهي أكثر قابلية للقراءة بشكل خاص.
المتغيرات مثل $nom و $possesseur يجب أن يكونا معرّفتان مسبقا. بشكل عام ، سنقوم باسترداد المتغيرات من $_POST (من نموذج) لإدراج إدخال في قاعدة البيانات. سنكتشف حالة عملية في المختبر التالي.

UPDATE: تعديل البيانات


لقد أضفت للتو "Battlefield" إلى قاعدة البيانات وكل شيء سار على ما يرام.
لكن ... أنت تدرك مع دهشتها أن "Battlefield" يتم لعبها فعليًا بـ 32 لاعبًا كحد أقصى (بدلاً من 50) وأن سعرها انخفض بالإضافة إلى ذلك: نجدها بـ 10 دولار (بدلاً من 45).
UPDATEيسمح لك الطلب بتعديل إدخال
No problemo amigo !!
باستخدام استعلام SQL صغير ، يمكننا إصلاح ذلك. في الواقع ، باستخدامك ، UPDATE ستتمكن من تعديل الإدخال الذي يطرح مشكلة:

UPDATE jeux_video SET prix = 10, nbre_joueurs_max = 32 WHERE ID = 51
كيف يعمل؟
  • بادئ ذي بدء ، UPDATE تتيح لنا الكلمة الرئيسية أن نقول أننا سنعدل إدخالًا.
  • بعد ذلك ، اسم الجدول ( jeux_video) .
  • الكلمة الأساسية SET، التي تفصل اسم الجدول من قائمة الحقول المراد تعديلها.
  • فيما يلي الحقول التي يجب تعديلها ، مفصولة بفواصل. هنا ، نقوم بتعديل حقل "Prix" ، ونخصص له القيمة 10( prix = 10)" " ، ثم نفعل الشيء نفسه بالنسبة للحقل nbre_joueurs_max .  لن يتم تعديل الحقول الأخرى.
  • أخيرًا ، الكلمة WHERE الأساسية ضرورية. يسمح لنا بإخبار MySQL عن أي إدخال يمكن تعديله (وإلا ، ستتأثر كل الإدخالات!). غالبًا ما نستخدم حقل المعرف للإشارة إلى الإدخال الذي يجب تغييره. هنا ، من المفترض أن "Battlefield" قد تم تسجيله تحت المعرف رقم 51.
إذا كنت تريد ، يمكنك استخدام اسم اللعبة بدلاً من المعرف لتحديد اختيارك:

UPDATE jeux_video SET prix = '10', nbre_joueurs_max = '32' WHERE nom = 'Battlefield 1942'
اللحظة الأخيرة ! اشترى فلورنت للتو كل ألعاب ميشيل. سيتعين علينا تغيير هذا على الفور.
أه ، هل سيتعين علينا تعديل كل إدخال واحد تلو الآخر؟
لا! لا توجد مسألة قضاء ساعات في تعديل كل إدخال واحد تلو الآخر لذلك! بالتفكير في حوالي 0.5 ثانية ، ستجد استعلام SQL الذي يسمح لك بالقيام بما تريد بمفردك.
هذا جيد ، هل وجدته؟ هيا ، سوف أعطيك الجواب:

UPDATE jeux_video SET possesseur = 'Florent' WHERE possesseur = 'Michel'
الترجمة: "  في الجدول jeux_video، قم بتعديل جميع الإدخالات التي  possesseur يساوي مجالها Michel ، واستبدله بـ Florent . "
سواء كان هناك 1 أو 10 أو 100 أو 1000 إدخال ، فهذا الاستعلام وحده كافٍ لتحديث الجدول بأكمله ! كم هي جميلة SQL ... ؛
التطبيق في PHP
بنفس الطريقة ، في PHP نستخدم exec() لإجراء تعديلات:

<?php
$bdd->exec('UPDATE jeux_video SET prix = 10, nbre_joueurs_max = 32 WHERE nom = \'Battlefield 1942\'');
?>
لاحظ أن هذه المكالمة تُرجع عدد الخطوط التي تم تغييرها. حاول استرداد هذه القيمة في متغير وعرضها ، على سبيل المثال مثل هذا:

<?php
$nb_modifs = $bdd->exec('UPDATE jeux_video SET possesseur = \'Florent\' WHERE possesseur = \'Michel\'');
echo $nb_modifs . ' entrées ont été modifiées !';
?>
سيعرض هذا شيء مثل: 13 entries have been modified!
مع طلب جاهز
إذا قمت بإدخال بيانات متغيرة ، على سبيل المثال أرسلها المستخدم ، فإنني أوصي مرة أخرى باستخدام استعلام مُعد:

<?php
$req = $bdd->prepare('UPDATE jeux_video SET prix = :nvprix, nbre_joueurs_max = :nv_nb_joueurs WHERE nom = :nom_jeu');
$req->execute(array(
    'nvprix' => $nvprix,
    'nv_nb_joueurs' => $nv_nb_joueurs,
    'nom_jeu' => $nom_jeu
    ));
?>

: حذف البيانات


وأخيرا، وهنا هو الطلب الأخير التي يمكن أن يكون مفيدا: DELETE . سريعا وسهل الاستخدام ، لكنه خطر بعض الشيء: بعد الحذف ، لا توجد وسيلة لاستعادة البيانات ، لذلك كن حذرا!
إليك كيفية حذف الإدخال من "Battlefield" على سبيل المثال:

DELETE FROM jeux_video WHERE nom='Battlefield 1942'
لا يوجد شيء أسهل:
  • FROM  : أن يقول "حذف في" ؛
  • jeux_video  : اسم الجدول ؛
  • WHERE  : ضروري للإشارة إلى أي إدخال (إدخالات) يجب حذفه.
إذا نسيت WHERE ، فسيتم حذف جميع الإدخالات. هذا يعادل تنظيف الجدول.
اسمح لك بتجربة هذا الطلب في PHP . هنا يمكنك أيضًا الدخول exec() إذا كنت تريد تنفيذ استعلام معين ، أو استخدام استعلام مُعد إذا كان استعلامك يعتمد على المتغيرات.

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


كما تعلمون ، SQL هي لغة في حد ذاتها نستخدمها في PHP . إذا كان يمكن أن يكون هناك أخطاء في PHP ، يمكن أن يكون هناك أيضا أخطاء في SQL !
على سبيل المثال ، قد يكون استعلامك مكتوبًا بشكل سيئ ، والجدول الذي تريد فتحه غير موجود ، إلخ. باختصار ، لا يزال هناك العديد من الأخطاء المحتملة.
ومع ذلك ، ليس MySQL هو الذي سيخبرك أن هناك خطأ ، ولكن PHP ، والأخير ليس ثرثارا للغاية حول أخطاء SQL . لذلك سوف نرى:
  1. 1. كيفية اكتشاف خطأ SQL في PHP ؛
  2. 2. كيف نجعل PHP يتحدث بحيث يعطينا خطأ SQL (عن طيب خاطر أو بالقوة! )
بقعة خطأ SQL في PHP
عند حدوث خطأ SQL ، تعرض الصفحة في الغالب الخطأ التالي:
Fatal error: Call to a member function fetch() on a non-object
يحدث هذا الخطأ عندما تريد عرض نتائج استعلامك ، عادةً في الحلقة
  while ($donnees = $reponse->fetch()) .
عندما يكون لديك هذا الخطأ ، لا تنظر إلى أبعد من ذلك ، فهو استعلام SQL السابق الذي لم ينجح. ومع ذلك ، أنت تفتقد تفاصيل سبب الطلب. سنرى الآن كيف يمكننا علاج هذا.
تعال!  هيا أعطنا الخطأ
من الواضح أن PHP لا يريد أن يعطينا الخطأ الذي تم إرجاعه بواسطة MySQL ، وسوف نطلب ذلك بطريقة أخرى. لقد قدمت لك هذه الطريقة أيضًا في أحد الفصول الأولى في MySQL .
حدد موقع الطلب الذي تعتقد أنه يتعطل (بالتأكيد الطلب قبل الحلقة   )، واطلب عرض الخطأ إذا كان هناك واحد ، مثل هذا:

<?php
$reponse = $bdd->query('SELECT nom FROM jeux_video') or die(print_r($bdd->errorInfo()));
?>
إذا كان الطلب يعمل ، فلن يتم عرض أي خطأ. إذا تعطل الطلب من ناحية أخرى ، فسيتوقف PHP عن إنشاء الصفحة وسيعرض الخطأ الذي قدمه MySQL ...
من هناك ، سيكون عليك أن تتصرّف لأن أخطاء SQL كثيرة جدًا ولا يمكنني سردها جميعًا.
بشكل عام ، يخبرك MySQL "لديك خطأ في بناء جملة SQL بالقرب من" XXX " . الأمر متروك لك لقراءة استعلام SQL مرة أخرى ؛ يوجد الخطأ عادة بالقرب من المكان الذي يتم إخبارك فيه.

في الخلاصة


  • نستخدم كلمات رئيسية مختلفة بناءً على نوع التعديل الذي نريد إجراؤه:
    • INSERT INTO : إضافة إدخال ؛
    • UPDATE : تعديل واحد أو أكثر من الإدخالات ؛
    • DELETE : حذف إدخال واحد أو أكثر.
  • كما هو الحال مع اختيار البيانات ، نستخدم الاستعلامات المعدة لتخصيص استفساراتنا بناءً على المتغيرات.
  • عند استخدام UPDATEأو DELETE، عليك أن تفكر في التصفية باستخدام WHERE وإلا ستتأثر العملية بأكملها!
  • يشير PHP إلى ما إذا كان قد حدث خطأ في MySQL .