PHPda global o'zgaruvchilar. Php oʻzgaruvchan koʻrinish doirasi funksiyalardagi oʻzgaruvchan koʻrinish

Oxirgi yangilanish: 11/1/2015

O'zgaruvchilar va funktsiyalardan foydalanganda, o'zgaruvchilar doirasini hisobga oling. Qo'llanish doirasi berilgan o'zgaruvchining amal qilish doirasini va foydalanish imkoniyatini belgilaydi.

Mahalliy o'zgaruvchilar

Mahalliy o'zgaruvchilar funktsiya ichida yaratiladi. Bunday o'zgaruvchilarga faqat berilgan funksiya ichidan kirish mumkin. Masalan:

Bu holda get() funksiyasi $result mahalliy o'zgaruvchisini belgilaydi. Va umumiy kontekstdan biz unga kira olmaymiz, ya'ni $a = $result yozing; Bu mumkin emas, chunki $result oʻzgaruvchisining qamrovi get() funksiyasi bilan cheklangan. Bu funksiyadan tashqarida $result oʻzgaruvchisi mavjud emas.

Xuddi shu narsa funksiya parametrlariga ham tegishli: funktsiyadan tashqarida $lowlimit va $highlimit parametrlari ham mavjud emas.

Qoidaga ko'ra, mahalliy o'zgaruvchilar yuqoridagi misoldagi kabi hisob-kitoblarning ba'zi oraliq natijalarini saqlaydi.

Statik o'zgaruvchilar

Statik o'zgaruvchilar mahalliy o'zgaruvchilarga o'xshash. Ularning farqi shundaki, funktsiya bajarilgandan so'ng ularning qiymati saqlanadi. Funktsiya har safar chaqirilganda, u avval saqlangan qiymatdan foydalanadi. Masalan:

O'zgaruvchining statik bo'lishini ko'rsatish uchun unga static kalit so'zi qo'shiladi. getCounter() ga uchta ketma-ket qo'ng'iroqlar bilan $counter o'zgaruvchisi bittaga oshiriladi.

Agar $counter o'zgaruvchisi oddiy statik bo'lmagan o'zgaruvchi bo'lsa, getCounter() har safar chaqirilganda 1 ni chop etadi.

Odatda, statik o'zgaruvchilar yuqoridagi misoldagi kabi turli xil hisoblagichlarni yaratish uchun ishlatiladi.

Global o'zgaruvchilar

Ba'zan siz o'zgaruvchining hamma joyda, global miqyosda mavjud bo'lishini xohlaysiz. Bunday o'zgaruvchilar butun dastur uchun umumiy bo'lgan ba'zi ma'lumotlarni saqlashi mumkin. Global o'zgaruvchilarni aniqlash uchun global kalit so'zdan foydalaning:1

"; ) getGlobal(); echo $gvar; ?>

getGlobal() funksiyasini chaqirgandan so'ng, $gvar o'zgaruvchisiga dasturning istalgan qismidan kirish mumkin.

O'zgaruvchan doira bu o'zgaruvchi aniqlangan kontekstdir. Ko'pgina PHP o'zgaruvchilari bitta qamrovga ega. Ushbu yagona qamrov (shuningdek, global miqyos deb ataladi) kiritilgan fayllarni ham qamrab oladi:

Ushbu misolda $a o'zgaruvchisi kiritilgan skript ichida ham mavjud bo'ladi - main.inc .

Mahalliy o'zgaruvchilar

Maxsus funktsiya ta'rifi belgilaydi mahalliy qamrov o'zgaruvchi uchun, ya'ni. Funktsiya ichida ishlatiladigan har qanday o'zgaruvchi sukut bo'yicha funktsiyaning mahalliy doirasi bilan chegaralanadi (faqat u aniqlangan funktsiya ichida mavjud). U qanday ishlaydi: Umumiy kodda ishlatiladigan o'zgaruvchilarni funktsiyalarda ishlatiladigan o'zgaruvchilardan ajratish uchun PHP har bir funktsiya ichidagi o'zgaruvchilar uchun alohida saqlashni ta'minlaydi. Saqlash maydonining bunday bo'linishi ko'lami, ya'ni o'zgaruvchining qiymati mavjud bo'lgan hudud funktsiyaning mahalliy xotirasi ekanligini anglatadi.

Quyidagi misol funktsiyadan tashqarida e'lon qilingan o'zgaruvchining funksiya ichida o'zgarmasligini aniq ko'rsatib turibdi. Funktsiya qanday ishlashini tushunishga urinmasligingiz kerak bo'lsa-da, asosiysi uning o'ziga xos o'zgaruvchilar to'plami bor:

30 ?>

Ushbu fragmentni bajarish natijasida quyidagilar ko'rsatiladi: 30.

Birth() funktsiyasi ichida $age o'zgaruvchisi 1 ga o'rnatiladi, lekin bu global miqyosda belgilangan o'zgaruvchiga o'xshamaydi. Shuning uchun, $age o'zgaruvchisining qiymati chop etilganda, 30 ning asl qiymati chop etiladi.Shuni ta'kidlash joizki, mahalliy o'zgaruvchilar funktsiya chaqirilgan paytda yaratiladi va funktsiya tugagandan so'ng o'chiriladi.

Agar siz global o'zgaruvchining qiymatini (global miqyosda qo'llaniladigan o'zgaruvchilar chaqirilganidek) birth() funksiyasidagi mahalliy emas, balki o'qish yoki o'zgartirishni xohlasangiz, u funktsiya ta'rifi doirasida global deb e'lon qilinishi kerak.

Eslatma: Saytning moslashtirilgan versiyasi faollashtirildi, u avtomatik ravishda brauzeringizning kichik hajmiga moslashadi va o'qish qulayligi uchun saytning ba'zi tafsilotlarini yashiradi. Tomosha qilishdan zavqlaning!

Salom aziz blog o'quvchilari Sayt yoqilgan! Biz PHPda funksiya mavjudligini bilib oldik, biz o'z funksiyalarimizni yaratishni, ularga argumentlar berishni va ularni bajarishga chaqirishni o'rgandik. PHP-da funksiyalar mavzusini davom ettirib, quyidagi narsalarni ta'kidlash kerak:

  • Funksiya ichida siz istalgan PHP kodidan (davrlar, shartlar, har qanday operatsiyalar), shu jumladan boshqa funktsiyalardan (ham o'rnatilgan, ham moslashtirilgan) foydalanishingiz mumkin;
  • Funktsiya nomi lotin harfi yoki pastki chiziq bilan boshlanishi kerak, undan keyin lotin harflari, raqamlar yoki pastki chiziqning istalgan soni qo'yilishi kerak;
  • Barcha funktsiyalar global qamrovga ega, ya'ni har qanday funktsiyani istalgan joyda chaqirish mumkin, hatto bu funktsiya boshqasining ichida aniqlangan bo'lsa ham;
  • PHP funksiyani haddan tashqari yuklashni qo'llab-quvvatlamaydi, shuningdek yaratilgan funktsiyani qayta aniqlash (o'zgartirish, qo'shish) yoki o'chirish imkoniyati yo'q;
  • Funktsiyalarni ishlatishdan oldin ularni aniqlash shart emas. Ya'ni, agar siz avval funktsiyani chaqirsangiz va uni quyidagi kodda tasvirlab bersangiz, bu ishlashga ta'sir qilmaydi va xatolarga olib kelmaydi.

Shartli funksiyalar

Biz shartga qarab funksiya yaratishimiz (aniqlashimiz, tavsiflashimiz) mumkin. Masalan:

//funksiya sayHi deb ataladi, uni istalgan joyda chaqirish mumkin /*sayGoodbye funksiyasini bu yerda chaqirib bo‘lmaydi, chunki biz hali shartni tekshirmadik va if konstruksiyasiga kirmadik*/ if($apply)( sayGoodbye())( echo "Hammaga xayr!
"; } } /*endi biz goodbye deb qo'ng'iroq qilishimiz mumkin*/
"; }

Natija:

Va bu misolni ko'rib chiqing:

/*va agar siz bu yerda deyishga xayrlashsangiz shunday bo'ladi*/ Alvido(); if($apply)( sayGoodbye())( echo "Hammaga xayr!
"; ) ) funksiya sayHi())( echo "Hammaga salom!
"; }

Natija:

Darhaqiqat, men qancha ishlagan bo'lsam ham, men hech qaerda bunday narsalarni ko'rmaganman, lekin siz tilning barcha imkoniyatlarini yodda tutishingiz kerak.

Ichki funksiyalar

Ichki funktsiya boshqa funktsiya ichida e'lon qilingan funktsiyadir. Misol:

/*Siz bu yerda sayGoodbye ga qo‘ng‘iroq qila olmaysiz, chunki u sayHi funksiyasini chaqirgandan keyingina paydo bo‘ladi*/ sayHi(); /*sayHi funksiyasini chaqiring, uni istalgan joyda chaqirish mumkin*/ /*Endi biz deyishga qo'ng'iroq qilishimiz mumkin*/ Alvido(); funksiya sayHi())( echo "Hammaga salom!
"; funksiya sayGoodbye())( echo "Hammaga xayr!
"; } }

Shunga qaramay, birinchi o'tishda PHP tarjimoni sayHi funksiyasining tavsifini topganligini belgilaydi, lekin uning tanasiga kirmaydi, u faqat nomni ko'radi va tarjimon sayHi tanasiga kirmagani uchun, u holda biz boshqa funktsiya ichida nimani aniqlayotganimizni bilmaydi - sayGoodbye.

Keyin kod bajarila boshlaydi, biz sayHi deb chaqiramiz, PHP tarjimoni uni bajarish uchun sayHi funksiyasining tanasiga kirishi kerak va u yerda tasodifan boshqa funksiya tavsifini topadi - sayGoodbye, shundan so'ng sayGoodbye ni istalgan joyda, shuncha marta chaqirish mumkin. qanday istasangiz.

Lekin yuqoridagi vaziyatda juda nozik jihatga e'tibor qaratish o'rinlidir: sayHi funksiyasi bir martalik bo'ladi, chunki agar uni yana chaqirsak, PHP yana sayGoodbye funksiyasining ta'rifiga duch keladi va PHPda buni qilolmaysiz. bu - siz funktsiyalarni bekor qila olmaysiz. Men bu haqda va u bilan qanday kurashish haqida oldingi maqolada yozgan edim.

PHP-da yuqorida tavsiflangan usullar juda kam qo'llaniladi, ularni tez-tez ko'rish mumkin, masalan, JavaScript-da.

O'zgaruvchan doira

PHPda ikkita skop mavjud: global Va mahalliy. Har bir dasturlash tili tuzilmalarining qamrovi har xil. Misol uchun, C++ tilida hatto tsikllar ham o'z (mahalliy) doirasiga ega. Aytgancha, PHPda bu global qamrovdir. Ammo bugun biz funktsiyalar haqida gapiramiz.

PHP dagi funksiyalar o zining ichki qamroviga (lokal) ega, ya ni funksiya ichidagi barcha o zgaruvchilar faqat shu funksiya ichida ko rinadi.

Shunday qilib, yana bir bor: funktsiyalardan tashqaridagi hamma narsa global miqyosdir, funktsiyalar ichidagi hamma narsa mahalliy doiradir. Misol:

Hurmatli mutaxassislar, diqqat, savol! Oxirgi ko'rsatma qanday natija beradi? echo $name; ?

O'zingiz ko'rganingizdek, bizda 2 ta o'zgaruvchi bor edi $name, biri funktsiya ichida (mahalliy qamrov), ikkinchisi faqat kodda (global qamrov), o'zgaruvchiga oxirgi tayinlash $name edi $name = "Rud Sergey"; Ammo u funktsiya ichida bo'lgani uchun u o'sha erda qoldi. Global miqyosda oxirgi topshiriq bo'ldi $name = "Andrey"; bu biz aslida natija sifatida ko'rmoqdamiz.

Ya'ni, ikkita bir xil o'zgaruvchilar, lekin turli sohalarda ular kesishmaydi va bir-biriga ta'sir qilmaydi.

Keling, rasmda qamrovni ko'rsataman:

Birinchi o'tish paytida tarjimon global qamrovni qisqacha skanerlaydi, qanday o'zgaruvchilar va funktsiyalar borligini eslaydi, lekin kodni bajarmaydi.

Mahalliy miqyosdan global o'zgaruvchilarga kirish

Ammo biz hali ham global miqyosdagi bir xil $name o'zgaruvchisiga funktsiyadan kirishimiz kerak bo'lsa va shunchaki unga kirish emas, balki uni o'zgartirishimiz kerak bo'lsa-chi? Buning uchun 3 ta asosiy variant mavjud. Birinchisi, kalit so'zdan foydalanish global:

"; global $name; /*bundan buyon biz global o‘zgaruvchini nazarda tutamiz $name*/$name = "Rud Sergey"; ) $name = "Andrey"; aytHi($name); echo $name; // ?

Natija:

Ammo bu usulning kamchiligi bor, chunki biz global o'zgaruvchiga kirdik $name biz mahalliy o'zgaruvchini yo'qotdik (ustiga yozdik). $name.

Ikkinchi yo'l foydalanishdan iborat PHP superglobal massivi. PHP o'zi biz global miqyosda yaratgan har bir o'zgaruvchini avtomatik ravishda ushbu massivga joylashtiradi. Misol:

$name = "Andrey"; // Xuddi shunday$GLOBALS["name"] = "Andrey";

Demak:

"; $GLOBALS["name"] = "Rud Sergey"; ) $name = "Andrey"; sayHi($name); echo $name; // ?

Natija kalit so'zni ishlatish bilan bir xil bo'ladi global:

Faqat bu safar biz mahalliy o'zgaruvchini, ya'ni o'zgaruvchini qayta yozmadik $name funktsiya ichida bir xil bo'lib qoladi va teng bo'ladi "Andrey", lekin emas "Rud Sergey".

Argumentlarni mos yozuvlar bo'yicha uzatish

Uchinchi yo'l- bu manzilni uzatish ( havolalar) o'zgaruvchining qiymati emas, balki. PHPdagi havolalar boshqa dasturlash tillaridan farqli ravishda unchalik muvaffaqiyatli emas. Biroq, men sizga odatda PHP 5.3 va undan yuqori versiyalarida qo'llab-quvvatlanadigan funktsiyaga murojaat qilish orqali argumentni uzatishning yagona to'g'ri variantini aytib beraman. Havolalar bilan ishlashning boshqa usullari ham bor, lekin ular PHP 5.2 va undan pastroq versiyalarda ishlagan, natijada PHP ishlab chiquvchilari ulardan voz kechishga qaror qilishgan, shuning uchun biz ular haqida gapirmaymiz.

Shunday qilib, PHP 5.3 va undan yuqori versiyalarda argumentning TO'G'RI topshirilishi quyidagicha amalga oshiriladi:

Funktsiya sayHi(& $name)(

Funktsiya tavsifining o'zida biz ampersand (&) belgisini qo'shdik - bu belgi biz o'zgaruvchining qiymatini qabul qilmasligimizni anglatadi, lekin xotiradagi ushbu qiymatga havola (manzil). PHP-dagi havolalar bir xil qiymatga ishora qiluvchi ikkita o'zgaruvchini yaratishga imkon beradi. Bu shuni anglatadiki, ushbu o'zgaruvchilardan biri o'zgarganda, ikkalasi ham o'zgaradi, chunki ular xotirada bir xil qiymatga ishora qiladi.

Va oxirida bizda:

//qiymatni emas, balki qiymatga havolani qabul qiling echo "Salom, ".$name."!
"; $name = "Rud Sergey"; ) $name = "Andrey"; sayHi($name); echo $name; // ?

Natija:

Statik o'zgaruvchilar

Quyidagi vaziyatni tasavvur qiling: jami necha marta salom berganimizni hisoblashimiz kerak. Mana biz nima qilmoqchimiz:

"; $c++; // hisoblagichni 1 ga oshiring


Natija:

O'zgaruvchan $c uning ma'nosini eslamaydi, har safar yangidan yaratiladi. Biz mahalliy o'zgaruvchimizni yaratishimiz kerak $c funktsiyani bajargandan so'ng uning qiymatini esladilar, buning uchun ular kalit so'zdan foydalanadilar statik:

// hisoblagich, statik qilingan echo "Salom, ".$name."!
"; $c++; // hisoblagichni 1 ga oshiring echo "Shunchaki salom aytdim". $c . " bir marta.


"; ) sayHi("Rud Sergey"); sayHi("Andrey"); sayHi("Dmitriy");

Natija:

Qaytariladigan qiymatlar

Funktsiyalar qiymatlarni qaytarish kabi qulay narsaga ega. Bu funksiya ekranga biror narsani chop etish o'rniga hamma narsani o'zgaruvchiga qo'yadi va bu o'zgaruvchini bizga beradi. Va biz u bilan nima qilishni allaqachon hal qilyapmiz. Masalan, ushbu funktsiyani olaylik, u raqamni kvadratga aylantiradi:

Natija:

Keling, uni ekranda ko'rsatish o'rniga, bajarilish natijasini qaytaradigan qilib yarataylik. Buning uchun return kalit so'zidan foydalaning:

Natija:

Endi biz buni turli yo'llar bilan ishlatishimiz mumkin:

// natijani chiqaradi aks-sado "
"; $num = getSquare(5); echo $num;

Natija:

E'tibor bering, kalit so'z qaytish shunchaki qiymat qaytarmaydi, balki funktsiyani, ya'ni kalit so'z ostidagi barcha kodlarni to'liq to'xtatadi qaytish hech qachon bajarilmaydi. Boshqacha qilib aytadigan bo'lsak, funksiyalarni qaytarish ham shunga o'xshash ishlaydi tanaffus looplar uchun:

echo "PHP hech qachon menga etib bormaydi:(";) echo getSquare(5); // natijani chiqaradi aks-sado "
"; $num = getSquare(5); // natijani o'zgaruvchiga tayinladi echo $num; // o'zgaruvchini ekranda ko'rsatish

Natija:

Ya'ni qaytish– bu ham funksiyadan chiqish. Uni qaytarish qiymatisiz, faqat chiqish uchun ishlatish mumkin.

Rekursiv funksiya

Rekursiv funktsiya o'zini chaqiradigan funktsiyadir. Rekursiya tez-tez ishlatilmaydi va resurs talab qiladigan (sekin) operatsiya hisoblanadi. Ammo shunday bo'ladiki, rekursiyadan foydalanish eng aniq va oddiy variantdir. Misol:

"; agar ($ raqam< 20){ // rekursiya cheksiz bo'lib qolmasligi uchun countPlease(++$raqam); // countPlease funktsiyasi o'zini chaqirdi) ) countPlease(1);

Natija:

Agar siz rekursiyasiz qanday qilishni bilsangiz, unda buni qilish yaxshidir.

PHPda kuchli yozish (turni yaxshilash)

PHP kuchli matn terish uchun kichik qadamlar qo'yadi, shuning uchun biz qanday funktsiyani olish kerakligini oldindan belgilashimiz mumkin (bu deyiladi) turiga ishora):

Natija:

Tushunarli xato: countPlease() ga uzatilgan 1-argument 7-qatorda /home/index.php da chaqirilgan va 3-qatorda /home/index.php da belgilangan butun son berilgan massiv boʻlishi kerak.

Xato bizga funktsiya massivni olishni kutayotganini aytadi, lekin buning o'rniga biz unga raqamni uzatamiz. Afsuski, hozircha biz faqat (massiv) turini belgilashimiz mumkin va PHP 5.4 bilan biz ham shunday variantni qo'shdik. chaqirish mumkin:

Qo'ng'iroq qilish mumkin berilgan qiymatni funksiya sifatida chaqirish mumkinligini tekshiradi. Chaqiriladigan yoki satr o'zgaruvchisi tomonidan ko'rsatilgan funksiya nomi yoki ob'ekt va chaqirilayotgan usulning nomi bo'lishi mumkin. Ammo biz ob'ektlar va usullar haqida keyinroq gaplashamiz (bu ob'ektga yo'naltirilgan dasturlash bo'limi), lekin siz allaqachon funktsiyalar bilan tanishsiz. Men sizga ish natijasini ko'rsata olmayman, chunki menda hozirda PHP 5.3 bor, lekin shunday bo'lardi:

getEcho funksiyasi deb ataladi

O'zgaruvchan uzunlikdagi argumentlardan foydalanish

Va nihoyat, yana bir kamdan-kam ishlatiladigan nuance. Vaziyatni tasavvur qiling: biz funktsiyaga argumentlarni o'tkazamiz, garchi biz ularni funktsiyada tasvirlamagan bo'lsak ham, masalan:

Natija:

Ko'rib turganingizdek, hech qanday xatolik yo'q, lekin bizning o'tgan argumentlarimiz hech qaerda ishlatilmaydi. Ammo bu ularning yo'qligini anglatmaydi - ular hali ham funktsiyaga o'tgan va biz ulardan foydalanishimiz mumkin; buning uchun o'rnatilgan PHP funktsiyalari mavjud:

func_num_args()- Funksiyaga uzatilgan argumentlar sonini qaytaradi
func_get_arg(tartib raqami)- Argumentlar ro'yxatidan elementni qaytaradi
func_get_args()- Funktsiya argumentlarini o'z ichiga olgan massivni qaytaradi

"; echo func_get_arg(0) ; ) $age = 22; getEcho("Rud Sergey", $age);

Natija:

Xulosa

Bugungi maqola PHP dagi funksiyalar mavzusidagi yakuniy maqoladir. Endi siz ushbu mavzu bo'yicha bilimlaringizning to'liqligiga ishonchingiz komil bo'lishi mumkin va o'zingizning ehtiyojlaringiz uchun funktsiyalardan ishonch bilan foydalanishingiz mumkin.

Agar kimdir bu borada yaxshilanishni xohlasa-yu, lekin buni qanday qilishni bilmasa, eng yaxshi yo'l tayyor (o'rnatilgan) PHP funktsiyalarini yozish bo'ladi, masalan, siz o'zingizning count() funksiyangizni yozishingiz mumkin. yoki boshqa.

E'tiboringiz uchun barchangizga rahmat va yana ko'rishguncha! Agar biror narsa tushunarsiz bo'lsa, sharhlarda savollaringizni berishingiz mumkin!

O'zgaruvchining qamrovi bu o'zgaruvchi aniqlangan kontekstdir. Ko'pgina hollarda, barcha PHP o'zgaruvchilari faqat bitta qamrovga ega. Ushbu yagona qamrov, shuningdek, kiritilgan va kerakli fayllarni ham qamrab oladi. Masalan:

$a = 1;
"b.inc" ni o'z ichiga oladi;
?>

Bu erda $a o'zgaruvchisi kiritilgan b.inc skriptida mavjud bo'ladi. Biroq, foydalanuvchi tomonidan belgilangan funktsiyaning ta'rifi (tanasi) ushbu funktsiyaning mahalliy doirasini belgilaydi. Funktsiyada ishlatiladigan har qanday o'zgaruvchi sukut bo'yicha funktsiyaning mahalliy doirasi bilan cheklangan. Masalan:

$a = 1; /* global qamrov */

Funktsiya testi ()
{
echo $a ; /* mahalliy oʻzgaruvchiga havola */
}

Test();
?>

Bu skript hech qanday natija yaratmaydi, chunki echo bayonoti $a oʻzgaruvchisining mahalliy versiyasiga ishora qiladi va unga shu doirada qiymat berilmagan. Siz buni C dan bir oz farq qilishini payqagandirsiz, chunki C dagi global o'zgaruvchilar, agar ular mahalliy ta'rif bilan qayta yozilmagan bo'lsa, avtomatik ravishda funksiyalar uchun mavjud bo'ladi. Bu ba'zi muammolarni keltirib chiqarishi mumkin, chunki odamlar tasodifan global o'zgaruvchini o'zgartirishi mumkin. PHP da, agar global o'zgaruvchi funktsiya ichida ishlatilishi kerak bo'lsa, u funktsiya ta'rifi doirasida global deb e'lon qilinishi kerak.

Kalit so'z global

Avval foydalanish misoli global:

1-misol foydalanish global

$a = 1;
$b = 2;

Sum() funksiyasi
{
global $a, $b;

$b = $a + $b ;
}

Sum();
echo $b ;
?>

Yuqoridagi skript chiqadi 3 . Agar $a va $b funktsiya ichida global sifatida aniqlansa, ushbu o'zgaruvchilarning har qandayiga barcha havolalar ularning global versiyasiga ishora qiladi. Funktsiya boshqara oladigan global o'zgaruvchilar soniga cheklov yo'q.

Global miqyos o'zgaruvchilariga kirishning ikkinchi usuli PHP tomonidan aniqlangan maxsus $GLOBALS massividan foydalanishdir. Oldingi misolni quyidagicha qayta yozish mumkin:

$GLOBALS assotsiativ massiv boʻlib, uning kaliti nomi va qiymati global oʻzgaruvchining mazmuni hisoblanadi. $GLOBALS har qanday miqyosda mavjudligini unutmang, buning sababi $GLOBALS superglobal. Quyida supergloballarning imkoniyatlarini ko'rsatadigan misol keltirilgan:

3-misol Supergloballar va qamrov

test_global() funktsiyasi
{
// Ko'pchilik oldindan belgilangan o'zgaruvchilar emas
// "super" va mahalliy hududda mavjud bo'lishi
// ko'rinish, funktsiyalar "global" ni ko'rsatishni talab qiladi.
global $HTTP_POST_VARS ;

Echo $HTTP_POST_VARS["name"];

// Supergloballar har qanday miqyosda mavjud
// ko'rinish va "global" ko'rsatilishini talab qilmaydi.
// Supergloballar PHP 4.1.0 dan beri mavjud va
// HTTP_POST_VARS dan foydalanish eskirgan.
echo $_POST ["ism" ];
}
?>

Izoh:

Kalit so'zdan foydalanish global funktsiyadan tashqarida xato emas. U funktsiya ichiga kiritilgan faylda ishlatilishi mumkin.

Statikdan foydalanish ( statik) o'zgaruvchilar

O'zgaruvchan doiraning yana bir muhim xususiyati statik o'zgaruvchan. Statik o'zgaruvchi faqat funktsiyaning mahalliy doirasida mavjud bo'ladi, lekin dastur bajarilishi ushbu doirani tark etganda o'z qiymatini yo'qotmaydi. Quyidagi misolni ko'rib chiqing:

4-misol Statik o'zgaruvchilarga bo'lgan ehtiyojni ko'rsatish

funktsiya testi()
{
$a = 0 ;
echo $a ;
$a++;
}
?>

Bu funksiya juda foydasiz, chunki u har safar chaqirilganda $a ga o'rnatiladi 0 va chiqishlar 0 . $a ++ o'zgaruvchisining o'sishi bu erda rol o'ynamaydi, chunki $a o'zgaruvchisi funktsiyadan chiqqanda yo'qoladi. Joriy hisoblagich qiymatini yo'qotmaydigan foydali hisoblash funksiyasini yozish uchun $a o'zgaruvchisi statik deb e'lon qilinadi:

5-misol Statik o'zgaruvchilardan foydalanishga misol

funktsiya testi()
{
statik $a = 0 ;
echo $a ;
$a++;
}
?>

Endi $a faqat birinchi funktsiya chaqiruvida va har bir funktsiya chaqiruvida ishga tushiriladi test()$a qiymatini chop etadi va uni oshiradi.

Statik o'zgaruvchilar rekursiv funktsiyalar bilan ishlashga ham imkon beradi. Rekursiv funktsiya o'zini chaqiradigan funktsiyadir. Rekursiv funktsiyani yozishda ehtiyot bo'lish kerak, chunki rekursiyani cheksiz qilish imkoniyati mavjud. Rekursiyani to'xtatish uchun mos usul mavjudligiga ishonch hosil qilishingiz kerak. Quyidagi oddiy funksiya qachon toʻxtash kerakligini aniqlash uchun $count statik oʻzgaruvchisidan foydalanib, rekursiv ravishda 10 tagacha hisoblanadi:

Izoh:

Statik o'zgaruvchilar oldingi misolda ko'rsatilganidek e'lon qilinishi mumkin. Ifodalar natijasi bo'lgan ushbu o'zgaruvchilarga qiymatlarni belgilashga urinish ishlov berish xatosiga olib keladi.

7-misol Statik o'zgaruvchilarni e'lon qilish

foo funktsiyasi ()(
statik $int = 0 ; // o'ng
statik $int = 1 + 2 ; // noto'g'ri (chunki bu ifoda)
statik $int = sqrt(121); // noto'g'ri (chunki bu ham ifoda)

$int++;
echo $int;
}
?>

Izoh:

Statik deklaratsiyalar skriptni kompilyatsiya qilish jarayonida baholanadi.

Global bilan havolalar ( global) va statik ( statik) o'zgaruvchilar

PHP 4-ni quvvatlaydigan Zend Engine 1 statik va global o'zgaruvchilarni mos yozuvlar sifatida ko'rib chiqadi. Masalan, kalit so'zni ko'rsatish orqali funktsiya doirasiga kiritilgan haqiqiy global o'zgaruvchi global, amalda global o'zgaruvchiga havola yaratadi. Bu quyidagi misolda ko'rsatilganidek, kutilmagan xatti-harakatlarga olib kelishi mumkin:

test_global_ref() funksiyasi (
global $obj ;
$obj = &yangi stdclass ;
}

test_global_noref() funksiyasi (
global $obj ;
$obj = yangi stdclass ;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);
?>

