MUHIM: Tayyorlangan iboralar PDO-ni ishlatishda asosiy sababdir yagona xavfsiz usul O'zgaruvchilarni o'z ichiga olgan SQL so'rovlarini bajarish.
Bundan tashqari, tayyorlash () / bajarish (() ni turli xil ma'lumotlar to'plamlari yordamida bir marta tayyorlangan so'rovni takrorlash uchun ishlatish mumkin. Amalda, bu juda kamdan-kam hollarda talab qilinadi va tezlikni oshirishga olib kelmaydi. Agar siz bir xil turdagi ko'plab so'rovlar qilishingiz kerak bo'lsa, siz quyidagicha yozishingiz mumkin:
$ ma'lumotlar \u003d massiv (
1 => 1000,
5 => 300,
9 => 200,
);
$ stmt \u003d $ pdo -\u003e tayyorlash ( "UPDATE foydalanuvchilari SET bonus \u003d bonus +? Qaerda id \u003d?");
oldindan belgilash ($ ma'lumotlar $ id \u003d\u003e $ bonus sifatida)
{
$ stmt -\u003e bajaring ([$ bonus, $ id]);
}
Bu erda biz so'rovni bir marta tayyorlaymiz va keyin ko'p marta bajaramiz.
Biz ma'lumotlar bazasidan qatorlarni ketma-ket olish uchun ishlatiladigan () usuli bilan tanishdik. Ushbu usul mysq_fetch_array () va shunga o'xshash funktsiyaning analogidir, ammo u boshqacha ishlaydi: ko'p funktsiyalar o'rniga bu erda bitta usul ishlatiladi, ammo uning harakati o'tgan parametr tomonidan o'rnatiladi. Keyinchalik ushbu parametrlar haqida tafsilotlar yoziladi va qisqacha tavsiya sifatida FETCH_LAZY rejimida yuklash () ni ishlatishingizni maslahat beraman:
$ stmt \u003d $ pdo -\u003e tayyorlash ( "E-pochtani qayerda \u003d foydalanuvchilarini TANLASH ismi \u003d?");
$ stmt -\u003e bajaring ([$ _GET ["email"]]);
while ($ row \u003d $ stmt -\u003e olish (PDO :: FETCH_LAZY))
{
echo $ string [0]. "\\ n";
echo $ string ["name"]. "\\ n";
echo $ row -\u003e nomi. "\\ n";
}
Ushbu rejimda qo'shimcha xotira behuda sarf qilinmaydi va bundan tashqari ustunlarga uchta usul bilan - indeks, nom yoki mulk orqali kirish mumkin.
PDO bayonotida bitta ustun qiymatini olish uchun yordamchi funksiya ham mavjud. Agar biz faqat bitta maydonni talab qilsak, bu juda qulaydir - bu holda yozuv hajmi sezilarli darajada kamayadi:
$ stmt \u003d $ pdo -\u003e tayyorlash ( "Jadvalni tanlang. Qaerda id \u003d?");
$ stmt -\u003e bajaring (qator ($ id));
$ name \u003d $ stmt -\u003e fetchColumn ();
Ammo eng qiziqarli funktsiya, eng katta funktsiyaga ega, bu fetchAll (). Aynan u PDO-ni nafaqat past darajadagi haydovchini, balki ma'lumotlar bazalari bilan ishlash uchun yuqori darajadagi kutubxonaga aylantiradi.
FetchAll () so'rov qaytarilgan barcha qatorlardan iborat qatorni qaytaradi. Bundan ikkita xulosa chiqarish mumkin:
1. Ushbu funktsiya so'rov juda ko'p ma'lumotlarni qaytarib berganda ishlatilmasligi kerak. Bunday holda, an'anaviy pastadirni fetch () yordamida ishlatish yaxshiroqdir.
2. Zamonaviy PHP dasturlarida ma'lumotlar qabul qilingandan so'ng darhol namoyish etilmaydi va ushbu shablonga o'tkaziladi, fetchAll () shunchaki ajralmas bo'lib qoladi, bu sizga qo'lda tsikl yozmaslikka imkon beradi va shu bilan kod miqdorini kamaytiradi.
Oddiy qatorga ega bo'lish.
Parametrlarsiz chaqirilgan ushbu funktsiya FETCH_MODE ichida standart ravishda belgilangan formatdagi ma'lumotlar bazasida qatorlarni o'z ichiga olgan indekslangan qatorni qaytaradi. PDO :: FETCH_NUM, PDO :: FETCH_ASSOC, PDO :: FETCH_OBJ konstantalari o'zgaruvchan formatni o'zgartirishi mumkin.
Ustunni olish.
Ba'zan siz satr yig'indisidan bitta maydonni so'rab oddiy bir o'lchovli qatorni olishingiz kerak. Buning uchun PDO :: FETCH_COLUMN rejimi ishlatiladi.
$ data \u003d $ pdo -\u003e so'rov ("foydalanuvchilarni SELECT nomi") -\u003e fetchAll (PDO :: FETCH_COLUMN);
qator (
0 \u003d\u003e "Jon",
1 \u003d\u003e "Mayk",
2 \u003d\u003e "Maryam",
3 \u003d\u003e "Keti",
)
Kalit qiymat juftligini olish.
Xuddi shu ustunni olishni istagan, lekin raqamlar bo'yicha emas, balki maydonlardan biri bilan indekslangan mashhur format. Doimiy PDO :: bunga FETCH_KEY_PAIR javob beradi.
$ data \u003d $ pdo -\u003e so'rov ("SELECT ID, foydalanuvchilarning ismi") -\u003e fetchAll (PDO :: FETCH_KEY_PAIR);
qator (
104 \u003d\u003e "Jon",
110 \u003d\u003e "Mayk",
120 \u003d\u003e "Meri",
121 \u003d\u003e "Keti",
)
Maydon tomonidan indekslangan barcha qatorlarni olish.
Ko'pincha bazadan barcha satrlarni olish kerak, lekin raqamlar bilan emas, balki noyob maydon bilan indekslanadi. Doimiy PDO qiladi: FETCH_UNIQUE
$ data \u003d $ pdo -\u003e so'rov ("SELECT * FROM foydalanuvchilar") -\u003e fetchAll (PDO :: FETCH_UNIQUE);
qator (
104 \u003d\u003e qator (
"name" \u003d\u003e "Jon",
"car" \u003d\u003e "Toyota",
),
110 \u003d\u003e qator (
"name" \u003d\u003e "Mayk",
"car" \u003d\u003e "Ford",
),
120 \u003d\u003e qator (
"name" \u003d\u003e "Maryam",
"avtomobil" \u003d\u003e "Mazda",
),
121 \u003d\u003e qator (
"name" \u003d\u003e "Keti",
"avtomobil" \u003d\u003e "Mazda",
),
)
Shuni esda tutish kerakki, ustun ustidagi birinchi navbatda albatta noyob maydonni tanlash kerak.
Hammasi bo'lib, PDO-da o'ndan ortiq turli xil ma'lumotlarni yig'ish usullari mavjud. Bundan tashqari, siz ularni birlashtira olasiz! Ammo bu alohida maqola uchun mavzu.
Tayyorlangan iboralar bilan ishlaganda, to'ldiruvchi faqat satr yoki raqamni almashtirishi mumkinligini tushunish kerak. Kalit so'zni ham, identifikatorni ham, chiziqning bir qismini yoki chiziqlar to'plamini to'ldirish vositasi bilan almashtirish mumkin emas. Shuning uchun LIKE uchun avval qidirish satrini tayyorlab, so'ng uni so'rovga almashtirishingiz kerak:
$ name \u003d "% $ name%";
$ stm \u003d $ pdo -\u003e tayyorlash ( "TANLANG * Jadvalni NIMA QO'YDI?");
$ stm -\u003e bajaring (qator ($ name));
$ ma'lumotlar \u003d $ stm -\u003e fetchAll ();
Xo'sh, siz tushunasiz. Bu erda hammasi yomon. PDO identifikatorlar bilan ishlash uchun hech qanday vositalarni taqdim etmaydi va ular eski usulda qo'lda formatlanishi kerak (yoki shunga qaramay, SafeMysql yo'nalishi bo'yicha, bu boshqa muammolar singari oddiy va oqlangan tarzda hal qilinadi).
Shuni esda tutish kerakki, identifikatorlarni formatlash qoidalari turli xil ma'lumotlar bazalari uchun farq qiladi.
Mysql-da, identifikatorni qo'lda formatlash uchun siz ikkita narsani qilishingiz kerak:
- teskari tirnoq bilan o'rab qo'ying (yorliq, "" ").
- identifikator ichidagi ushbu belgilarni ikki baravar ko'paytirish orqali qidiring.
$ maydoni \u003d "` ". str_replace ("" "", "` `", $ _GET ["maydon"]). "" ";
$ sql \u003d $ field ";
Biroq, bitta ogohlantirish bor. Faqat formatlash etarli bo'lmaydi. yuqoridagi kod bizni klassik in'ektsiyadan himoya qiladi, ammo ba'zi hollarda, agar biz maydonlar va jadvallarning nomlarini to'g'ridan-to'g'ri so'rovga almashtirsak, dushman istalmagan narsani yozishi mumkin. Masalan, foydalanuvchilar jadvalida ma'mur maydoni mavjud. Agar kiruvchi maydon nomlari filtrlanmagan bo'lsa, unda ushbu maydonda POSTdan avtomatik ravishda so'rov paydo bo'lganda, har qanday ahmoq biron bir makkani yozib oladi.
Shuning uchun, quyidagi misolda bo'lgani kabi, foydalanuvchidan keladigan jadvallar va maydonlar nomlarini tekshirish tavsiya etiladi
Ko'p sonli darsliklarda ko'rish mumkin bo'lgan har qanday kodni kiritish istagi va apsteni o'ldirish istagini uyg'otadi. Bir xil nom bilan takrorlangan ko'p kilometrli inshootlar - $ _POST identifikatorlarida, o'zgaruvchan nomlarda, so'rovdagi maydon nomlarida, so'rovda to'ldirish joylarida, to'ldirishda va o'zgaruvchan nomlarda.
Ushbu kodga qarab, men kimnidir o'ldirmoqchiman yoki hech bo'lmaganda uni biroz qisqartirmoqchiman.
Agar siz shakldagi maydon nomlari jadvaldagi maydon nomlariga mos kelishi to'g'risida kelishuvni qabul qilsangiz, buni amalga oshirishingiz mumkin. Keyin bu nomlarni faqat bir marta sanab o'tish mumkin (yuqorida aytib o'tilgan buzilishlardan himoya qilish uchun) va mysql-ning o'ziga xos xususiyatlari tufayli INSERT va UPDATE so'rovlariga mos keladigan so'rovni tuzishda kichik yordamchi funktsiyadan foydalaning:
pdoSet funktsiyasi ($ ruxsat berilgan, va $ qiymatlar, $ manba \u003d massiv ()) (
$ set \u003d "";
$ qiymatlari \u003d qator ();
agar (! $ manba) $ source \u003d & $ _POST;
oldingi ($ maydon sifatida ruxsat berilgan) (
if (isset ($ source [$ field]))) (
$ set. \u003d "` ". str_replace ("` "," `` ", $ maydoni). "" ". "\u003d: $ maydoni,";
$ qiymatlari [$ field] \u003d $ source [$ field];
}
}
qaytish pastki ($ to'plami, 0, - 2);
}
Shunga ko'ra, kodni kiritish uchun bo'ladi
$ ruxsat berilgan \u003d qator ("ism", "familiya", "elektron pochta"); // ruxsat berilgan maydonlar
$ sql \u003d "INSERT-ga foydalanuvchilar o'rnatgan". pdoSet ($ ruxsat berilgan, $ qiymatlar);
$ stm \u003d $ dbh -\u003e tayyorlang ($ sql);
$ stm -\u003e bajarish ($ qiymatlari);
Va yangilash uchun - bu:
$ ruxsat berilgan \u003d qator ("ism", "familiya", "elektron pochta", "parol"); // ruxsat berilgan maydonlar
$ _POST ["parol"] \u003d MD5 ($ _POST ["kirish"]. $ _POST ["parol"]);
$ sql \u003d "YANGI YILNING SET". pdoSet ($ ruxsat berilgan, $ qiymatlar). "WHERE id \u003d: id";
$ stm \u003d $ dbh -\u003e tayyorlang ($ sql);
$ qiymatlari ["id"] \u003d $ _POST ["id"];
$ stm -\u003e bajarish ($ qiymatlari);
Juda ta'sirli emas, lekin juda samarali. Eslatib o'taman, agar siz MySQL bilan xavfsiz va qulay ishlash uchun Sinfdan foydalansangiz, bularning hammasi ikki qatorda amalga oshiriladi.
PDO va kalit so'zlar
Bu erda filtrlashdan tashqari, hech narsa haqida o'ylash mumkin emas. shuning uchun so'rovda yozilmagan barcha operatorlarni to'g'ridan-to'g'ri oq ro'yxat orqali ishga tushirish ahmoqdir.
$ dirs \u003d qator ("ASC", "DESC");
$ key \u003d array_search ($ _GET ["dir"], $ dirs));
$ dir \u003d $ buyurtmalar [$ key];
$ sql \u003d "TANLANG * FROM" jadvalidan buyurtma$ maydon $ dir ";
Do'stlaringiz bilan baham: |