Veb-ilovalarda foydalanuvchiga xabarlarni ko'rsatish. PHP AJAX CRUD: MySQL ma'lumotlar bazasida yozuvlarni yaratish, o'chirish, tahrirlash CRUD operatsiyalari uchun PHP skripti

Umumiy koʻrinish

Joomla'da birinchi bo'lib o'rnatilgan bildirishnoma tizimi ilovangizga foydalanuvchini (yoki foydalanuvchilar guruhini) turli xil hodisalar haqida xabardor qilish imkonini beradi. Bildirishnomalarni foydalanuvchi o'qish va kuzatib borishdan manfaatdor bo'lgan muhim ogohlantirishlar sifatida o'ylab ko'ring.
Bildirishnomalar hamma joyda yaratilishi mumkin. Sizning komponentingizda yoki plaginlarda va keyinroq JomSocial bildirishnoma tizimida ko'rsatiladi.
Ushbu qo'llanma sizga qanday qilishni ko'rsatib beradi, lekin bizda uchinchi tomon komponenti haqida tasavvurimiz yo'qligi sababli biz foydalanishimiz mumkin :) misollar onAfterProfileUpdate tadbirida ishga tushiriladigan hamjamiyat plaginida amalga oshiriladi.
Agar siz ushbu hodisada ishga tushadigan plaginni qanday yaratishni bilmasangiz, ushbu qo'llanmani tekshirishingizni tavsiya qilamiz.

Baribir uni komponentingizda amalga oshirish

Ushbu qo'llanmaning umumiy ko'rinishida aytilganidek, biz hamjamiyat plaginidan foydalangan holda bildirishnomalarni yaratamiz.
Siz komponentingiz yoki plaginingiz ichida bildirishnomalar yaratmoqchi bo'lishingiz mumkin. Quyidagi o'quv qo'llanma har qanday holatda ishlaydi. Siz faqat kodingizning qaysi nuqtasida bildirishnoma yaratilishini aniqlashingiz va shunchaki JomSocial Core Libraries faylini yuklashingiz kerak.

talab_bir marta JPATH_ROOT . "/components/com_community/libraries/core.php" ;

Quyida tushuntirilgan qo'llanmadan so'ng kengaytmangiz uchun ham yaxshi ishlaydi

Rivojlanish muhitini tayyorlash

1. Siz allaqachon hamjamiyat tipidagi misol plaginini yaratgan deb taxmin qilamiz, u foydalanuvchi o‘z profilini o‘zgartirganda ishga tushadi
Agar yo'q bo'lsa, siz bo'sh misol plaginini dan yuklab olishingiz, uni Joomla-ga o'rnatishingiz va plaginni yoqishingiz mumkin. U nomlanadi Hamjamiyat - bildirishnomalar misoli
2. Ma'lumotlar bazasiga o'ting va bu ikkita jadvalni bo'shating, ularda hech qanday yozuvlar bo'lmasligi uchun

A) prefiks_jamoa_xabarnomasi
b) prefiks_jamoa_mailq

3. Sinov saytlarida kamida ikki (2) foydalanuvchi bo'lsin va ularning identifikatorini biling

Joomla-ning oldingi versiyalarida foydalanuvchi identifikatorlari har doim belgilangan raqamdan boshlanadi (62, 42) Joomla 3-da bu raqam tasodifiy bo'ladi, shuning uchun bizning sinov muhitimiz tasviri, chunki u sizning oxirida, albatta, boshqacha bo'ladi.

Birinchi xabarnoma

ROOT/plugins/community/example-da joylashgan plagin PHP faylini oching.
OnAfterProfileUpdate() funktsiyasi ichida o'zgartiring

CNotificationLibrary::add ( $cmd , $actor , $target , $subject , $body , $shablon , $params );