Ushbu misolni ishga tushirish natijasi: get_instance_noref () (
statik $obj ;

Echo "Statik ob'ekt:";
var_dump($obj);
agar (!isset($obj )) (
// Ob'ektni statik o'zgaruvchiga tayinlash
$obj = yangi stdclass ;
}
$obj -> mulk++;
$obj ni qaytarish;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n" ;
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();
?>

Ushbu misolni ishga tushirish natijasi:

Statik ob'ekt: NULL
Statik ob'ekt: NULL

Statik ob'ekt: NULL
Statik ob'ekt: ob'ekt (stdClass) (1) (
["mulk"]=>
int(1)
}

Ushbu misol shuni ko'rsatadiki, siz statik o'zgaruvchiga havolani tayinlaganingizda, u emas esda qolarli funktsiyani chaqirganingizda &get_instance_ref() ikkinchi marta.

Ko'p funktsiyalarga ega to'liq veb-sayt yaratish uchun siz ko'p narsalarni bilishingiz kerak. Biroq, PHP saytga haqiqiy o'ziga xoslikni berishi mumkin. Global o'zgaruvchi bu dasturlash tilida tez-tez ishlatilmaydi, lekin ba'zida uning qanday ishlashini bilish juda foydali.


Ushbu maqolada biz global o'zgaruvchi nima ekanligini va u qanday ishlashini aniq o'rganamiz.

Global o'zgaruvchi: qamrov

O'zgaruvchi aniqlangan kontekst uning doirasi deyiladi. Odatda, o'zgaruvchilar faqat bitta qamrovga ega. PHP-dagi global o'zgaruvchilar boshqa fayllardan yuklanganda, ular talab qilinishi yoki kiritilishi mumkin. Ular sukut bo'yicha funktsiyaning mahalliy doirasi bilan cheklangan. Qanday qilib o'zgaruvchini uning chegarasidan tashqaridagi fayllarga ko'rinadigan qilish va undan foydalanish imkoniyatiga ega bo'lish mumkin? Aynan shuning uchun PHP global o'zgaruvchini taqdim etadi. Bu erda asosiy so'z "global". PHP da global o'zgaruvchini qanday e'lon qilish mumkin? Ushbu maqsadga erishish uchun "global" so'zidan foydalanish kerak. U global qilmoqchi bo'lgan o'zgaruvchidan oldin darhol joylashtirilishi kerak. Bu shunday ko'rinadi: global "O'zgaruvchan". Ushbu turdagi ko'rsatmalarni amalga oshirgandan so'ng, mutlaqo har qanday fayl ma'lumotlar bilan ishlay oladi.

Agar biror joyda ushbu o'zgaruvchiga havolalar mavjud bo'lsa, dastur global versiyaga e'tibor beradi. Nega bunday g'alati so'zlar ishlatilgan? Gap shundaki, ayni paytda mahalliy versiyalar ham mavjud bo'lishi mumkin. Lekin ular faqat ular e'lon qilingan fayllarda ko'proq foydalanish mumkin bo'ladi. Qolganlari uchun global PHP sinf o'zgaruvchilari qo'llaniladi. Bu erda siz juda ehtiyotkorlik bilan va ehtiyotkorlik bilan harakat qilishingiz kerak. Shubhalarning oldini olish uchun ularning qanday ko'rinishiga oddiy misol keltiramiz: global a. Agar bitta fayl bir nechta o'zgaruvchilarga kirish huquqiga ega bo'lsa, bu ziddiyatga olib kelishi mumkin. Ammo bu erda global yoki mahalliy o'zgaruvchi o'qiladimi yoki xatolik yuz beradimi, buni aniq aytish mumkin emas. Agar siz uni funktsiya ichiga yozsangiz, hech qanday muammo yuzaga kelmasligi kerak. Funktsiya chegaralaridan tashqarida o'zgaruvchidan foydalanish muammoli bo'ladi. Shuning uchun siz kodning tuzilishini diqqat bilan kuzatib borishingiz va hech qanday joyda nizo uchun shartlar yo'qligiga ishonch hosil qilishingiz kerak.

Global o'zgaruvchilar: boshqa belgi
Global o'zgaruvchilarni o'rnatishning boshqa usullari bormi? Ha, va yolg'iz emas. Keling, avval $GLOBALS ni ko'rib chiqaylik. Bu kalit nomi bo'lgan assotsiativ massivdir. Qiymat sifatida global o'zgaruvchining mazmuni ishlatiladi. Shuni ta'kidlash kerakki, deklaratsiyadan keyin bu massiv har qanday miqyosda mavjud. Bu uni superglobal deb hisoblashga asos beradi. Bu shunday ko'rinadi: $GLOBALS ['O'zgaruvchi'].

Supergloballar
Har qanday dasturlash tilida alohida funktsiyalar uchun ajratilgan nomlar mavjud. PHPda bir xil nomdagi global o'zgaruvchilarni yaratish shunchaki mumkin emas. Ushbu dasturlash tili o'ziga xos xususiyatlarga ega. Masalan, oldindan belgilangan o'zgaruvchilarda "super" prefiksi yo'qligi ayniqsa muhimdir. Bu shuni anglatadiki, ular hamma joylarda mavjud emas. Bu vaziyatni qanday tuzatish mumkin? Ba'zi bir mahalliy tarmoqda oldindan belgilangan o'zgaruvchini mavjud qilish uchun siz uni shunday e'lon qilishingiz kerak: global "o'zgaruvchi". Bu haqda allaqachon aytib o'tilgan. Biroq, bu mutlaqo to'g'ri emas. Haqiqiy misolni ko'rib chiqaylik:
Global $HTTP_POST_VARS; echo $HTTP_POST_VARS ['nom'].
Farqni his qilyapsizmi? Shuni yodda tutish kerakki, PHPda global o'zgaruvchi funktsiya ichida ishlatilishi kerak. Shuningdek, u unga kiritilgan faylda joylashgan bo'lishi mumkin.

Xavfsizlik va havolalar
O'zingiz ko'rib turganingizdek, PHPda global o'zgaruvchini yaratish muammo emas. Lekin havolalar bilan bog'liq har qanday aniqliklar bormi? Global o'zgaruvchilardan foydalanilganda, ba'zi kutilmagan xatti-harakatlar mumkin. Ammo bu masalani batafsil o'rganishdan oldin, fonga murojaat qilish kerak. Register_globals direktivasi 4.2 versiyasida sukut bo'yicha yoqilgandan o'chirilganga o'zgartirildi. Ko'pgina foydalanuvchilar uchun bu mutlaqo ahamiyatsiz va behuda, chunki ishlab chiqilayotgan mahsulotning xavfsizligi bevosita unga bog'liq. Agar siz global o'zgaruvchini yaratishingiz kerak bo'lsa, PHP direktivasi ushbu sozlamaga bevosita ta'sir qilmaydi. Biroq, noto'g'ri foydalanish xavfsizlik xavfiga aylanishi mumkin. Masalan, agar register_globals yoqilgan holatda bo'lsa, kod bajarilishidan oldin turli zarur o'zgaruvchilar ishga tushiriladi. Shuning uchun ular uni o'chirishga qaror qilishdi. Nima uchun global o'zgaruvchi o'z holatining katta qismini ma'lum bir direktivaga qarzdor? Muammo shundaki, yoqilganda ishlab chiquvchilar har doim ham u qaerdan kelganligi haqidagi savolga javob bera olmadilar, biroq boshqa tomondan, bu kod yozish jarayonini sezilarli darajada osonlashtirdi. Shu bilan birga, bunday tashkilot xavfsizlikka ma'lum bir tahdid tug'dirdi. Ma'lumotlarni aralashtirish va xatolarni oldini olish uchun direktiv o'chirildi. Endi xavfli kod misolini ko'rib chiqamiz. Shuningdek, biz PHP global o'zgaruvchisi deklaratsiyasi ma'lumotni almashtirishga urinish bilan birga kelgan holatlarni qanday aniqlash mumkinligini ko'rib chiqamiz. Bu ularga duch kelgan birinchi foydalanuvchi tomonidan buzib bo'lmaydigan barqaror ishlaydigan saytlarni yaratish uchun talab qilinadi.

Xavfli kodlar
Ruxsat berilgan foydalanuvchilar uchun o'zgaruvchini true ga o'rnatamiz:
Agar (authenticate_user()) ($authoriza=true;) agar ($authorize) (“/highly/sensitive/data.php”ni o'z ichiga oladi;). Ushbu holatdagi o'zgaruvchi avtomatik ravishda o'rnatilishi mumkin. Ma'lumotni shunchaki almashtirish mumkinligini hisobga olsak va uning kelib chiqish manbasi aniqlanmagan bo'lsa, deyarli har qanday foydalanuvchi bunday tekshiruvdan o'tishi va o'zini kimgadir taqlid qilishi mumkin. Tajovuzkor, agar xohlasa, butun skriptning mantig'ini buzishi mumkin. Direktivning qiymatini o'zgartirsangiz, kod to'g'ri ishlaydi. Aynan shu narsa qilishimiz kerak. Biroq, o'zgaruvchilarni ishga tushirish nafaqat dasturchilar orasida yaxshi amaliyot, balki skriptning barqarorligini ham kafolatlaydi.

Ishonchli variant
Ushbu maqsadga erishish uchun siz direktivani o'chirib qo'yishga urinib ko'rishingiz yoki murakkabroq kod yozishingiz mumkin, masalan: if (isset($_SESSION ['username'])) (echo "Salom" ($_SESSION ['username'"). ])”;) boshqacha (“Salom mehmon” aks-sadosi; “Xush kelibsiz!” aks-sadosi;). Bunday holda, almashtirishni amalga oshirish qiyin bo'ladi. Biroq, bu mumkin. Buning uchun siz tezkor javob vositalarining mavjudligi haqida oldindan g'amxo'rlik qilishingiz kerak. Agar siz PHP-ga global o'zgaruvchilarni kiritishingiz kerak bo'lsa, siz quyidagi vositadan foydalanishingiz mumkin: agar siz qiymat qaysi diapazonda olinishini aniq bilsangiz, uni skript bu faktni taqqoslash orqali tekshiradigan tarzda yozishingiz mumkin. Bu, albatta, qiymatni almashtirishdan 100% himoyani kafolatlay olmaydi. Biroq, mumkin bo'lgan variantlardan o'tish operatsiyani sezilarli darajada murakkablashtiradi.

Spoofing urinishini qanday aniqlash mumkin?
Keling, avval yozilgan hamma narsani to'g'ri tushunganingizni tekshirib ko'raylik. Funktsiyada global o'zgaruvchilarni o'zingiz e'lon qilishingiz kerak bo'ladi. Bu uy vazifasining bir turi. Birinchidan, bu kod:

Keling, ba'zi tushuntirishlar beraylik. C_COOKIE o'zgaruvchisi ishonchli manbadan olingan. Uning natijasi kutilganidek bo'lishini ta'minlash uchun o'zgaruvchining qiymati tekshiriladi. Muammolar yuzaga kelsa, administrator bildirishnoma oladi. Hech narsa sodir bo'lmasa, hech qanday chora ko'rilmaydi.