Misolda ko'rsatilganidek, bildirishnoma qo'shish api 7 ta parametrga ega

  • $cmd - xabarnoma turi. Ushbu faylda barcha bildirishnomalar turlarini ko'rishingiz mumkin. ROOT/components/com_community/libraries/notificationtypes.php 53-qatordan boshlab yoki atrofida. System_messaging bildirishnoma turidan foydalanishni tavsiya etamiz.
  • $aktyor - harakatni amalga oshiruvchi shaxs
  • $target - bu bildirishnoma oladigan shaxs yoki odamlar guruhi
  • $subject - bu bildirishnoma mavzusi, ikkalasida ham bildirishnoma qalqib chiquvchi oynasi va elektron pochta sarlavhasi
  • $body - elektron pochta xabarnomasining asosiy qismi
  • $shablon - foydalanish uchun maxsus shablon kerak bo'lsa, uni shu yerda belgilashingiz mumkin. Aks holda, bu parametr bo'sh bo'lishi mumkin
  • $params - maxsus belgilangan parametrlar
  • Bularning barchasini bilib, biz foydalanadigan o'zgaruvchilarni aniqlaylik
    Plagin kodingizni quyidagicha o'zgartiring:

    $user = CFactory::getUser(); $cmd = "system_messaging" ; // birinchi parametr, faoliyat turi $actor = $user -> id ; //ikkinchi parametr - $actor identifikatorini oling $target = "965" ; // uchinchi param. Kim bildirishnoma oladi? Bizning ishlab chiquvchi muhitimizda uning identifikatori 965 bo'lgan administrator foydalanuvchisi. Sizning muhitingizda siz ob'ektingizdan yoki foydalanuvchilar qatoridan identifikatorni olishni xohlaysiz. $subject = "Xabarnoma mavzusi" ; // Har ikkisining mavzusi, elektron pochta va qalqib chiquvchi bildirishnomalar $body = ; // Elektron pochtadagi asosiy xabar. $shablon = "" ; // Agar jomsocial shablon faylidan foydalanish kerak bo'lsa, uni shu yerda belgilashingiz mumkin. $params = new CParameter("" ); // Biz CNotificationLibrary:: add ( $cmd , $actor , $target , $subject , $body , $template , $params ) klassini rasmiy belgilamasdan turib, qoʻshimcha parametrlar obyektini yaratmoqchimiz va unga maʼlumotlarni tayinlaymiz. ;

    Endi istalgan foydalanuvchi bilan tizimga kiring va profil ma'lumotlarini o'zgartiring. Nima bo'lganini ko'rish uchun ma'lumotlar bazasiga boraylik.
    Prefix_community_notifications jadvaliga o'ting va yangi yozuvni kuzating

    Prefix_community_mailq jadvaliga o'ting va yangi yozuvni ko'ring

    Tabriklaymiz! - Siz elektron pochta va ichki JomSocial bildirishnoma tizimi orqali yuborilgan birinchi shaxsiy bildirishnomangizni muvaffaqiyatli yaratdingiz.


    Potentsial kod Bloat

    Yuqoridagi misol yaxshi va u ishlaydi, lekin odatda uni shunday ishlatish tavsiya etilmaydi. Buning o'rniga, buni shunday yozish mumkin

    $aktyor = CFactory::getUser(); $params = new CParameter("" ); CNotificationLibrary:: add ( "system_messaging" , $actor -> "Bu xabarnomaning asosiy xabari", "" , $params );

    Bu yuqorida ko'rsatilgan kod bilan bir xil ishni bajarishda ancha toza va amal qilish osonroq.

    Maxsus bildirishnoma parametrlari

    Bildirishnoma API'si siz qo'shmoqchi bo'lgan har qanday parametr bilan kengaytirilishi mumkin.
    Ushbu parametrlar elektron pochta shabloniga, bildirishnomaga va, albatta, til fayliga o'tkazilishi mumkin.

    $aktyor = CFactory::getUser(); $link = "http://www.google.com" ; $params = new CParameter("" ); $params -> set (“aktyor” , $actor -> getDisplayName () ); // (aktyor) tegi sifatida foydalanish mumkin $params -> set ("actor_url" , "index.php?option=com_community&view=profile&userid=" . $actor -> id ); // (aktyor) tegi uchun havola $params -> set ("url" , $link ); // butun faoliyatning url. Bildirishnoma oynasida kursorni avatar ustiga olib kelganda foydalaniladi. Chiquvchi xatlarda (url) teg sifatida ham foydalanish mumkin. $link o'zgaruvchisini aniqlaganingizga ishonch hosil qiling:) CNotificationLibrary:: add ( "system_messaging" , $actor -> id , "965" , "Bildirishnoma mavzusi", "Bu xabarnomaning asosiy xabari", "" , $params) ;

    • $params = yangi CParameter( ); - Biz yangi params ob'ektini yaratmoqchimiz va unga sinfni rasmiy ravishda belgilamasdan ma'lumotlarni tayinlaymiz.
    • $params->set("aktyor", $actor->getDisplayName()); - Sizning bildirishnomangiz doimo aktyor bo'lishi kerak. Ushbu parametr shablonga (aktyor) tegi sifatida o'tkazilishi mumkin. Bildirishnoma oynasida u harakatni amalga oshiradigan foydalanuvchini belgilaydi.
    • $params->set("actor_url", "index.php?option=com_community&view=profile&userid=" . $actor->id); - Aktyor URL manzili odatda aktyorning URL manzilidir. Bildirishnoma qalqib chiquvchi oynasida u (aktyor) elementiga havolani qo'shadi
    • $params->set("url", $link); - Bu siz doimo to'g'ri o'rnatishingiz kerak bo'lgan eng muhim parametrdir. Bildirishnoma oynasida ushbu parametr avatar tasviri ustida ishlatiladi. Elektron pochta xabarnomasida u faoliyat sodir bo'lgan joyni aks ettiradi.

    Ushbu misol uchun biz $link o'zgaruvchisini o'rnatamiz www.google.com shuning uchun qanday ishlashini ko'rishingiz mumkin

    Til qatorini qo'shish va parametrlardan foydalanish

    Biz o'rnatgan parametrlarga ega bo'lsak, til fayllarimizda ham foydalanish mumkin.
    "Til tugmachalarini o'zgartirish orqali aniqlaymiz. CNotificationLibrary::add() API

    CNotificationLibrary::add("system_messaging" , $actor -> id , "965" , JText::sprintf("PLG_COMMUNITY_EXAMPLE_SUBJECT" ) , JText::sprintf("PLG_COMMUNITY_EXAMPLE_BODY", $ms ");

    Til fayli shunday ko'rinishi kerak

    PLG_COMMUNITY_EXAMPLE_SUBJECT = "(aktyor) profili yangilangan" PLG_COMMUNITY_EXAMPLE_BODY = "Assalomu alaykum Admin \n Bu sizga (aktyor) profili yangilangani haqida xabar beradi \n\n Agar Googlega oʻtmoqchi boʻlsangiz, shu yerni bosing \n a href=" _QQ_" (url)"_QQ_">(url)"

    Ushbu misolda biz teg (aktyor) va (url) ma'lumotlarni ikkalasiga ham, bildirishnomalarga va elektron pochta shablonlariga o'tkazish uchun foydalandik. Keling, bu qanday ko'rinishini ko'rib chiqaylik.
    Xabarnoma oynasida kursorni avatar ustiga olib borganingizda, ishga tushirilgan (url) parametriga e'tibor bering va havolani avatar orqali Google-ga qo'shadi. Bu ataylab qilingan, chunki biz shunday qildik :)


    ]

    Xuddi shu oynada, kursorni aktyor havolasi ustiga olib borganingizda. Bu (aktyor) harakatni amalga oshiruvchi foydalanuvchini aks ettirgan qismi, (actor_url)" ob'ekt to'g'ri bog'langanligiga e'tibor qaratdi.


    Keling, elektron pochta navbatida nima sodir bo'lishini ko'rib chiqaylik


    Va nihoyat, oxirgi foydalanuvchiga yuboriladigan haqiqiy elektron pochta


    Muvaffaqiyat
    Hozirgacha biz uchta (3) parametr yaratdik, ular bildirishnoma oynasida va elektron pochta xabarlarida muvaffaqiyatli qo'llaniladi.

  • (aktyor) - harakatni bajaradigan foydalanuvchining foydalanuvchi nomini qaytaradi
  • (actor_url) - beradi atribut (aktyor)
  • (url) - Majburiy emas, lekin har doim bildirishnomangizda bo'lishi kerak. Bu bizga xabar qilingan harakat sodir bo'lgan asosiy url.
  • Xuddi shunday, siz ham belgilashingiz mumkin "

    • (maqsad) - agar kerak bo'lsa
    • (target_url) agar sizga xabarnomada kerak bo'lsa.
    • (sarlavha) - Odatda bildirishnoma yaratgan ob'ektga murojaat qilish uchun ishlatiladi. Misol: “X foydalanuvchi Y albomiga yangi surat joylashtirdi.” Albom Y bu erda nom
    • (title_url) - Avvalgilarida bo'lgani kabi, bildirishnomani yaratgan ob'ektning URL manzili.
    • (xabar) - Ushbu parametrdan JomSocial elektron pochtasining asosiy qismidagi xabarni o'rnatish (va aks ettirish) uchun foydalanish mumkin.
    3,3 ming

    Foydalanuvchiga xabarlarni ko'rsatish - bu veb-ilova bajarishi kerak bo'lgan juda keng tarqalgan harakat. Bu shakllarni qayta ishlashda paydo bo'lishi mumkin, bu xato xabarlari, foydalanuvchi saytning cheklangan qismiga kirishga harakat qilganda ro'yxatdan o'tishni aytadigan xabarlar va boshqa ko'p hollarda bo'lishi mumkin.

    Ko'pincha xabarlarni yaratish va chiqarish turli xil HTTP so'rovlariga bo'linadi. Qoidaga ko'ra, shakllarni qayta ishlashdan keyin qayta yo'naltirishdan foydalanish qulay (Orqaga va Yangilash tugmalari bilan bog'liq muammolarni oldini olish uchun), lekin shu bilan birga, xabarni yaratish uchun tabiiy moment aynan shakllarni qayta ishlash va unga hamroh bo'lgan harakatlarni bajarish vaqtidir. bu. Nega? Tasavvur qiling-a, xabar matni quyidagicha ko'rinishi kerak: ""Sichqoncha paneli" elementi uchun buyurtma qilingan birliklar soni 7 dan 12 gacha muvaffaqiyatli o'zgartirildi." Qayta yo'naltirishdan so'ng, ehtimol funksionallik nuqtai nazaridan butunlay boshqa sahifaga, avval nima qilinganligini aniqlash uchun qo'shimcha bosh og'rig'i bo'ladi.

    Ko'pincha xabarlar shaklni qayta ishlaydigan POST so'rovida ko'rsatiladi - bu yaxshi emas, "bu sahifa eskirgan" so'zlari hayotni buzadi (foydalanuvchi "Orqaga" tugmasini sinab ko'rishga qaror qilganda).

    Kimdir do'stona xabarlardan voz kechib, qayta yo'naltirishdan foydalanadi.

    Shu bilan birga, hayotni yaxshilashning oddiy va aniq yo'li mavjud. Aniq bo'lishiga qaramay, negadir men uni hech kim ishlatmaganini ko'rmaganman - hech bo'lmaganda boshqa odamlarning manbalariga qaraganimda.

    Shunday qilib, bizda muammo bor - xabar turli so'rovlarda "yashashi" kerak. Bizga xabar matnini uni ko'rsatishi kerak bo'lgan sahifaga o'tkazish mexanizmi kerak. Seanslar haqida allaqachon eslagandirsiz.

    Ha, umuman olganda, siz haqsiz. Boshqa usullar, masalan, global o'zgaruvchi orqali, qayta yo'naltirish ishlatilganda ma'lumotlarni saqlashga ruxsat bermaydi (Maksim Naumenkoning eslatmasi). Bundan tashqari, men odatda ilovadagi har bir ekran boshqa ma'lumotlar bilan bir qatorda oldingi ekranlarda yaratilgan xabarlarni ko'rsatish qobiliyatiga ega ekanligiga ishonch hosil qilaman. Bu qulay, chunki xabarlarni ko'rsatish uchun alohida ekranlarni tayyorlashning hojati yo'q va foydalanuvchi yana sichqonchani bosishi shart emas. Lekin, haqiqatan ham, dizayner bu erda o'ylashi kerak - xabarlar paydo bo'ladigan maydonni ta'kidlash.

    G'oya juda oddiy va uni bir nechta darslar bilan amalga oshirish mumkin.

    Aqlga keladigan birinchi narsa bu bizning oddiy sinf diagrammamizdagi xabarni ifodalovchi Message sinfini yaratishdir. Xabar seansda o'zini saqlashi, shuningdek, ekranda o'zini ko'rsatishi kerak.

    class Xabar ( /** * Xabar mazmuni. */ var $content; /** * Xabar matnini ishga tushirish uchun konstruktor. * * @param mazmuni xabar mazmuni */ funksiya Xabar($content) ( $this->content = $ kontent ; ) /** * Seansga xabar yozing */ function send() ( $_SESSION["session_messages"] = $this->content; ) /** * Xabarni sahifaga chiqarish. */ funksiyasi toPage() ( echo " - " . $this->content . "
    "; } }

    $_SESSION o'zgaruvchisi sessiyaga kirish uchun ishlatiladi.

    E'tibor bering, $_SESSION massiv, biz "session_message" indeksli ushbu massivning faqat bitta elementidan foydalanmoqdamiz.

    Bunday holda, biz "massivlar massivi" bilan shug'ullanamiz - biz "session_message" elementida saqlaydigan narsa massiv, bu uzatilgan xabarlar ro'yxati (albatta, ulardan bir nechtasi bo'lishi mumkin).

    Agar siz mavzuni topa olmasangiz, qo'llanmaning sessiyalar va massivlarga bag'ishlangan bo'limlarini ko'rib chiqish vaqti keldi.

    Savolingiz bo'lishi mumkin. Nima uchun bu erda darslar kerak? Ikki funktsiya bilan ishlash mumkin edi. Ammo keling, batafsilroq ko'rib chiqaylik. Biz har xil turdagi (ma'lumot, xato, ogohlantirish) xabarlar yaratishimiz va xabarlarni qabul qiluvchilarni aniqlashimiz kerak bo'lishi mumkin.

    E'tibor bering, hozirda sessiyaga ob'ektning o'zi emas, balki faqat xabar matni qo'yiladi. OOP bu usulga kiradigan mijoz kodini o'zgartirmasdan send() usulining xatti-harakatlarini keyinchalik o'zgartirishga imkon beradi (masalan, kelajakda biz Message ob'ektini ko'p maydonlarga ega bo'lsa, sessiyaga yozishimiz mumkin).

    Tasavvur qilaylik, biz buni funksiyalar yordamida qilamiz. Bizda, ehtimol, message_send($txt) funksiyasi, shuningdek, message_to_page($txt) funksiyasi bo‘lar edi. Endi biz har xil turdagi xabarlar uchun har xil xatti-harakatlarga ega bo'lish qobiliyatini qo'shishimiz kerak. Funktsiya chaqiruvlari o'zgaradi: message_send($txt, $kind), message_to_page($txt, $kind). Bunday funktsiyalarni qidirish, tuzatishlar kiritish uchun siz butun dastur kodini tarashingiz kerak bo'ladi.

    Xabarni assotsiativ massiv sifatida taqdim etish orqali vaziyatni oldindan taxmin qilish orqali buni oldini olish mumkin: $msg[‘txt’], $msg[‘tur’], keyin funksiya chaqiruvlarida faqat bitta parametr bo‘ladi. Bu qanday qilib sinfga aylanishga harakat qilayotganini his qila olasizmi?

    Shunday qilib, OOP sizga hamma narsani oldindan o'ylamaslik hashamatiga ega bo'lish imkoniyatini beradi.

    Keyingi sinf - Inbox - aynan shu uchun mo'ljallangan.

    class Inbox ( /** * Qabul qilingan xabarlar massivi. */ var $messages = array(); /** * Konstruktorda biz barcha qabul qilingan xabarlarni * olamiz va ularni sessiyadan o‘chirib tashlaymiz. */ funksiyasi Inbox() ( if (is_array($ _SESSION["session_messages"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i)< $co; $i++) { $this->xabarlar = yangi xabar($messages[$i]); ) ) /* xabarlar massivini tozalash */ $_SESSION["session_messages"] = array(); ) /** * Sahifadagi Kirish qutisi tarkibini ko'rsatish. */ function toPage() ( $co = sizeof($this->messages); if ($co > 0) ( echo "Tizimdan kelgan xabar:
    "; ) uchun ($i = 0; $i< $co; $i++) { $this->xabarlar[$i]->ToPage(); )))

    Keling, xabar almashish tizimimizni sinab ko'raylik.

    Keling, joriy daqiqadagi soniyalar sonini bildirish orqali ariza topshirishga javob beradigan juda oddiy misol yarataylik.

    Biz barcha ishlarni massivlar va seanslar bilan sinflar ichida yashirdik va yakuniy kod oddiy va chiroyli ko'rinadi.

    Veb-serveringizda katalog yarating, so'ngra unda ushbu uchta faylni yarating va skriptni sinab ko'ring. Esda tutingki, Orqaga va Yangilash tugmalari bilan hech qanday muammo yo'q.

    Endi tasavvur qiling-a, siz murakkab portal yaratmoqdasiz, bu erda, qoida tariqasida, sahifalarda bir nechta bloklar mavjud va ularning har biri alohida dasturni o'z ichiga olishi mumkin.

    Bu erda biz ikkita qiyinchilikka duch kelamiz:

    * Men xabarlar ro'yxati sahifaning ma'lum bir qismida paydo bo'lishini xohlayman va siz allaqachon buning uchun yaxshi joy topdingiz.
    Muammo shundaki, siz $inbox->toPage() buyrug'ini sahifadagi xabarlar ro'yxatining pozitsiyasiga mos keladigan vaqtda ishga tushirishingiz kerak. Agar biz ushbu ro'yxatning o'rnini o'zgartirmoqchi bo'lsak, kodga kirishimiz kerak, ammo buning uchun portal ramkasini doimiy ravishda o'zgartirish yaxshi emas. Eng yaxshi yechim xabarlarning chiqishini alohida modul ko'rinishida qilish bo'ladi, biz faqat uni ramkaga ulash kerakligini bilamiz.
    Ya'ni, modullarni ishga tushirishning qat'iy ketma-ketligidan ozod bo'ling. Darhaqiqat, Inbox chiqishi natijasi tizimning ishlashiga bog'liq emasligi sababli (bu bosqichda biz allaqachon sessiyadagi barcha ma'lumotlarga egamiz), unda nima uchun ortiqcha murakkablik?
    * Xabarlar ro'yxatining ko'rinishini (dizaynini) saqlab qolish uchun siz Message va Inbox sinflarining toPage() usullarida qattiq kodlangan HTML kodiga e'tibor berishingiz kerak. Odatda, dizaynni o'zgartirish uchun siz PHP kodini o'zgartirishingiz kerak bo'ladi.

    Birinchi muammoni hal qilishga harakat qilish uchun siz Inbox chiqishi natijasini saqlaydigan bufer yaratishingiz mumkin.

    Ehtimol, bizda hali ham shunga o'xshash (Kirish qutisiga) narsalar bo'ladi va biz bufer tizimini yaratishimiz kerak. Kimning chiqishi kimga tegishli ekanligini chalkashtirmaslik uchun, ehtimol, buferlarni nomlashga o'tamiz. Biz buferlar chiqishi kerak bo'lgan ketma-ketlikni biron bir joyda saqlaymiz - o'zgarishlarni osonlashtirish uchun tashqi faylda.

    Yechimga urinish bizga XML dan oraliq ma'lumotlarni saqlash vositasi sifatida foydalanish g'oyasini allaqachon beradi. Va XSLT uslublaridan foydalanish ikkinchi muammoni hal qilishga yordam beradi.

    XML nima va XSLT nima ekanligi haqida to'xtalmayman. Agar siz bu narsalar bilan tanish bo'lmasangiz, zvon.org qidirishni boshlash uchun yaxshi joy.

    Maqsad HTML kodini emas, balki toPage() usullarida XML strukturasini yaratishdir. Sahifa hujjati XML kodli satr sifatida yaratiladi (u "bufer" bo'lib xizmat qiladi) va skriptning oxirgi bosqichida biz XSL transformatsiyasidan foydalanamiz.

    Birinchidan, kodning asosiy qismining natijasi qanday bo'lishi kerakligini tasavvur qilaylik.

    daqiqa 57 soniya: 45

    Nima ekanligini taxmin qilish juda oson - ikkita xabar va shakl. E'tibor bering, PHP skripti faqat shunday satrni tayyorlashi kerak - bu juda oddiy. Bundan tashqari, asosiy teglarning tartibi muhim emas - siz ularni birinchi navbatda qo'yishingiz mumkin, masalan, dasturchi uchun qulay bo'ladi. Uni qanday amalga oshirish kerak. Siz hech narsani o'zgartirmasdan, chiqish buferidan foydalanishingiz, HTML kodi o'rniga XMLni chiqarishingiz va oxirida shunchaki satrda chiqishni olishingiz mumkin. Ammo keyin biz moslashuvchanlikni yo'qotamiz - masalan, ba'zida siz disk raskadrovka ma'lumotlarini to'g'ridan-to'g'ri sahifaga chiqarishni xohlaysiz (echo yordamida). Shu bilan birga, PHP ishlab chiquvchilari daraxt hujjatlarini yaratish va uzatishning yanada rivojlangan usulini taklif qiluvchi DOM moduli ustida ishlamoqda. Agar biz DOMni amalga oshirmoqchi bo'lsak, biz butun dasturni qayta loyihalashimiz kerak bo'ladi, satrlar chiqishini DOM elementlarini yaratishga o'zgartiramiz. Shuning uchun, men umumiy XML hujjatini ketma-ket yig'ib, ob'ektlarning XML ko'rinishini ob'ektlarning o'zida saqlashni afzal ko'raman. Bu unchalik qiyin emas, faqat biroz o'zgartirish kerak. Siz ushbu texnikaning XML ma'lumotlarini saqlashning o'ziga xos usuli bilan qat'iy bog'lanmaganligini ko'rasiz va bu sizga ozgina kuch sarflab DOM-dan foydalanishga o'tish imkonini beradi. Avvalo, har bir ob'ektimizda toPage() usuli borligiga e'tibor bering. Ushbu o'xshashlik bizni yangi umumiy ota-onalar sinfini joriy etish haqida o'ylashga majbur qilishi kerak. Sahifa uchun XML hujjatining qismlarini yaratishi mumkin bo'lgan har bir sinf ob'ektning XML ko'rinishiga g'amxo'rlik qiladigan sinfdan meros bo'lsin. Keling, uni Outputable deb ataylik.

    class Outputable ( /** * XML konteyneri (string). */ var $output = ""; /** * Konteyner tarkibini bering va konteynerni tozalang. * * @XML ma'lumotlari bilan qatorni qaytarish */ getOutput funktsiyasi () ( $ out = $this->output; $this->output = ""; return $out; ) /** * Konteyner tarkibiga bir qism qo‘shing. * * Qo‘shiladigan qatorni @param qatori * / function appendOutput($string) ( $this ->output .= $string . "n"; ) /** * "Abstrakt" usuli. */ function toPage() ( ) )

    toPage() usuli bo'sh qilingan - bu holda u tashqi "matryoshka" sinflari ichki sinf bilan qanday bog'lanishi kerakligi ko'rsatkichi sifatida kerak. Biroq, agar sahifada o'zini xuddi shunday ko'rsatadigan ko'plab ob'ektlar mavjudligini sezsak, biz bu erda standart dasturni taklif qilishimiz mumkin.

    Message va Inbox sinflari biroz o'zgaradi - endi ular ikkalasi Outputable-dan meros bo'lishi kerak va toPage() usullari ham o'zgaradi.
    Message.php

    class Xabar kengaytiriladi Chiqish mumkin ( /** * Xabar mazmuni. */ var $content; /** * Xabar matnini ishga tushirish uchun konstruktor. * * @param mazmuni xabar mazmuni */ funksiya Xabar($content) ( $this->content) = $content; ) /** * Seansga xabar yozing */ function send() ( $_SESSION["session_messages"] = $this->content; ) /** * Sahifaga xabar chiqarish.* / function toPage() ( $this->appendOutput("".$this->content.""); ) )

    class Inbox kengaytiriladi Chiqish mumkin ( /** * Qabul qilingan xabarlar massivi. */ var $messages = array(); /** * Konstruktorda biz barcha qabul qilingan xabarlarni * olamiz va ularni sessiyadan olib tashlaymiz. */ funksiyasi Inbox( ) ( if (is_array ($_SESSION["sessiya_xabarlari"])) ( $messages = $_SESSION["session_messages"]; $co = sizeof($messages); ($i = 0; $i) uchun< $co; $i++) { $this->xabarlar = yangi xabar($messages[$i]); ) ) /* xabarlar massivini tozalash */ $_SESSION["session_messages"] = array(); ) /** * Sahifadagi Kirish qutisi tarkibini ko'rsatish. */ function toPage() ( $co = sizeof($this->xabarlar); $this->appendOutput(""); uchun ($i = 0; $i)< $co; $i++) { $this->xabarlar[$i]->toPage(); $this->appendOutput($this->xabarlar[$i]->getOutput()); ) $this->appendOutput(""); ))

    Chiqarish usuli o'zgardi - endi, to'g'ridan-to'g'ri sahifaga chiqarish o'rniga, tashqi ko'rinish ob'ektlarning har birida "o'tiradigan" Outputable-da saqlanadigan vaqt uchun. appendOutput() usuli echo() konstruktsiyasini almashtirish vazifasini bajaradi. Ob'ektning chiqishini olish uchun getOutput() usuli qo'llaniladi.

    Endi kodning mijoz qismi nima ekanligini ko'rib chiqamiz, bu avvalgi muammoni hal qiladi.
    index.php

    Asosiy yangilik $global_content ob'ektida bo'lib, uning nomi o'zi uchun gapiradi. Bu holda, u Outputable sinfiga tegishli; real hayotdagi vazifalarda siz sahifa mazmuni uchun alohida sinf yaratishingiz mumkin.

    Agar diqqat bilan qarasangiz, skriptning mazmuni deyarli o'zgarmagan - bir xil kirish qutisi, bir xil toPage(). Sahifa tarkibidagi xabarlar roʻyxati mazmunini aks ettiruvchi koʻrsatma qoʻshildi. Turli xillik uchun endi ikkita xabar yaratildi.

    Natijani ko'rish uchun faqat XSL shablonini tayyorlash qoladi.
    style.xsl

    XSLT misoli

    xabar

    Biz nimaga erishdik?

    Avvalo, siz murakkab loyihalarni ishonchliroq bajarishingiz mumkin - modullarning haqiqiy mustaqilligi ta'minlanadi. Natijalarni sahifaga joylashtirish tartibi endi tashqi XSL shabloni yordamida boshqariladi va modullarni ishga tushirish tartibiga bog'liq emas.

    Loyihada o'z ishi natijasida XML ma'lumotlarini yaratadigan har qanday moduldan foydalanish mumkin. Aytgancha, bu shablonli dvigatellarga nisbatan afzalliklaridan biri bo'lib, unda ma'lumotlarni yaratish ma'lum bir dvigatelning chaqiruv usullari (tayinlash va boshqalar) ketma-ketligidan iborat bo'lib, ular uchun umumiy standart mavjud emas.

    Yana bir afzalligi - disk raskadrovka qulayligi. Agar siz skriptni ishga tushirsangiz, har bir sahifada disk raskadrovka chiqishi borligini sezasiz - bu nosozliklarni tuzatish ilovalarini sezilarli darajada osonlashtiradigan XML prototipi.

    Xabar ob'ektlarini qanday yaratish haqida o'ylashingiz kerak bo'lgan yana bir narsa. Mijoz kodida to'g'ridan-to'g'ri new dan foydalanish har doim ham qulay emas. Lekin, ehtimol, bu alohida maqola uchun mavzu.

    Va nihoyat, istiqbollar haqida qisqacha ma'lumot:

    * muhim xabarlar ro'yxati uchun qalqib chiquvchi oynalar
    * xabarlardagi "yuboruvchi sahifalar" va "maqsad sahifalari"
    * ma'lumotlar bazasiga xabarlarni kiritish
    * "Mening harakatlarim tarixini ko'rsatish" tugmasi
    * seanslar doirasidagi foydalanuvchi harakatlarini statistik tahlil qilish
    * veb-ilovalardagi "aqlli yordamchilar"

    KP va BUS-da, 11.5-versiyasidan boshlab, ijtimoiy tarmoqni o'z ichiga olgan nashrlarda "Web messenger" yangi moduli paydo bo'ldi.
    Barchaga taqdim etilishidan oldin modul bizning "Ijtimoiy intranetimiz" da 8 ta yangilanishni to'plagan holda olovga cho'mdi.


    Olti oylik rivojlanish jarayonida biz ko'p ishlarni qildik

    Biz avvalgi interfeysdan butunlay voz kechdik va mashhur messenjerlar tajribasi asosida yangisini yaratdik.
    Sahifada dialog oynasi ochila boshladi, unda yuzlar paydo bo'ldi, xabarlar rang bilan belgilandi va bir vaqtning o'zida bir nechta odamlar bilan suhbatni osonlik bilan davom ettirish mumkin bo'ldi.

    Tarix oynasi - bu alohida mavzu, hamma uzoq vaqtdan beri tarixni qidirishni xohlardi, endi bizda nihoyat bor, tez navigatsiya qilish uchun u erga taqvim qo'shishni rejalashtirmoqdamiz.

    Biz har xil turdagi xabarlar bilan bildirishnoma markazini yaratdik, ularni qabul qilish tarixini ko'rish imkoniyatini taqdim etdik va ishlab chiquvchilar uchun bildirishnomalarni qo'shish va qayta chaqirish uchun oddiy API.

    Va bularning barchasi saytingizning har bir sahifasida mavjud!

    Afsuski, rejalashtirilgan hamma narsa amalga oshmadi

    Birinchidan Bizning vaqtimiz yo'q edi, bu xabarlarni jadvallarimizga tarjima qilish edi.
    Bunday o'tish "ijtimoiy tarmoq" modulidan voz kechish imkonini beradi, bu muharrirlarni tanlashda ko'proq erkinlik beradi, shuningdek, guruh suhbatlarini joriy qilish mumkin bo'ladi.

    Ikkinchi, bu haqiqiy "tezkor" aloqani amalga oshirishdir. Endi modul muntazam birlashmadan foydalanadi, serverni har n-sekundda bir marta so'raydi, so'rov muddati aloqa faolligiga qarab o'zgaradi.
    Biz doimiy ulanishlarni ta'minlaydigan va kerak bo'lganda ma'lumotlar yangilanishlarini yuboradigan alohida xizmat yozishni rejalashtirmoqdamiz (messenjer uchun, jonli tasma uchun va hokazo).

    Uchinchi, biz interfeysni biroz o'zgartirishni, alohida kontaktlar ro'yxati va dialog oynasidan voz kechishni va ularni bir butunga birlashtirishni rejalashtirmoqdamiz, bu esa kelajakda messenjerni mobil ilovaga o'tkazish imkonini beradi.

    Hozircha hech qanday hujjat yo'q va u kuzgacha ko'rinmaydi, chunki... Modul faol ishlab chiqilmoqda va biz APIni o'zgartirish imkoniyatini qoldirmoqchimiz.
    Biroq, men APIning ish allaqachon tugagan qismi bilan ishlash misollarini nashr etishga harakat qilaman va siz ularni modullarda xavfsiz ishlatishingiz mumkin.

    Bildirishnomalar bilan ishlash (11.5.2 versiyasidan boshlab IM uchun tegishli)

    Biz uch turdagi bildirishnomalarni joriy qildik:
    - shaxsiylashtirilgan bildirishnoma;
    - tizimdan bildirishnoma;
    - tasdiqlashni talab qiluvchi xabarnoma;

    API-dan foydalanishdan oldin modul tizimda o'rnatilganligini tekshirishingiz kerak:

    agar (IsModuleInstalled("im") && CModule::IncludeModule("im")) ( ) ?>

    Shaxsiylashtirilgan bildirishnoma


    Agar xabarlar NOTIFY_TAG qilib sozlangan bo‘lsa, foydalanuvchi ularni guruhlaydi.

    Tizimdan bildirishnoma


    $arMessageFields = massiv(// oluvchi "TO_USER_ID" => $USER->GetId(), // jo'natuvchi (>0 bo'lishi mumkin) "FROM_USER_ID" => 0, // bildirishnoma turi "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, // bildirishnoma yuborishni so'ragan modul "NOTIFY_MODULE" => "im", // guruhlash uchun ramziy teg (faqat bitta xabar ko'rsatiladi), agar bu talab qilinmasa, "NOTIFY_TAG" => "IM_CONFIG_NOTICE" parametrini o'rnatmang, // saytdagi bildirishnoma matni (html va BB kodlari mavjud) "NOTIFY_MESSAGE" => "[b]Diqqat: "Tezkor xabarlar va bildirishnomalar" moduli sozlamalarida tekshirish va ijtimoiy tarmoqqa to'g'ri yo'lni ko'rsatish kerak" , // elektron pochta orqali yuboriladigan bildirishnoma matni (yoki XMPP ), agar farqlar bo'lmasa, parametrni o'rnatmang //"NOTIFY_MESSAGE_OUT" => ""); CIMNotify::Add($arMessageFields); ?>

    Tasdiqlashni talab qiluvchi bildirishnoma (tasdiqlash)


    $arMessageFields = array(// recipient "TO_USER_ID" => $USER->GetId(), // jo'natuvchi "FROM_USER_ID" => 2, // bildirishnoma turi "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM, // bildirishnoma yuborishni so'ragan modul "NOTIFY_MODULE " => "taqvim", // guruhlash uchun ramziy teg (faqat bitta xabar ko'rsatiladi), agar bu shart bo'lmasa, "NOTIFY_TAG" => "CALENDAR|INVITE|123|" parametrini o'rnatmang.$ USER->GetId() , // saytdagi bildirishnoma matni (html va BB kodlari mavjud) "NOTIFY_MESSAGE" => "Sizni 15-mart kuni bo'lib o'tadigan "Tezkor xabarlar va bildirishnomalar" uchrashuvida ishtirok etishga taklif qilaman, 2012 yil 14:00", // e-pochta orqali yuborish uchun bildirishnoma matni (yoki XMPP), agar farqlar bo'lmasa, "NOTIFY_MESSAGE_OUT" parametrini o'rnatmang => "Foydalanuvchi Evgeniy Shelenkov sizni "Instant" uchrashuvida ishtirok etishga taklif qiladi. xabarlar va bildirishnomalar” #BR# 15.03.2012 soat 14:00 da boʻlib oʻtadi.#BR # #BR# Qabul qilish: http://test.ru/calend.php?CONFIRM=Y&CID=123 #BR# Rad etish: http://test.ru/calend.php?CONFIRM=N&CID=123", // bildirishnoma tugmalarini tavsiflovchi massiv "NOTIFY_BUTTONS" => Massiv(// 1. tugma nomi, 2. qiymat, 3. tugma shabloni , 4. bosgandan so'ng manzilga o'tish (ixtiyoriy parametr) Massiv("TITLE" => "Qabul qilish", " VALUE" => "Y", "TYPE" => "qabul qilish" /*, "URL" => " http://test.ru/?confirm=Y" */), Array("TITLE" => "Rad etish", "VALUE" => "N", "TYPE" => "bekor qilish" /*, "URL" " => "http://test.ru/?confirm=N" */), // xat yuborish shablonining ramziy kodi, agar ko'rsatilmagan bo'lsa, u "NOTIFY_EMAIL_TEMPLATE" bildirishnoma shablonida yuboriladi => " CALENDAR_INVITATION"); CIMNotify::Add($arMessageFields); ?>

    Ushbu turdagi bildirishnomalar bilan ishlash uchun shunchaki xabar yuborishning o'zi kifoya emas, siz unga xizmat ko'rsatishingiz ham kerak.

    Xizmat
    Ikkita variant mavjud, eng oddiyi havola bo'yicha (agar siz NOTIFY_BUTTONS da 4-parametrni o'rnatsangiz).
    Havolaga kirganingizdan so'ng kodingizda quyidagi kodni chaqirishingiz kerak:
    Diqqat: teglar nomiga e'tibor bering; o'chirishga qo'ng'iroq qilganingizda, ushbu teg bilan barcha xabarlar o'chiriladi.
    Bir nechta xabarlarni jo'natishda buni hisobga olish kerak, shunda bitta foydalanuvchi tomonidan qilingan harakat tasodifan hamma uchun bildirishnomani o'chirib tashlamaydi (bunday mantiq zarur bo'lgan joylardan tashqari).

    Ikkinchi variant - tadbirlarda.
    1. qaramlikni ro'yxatdan o'tkazishingiz kerak

    Funktsiyalaringiz ichida unutmang ConfirmRequest Va RejectRequest bildirishnomani o'chirishga sabab bo'ladi CIMNotify::DeleteByTag()

    Hozircha hammasi shu, sharhlarda sizning takliflaringizni, muvaffaqiyatli amalga oshirishlaringizni kutaman!
    Agar siz APIni 11.5.2 ni parametrlari bilan massivda chiqarishdan oldin sinab ko'rmoqchi bo'lsangiz, qo'shimcha ravishda "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM ni ko'rsatishingiz kerak, shuningdek tugmalardagi havolali variant tasdiqlash bildirishnomalari uchun ishlamaydi. Ammo kutgan ma'qul; 11.5.2 yangilanishi 23-mayda chiqadi.

    Delirium tremensdan ko'ra yomon chiziq yaxshiroq ...

    PHP AJAX CRUD: MySQL ma'lumotlar bazasida yozuvlarni yaratish, o'chirish, tahrirlash

    Ushbu maqolada biz PHP yordamida MySQL ma'lumotlar bazasiga yozuvlarni qanday qo'shish, tahrirlash va o'chirish haqida bilib olamiz. Biz server tomonidagi skriptga AJAX so'rovini yuboradigan JQuery ishlov beruvchisidan foydalandik. Ishlovchi yozuvlar ro'yxatini yangilaydi.

    Yaratish, o'chirish, tahrirlash uchun so'rovlarni yuborish uchun AJAX shakli

    Yozuv qo'shilganda, shakl AJAX so'rovi orqali ma'lumotlarni PHP skriptiga yuboradi. Agar qo'shish muvaffaqiyatli bo'lsa, yozuvlar ro'yxati qayta yuklanadi.

    CRUD ma'lumotlar bazasi so'rovi uchun JQuery AJAX funktsiyalari

    JQuery AJAX funksiyasida bizda almashtirish holatlari tahrirlash va o'chirish qo'shiladi. Ushbu holatlar ma'lumotlar bazasi harakatlariga qarab turli xil so'rovlar va javoblar ma'lumotlar qatorlarini yaratadi.

    funktsiya showEditBox(id) ( $("#frmAdd").hide(); var currentMessage = $("#message_" + id + ".message-content").html(); var editMarkUp = ""+currentMessage+" SaveCancel"; $("#message_" + id + " .message-content").html(editMarkUp); ) funktsiyasi bekor qilishEditEdit(xabar,id) ( $("#message_" + id + " .message-content") .html(xabar); $("#frmAdd").show(); ) funksiyasi callCrudAction(action,id) ( $("#loaderIcon").show(); var queryString; switch(action) ( case "add" ": queryString = "action="+action+"&txtmessage="+ $("#txtmessage").val(); break; case "edit": queryString = "action="+action+"&message_id="+ id + " &txtmessage="+ $("#txtmessage_"+id).val(); break; case "delete": queryString = "action="+action+"&message_id="+ id; break; ) jQuery.ajax(( url: "crud_action.php", data:queryString, turi: "POST", muvaffaqiyat:function(data)( switch(action) ( case "add": $("#comment-list-box").apppend(ma'lumotlar); break; case "edit": $("#message_" + id + " .message-content").html(ma'lumotlar); $("#frmAdd").show(); sindirish; case "delete": $("#message_"+id).fadeOut(); sindirish; ) $("#txtmessage").val(""); $("#loaderIcon"). hide(); ), xato:funksiya ()() ); )

    CRUD operatsiyalari uchun PHP skripti

    Quyidagi kod ma'lumotlar bazasiga qarshi so'rovlarni amalga oshiradi. Ushbu PHP skripti, CRUD amalini bajargandan so'ng, AJAX javobi natijasida yozuvlarni yangilaydi.

    require_once("dbcontroller.php"); $db_handle = yangi DBController(); $action = $_POST["harakat"]; if(!empty($action)) ( switch($action) ( case "add": $result = mysql_query("INSERT INTO comment(xabar) VALUES("".$_POST["txtmessage"].")") ; if($result)($insert_id = mysql_insert_id(); echo " Edit Delete " . $_POST["txtmessage"] . " "; ) break; case "edit": $result = mysql_query("Yangilanish sharhlar to'plami xabari = "".$_POST["txtmessage"]."" WHERE id=".$_POST["message_id"]); if($result) echo $_POST["txtmessage"]; break; case "delete": if ( !empty($_POST["message_id"])) ( mysql_query("DELETE FROM FROM comment WHERE id=".$_POST["message_id"]); ) break; ) )

    Ushbu kursda bizning plaginimiz poydevori qo'yildi, maxsus kanca aniqlandi va ilgak qanday ishlashini ko'rsatish uchun doimiy xabar ilova qilindi.

    Biz Yo'q qildi, ular xabarlar turlarini va foydalanuvchi tomonidan kiritilgan ma'lumotlarga ko'ra ularni ko'rsatishni amalga oshirmadilar.

    Ammo biz boshlashdan oldin, biz turli xil xabarlar turlarini qo'llab-quvvatlashni, har bir xabar turini qo'llab-quvvatlaydigan sinf interfeysini va bunday xabarlarni saqlash uchun zarur bo'lgan ma'lumotlar strukturasini qo'shishimiz kerak.

    Boshlashga tayyormisiz?

    Men o'quv qo'llanmasini davom ettirishni intiqlik bilan kutyapman, lekin manba kodiga kirishdan oldin bir nechta narsalarni hisobga olishimiz kerak. Tizimingizda quyidagi dasturiy ta'minot o'rnatilganligiga ishonch hosil qiling:

    • PHP 5.6.25 va MySQL 5.6.28
    • Apache yoki Nginx
    • WordPress 4.6.1
    • Siz tanlagan IDE yoki muharrir

    Va agar siz yaxlit yechim izlayotgan bo‘lsangiz, MAMPni sinab ko‘rishni unutmang.

    Biz oldinga chiqdik

    Yuqorida aytib o'tganimizdek, biz aynan shu kursning o'rtasidamiz. Agar siz birinchi darslardan birini o'tkazib yuborgan bo'lsangiz, biz hozirgacha nimalarni ko'rib chiqdik:

  • Birinchi o'quv qo'llanmada biz plaginimizni yaratishning minimal asoslari va boshlash uchun nimaga ega bo'lishingiz kerakligiga e'tibor qaratdik.
  • Ikkinchi qismda biz WordPress-dagi asosiy boshqaruv sahifasiga ozgina qo'shib, plagin bilan yanada ko'proq harakat qildik. Shuningdek, biz foydalanadigan maxsus kancani tayinladik va uni server tomonida ishga tushirdik. Shuningdek, biz Sozlamalar messenjeri uchun asosiy parametrlarni o'rnatdik.
  • Va bu biz treningning yakuniy bosqichida ko'rib chiqamiz:

  • Biz barchasini birlashtiramiz, uni amalda ko'ramiz va plaginni yuklab olish uchun hamma uchun ochiq qilamiz.
  • Ayni paytda oldimizda boshqa vazifalar ham bor va biz ularga e'tibor qaratamiz.

    Keling, ishga qaytaylik

    Biz ishga kirishganimiz uchun (va oldingi darslarda aytib o'tilganidek), biz ushbu qismdagi vazifalarni yanada bajarishga intilamiz:

    Ushbu qo'llanmada biz muvaffaqiyat va muvaffaqiyatsizlik xabarlarini qo'llab-quvvatlash, shuningdek, xavfsizlik masalalariga to'xtalib o'tish orqali Sozlamalar messenjerimizni rivojlantirishni davom ettiramiz.

    Oldingi maqolada biz Sozlamalar Messenger-da ishlay boshladik, lekin faqat foydalanuvchi sahifasi yuklanayotganda muvaffaqiyat haqida bildirishnomani doimiy ravishda ko'rsatadigan xususiyatni sozlash nuqtasiga qadar.

    Ushbu qo'llanmada biz xato, ogohlantirish va muvaffaqiyat xabarlarini qo'llab-quvvatlaymiz. Keyin messenjer qanday ishlashi haqida tasavvurga ega bo'lish uchun ularni ekranda ko'rsatamiz.

    Bundan tashqari, biz foydalanuvchining ixtiyoriga ko'ra bildirishnomalarni o'chirishni qo'llab-quvvatlaydigan yana bir o'zgartirish kiritmoqchimiz.

    Bu ushbu dars uchun zarur ishning to'liq rejasi. Boshlaylik.

    Sozlamalar Messenger kengaytmasi

    Esda tutingki, Sozlamalar Messenger dasturining maqsadi WordPress boshqaruv paneli kontekstida xabarlarni ko'rsatish uchun maxsus xabarlar, maxsus ilgaklar va mahalliy WordPress API bilan ishlash uslubimizni aniqlashdir.

    Buning uchun biz oxirgi darsda bajarilgan ishlarni kengaytiramiz va shu yerdan boshlaymiz.

    Muvaffaqiyatli xabarlar

    Oldingi darsda muvaffaqiyatli xabarlar bilan boshlaganimiz uchun, keling, ularni davom ettiramiz. Endi bizda bitta texnikani ko'rsatadigan qattiq kodlangan usul mavjud: