Tur belgilash — parametr va qaytish turlari, strict_types
Muammodan boshlaylik
Hamkasbingiz yozgan funksiya:
<?php
function chegirma($narx, $foiz)
{
return $narx * $foiz / 100;
}
Savollar: $foiz — 15 mi yoki 0.15 mi? $narx — son mi yoki "250 000 so'm" degan matn ham bo'lishi mumkinmi? Funksiya nima qaytaradi? Javob bilish uchun kodni o'qib chiqish yoki muallifdan so'rash kerak.
Endi tasavvur qiling, kimdir chegirma("bepul", 10) deb chaqirdi. PHP 8 da bu TypeError — lekin xato funksiya ichida chiqadi va qayerdan noto'g'ri qiymat kelganini topish qiyin.
Tur belgilash (type declarations) ikkala muammoni hal qiladi: kod o'zini o'zi hujjatlaydi va xato kirish eshigida ushlanadi.
Parametr turlari
<?php
function chegirma(int $narx, int $foiz)
{
return $narx * $foiz / 100;
}
echo chegirma(200000, 15); // 30000
Endi funksiya e'lonining o'zi aytib turibdi: ikkala parametr — butun son.
Noto'g'ri tur berilsa:
<?php
echo chegirma("bepul", 10);
// TypeError: chegirma(): Argument #1 ($narx) must be of type int, string given
Xato aniq: qaysi funksiya, qaysi parametr, nima kutilgan, nima kelgan.
Qaytish turi
Qavsdan keyin : va tur:
<?php
function chegirma(int $narx, int $foiz): float
{
return $narx * $foiz / 100;
}
function toliqIsm(string $ism, string $familiya): string
{
return "$ism $familiya";
}
function kattami(int $yosh): bool
{
return $yosh >= 18;
}
Hech narsa qaytarmaydigan funksiya — void:
<?php
function logYoz(string $xabar): void
{
file_put_contents('app.log', $xabar . PHP_EOL, FILE_APPEND);
// return yo'q yoki faqat `return;`
}
Mavjud turlar
| Tur | Ma'nosi |
|---|---|
int, float, string, bool |
Oddiy turlar |
array |
Massiv |
void |
Hech narsa qaytarmaydi (faqat qaytish turi) |
null |
Faqat null |
mixed |
Istalgan tur |
callable |
Chaqirib bo'ladigan narsa (funksiya) |
?int |
int yoki null |
int|string |
int yoki string (union) |
never |
Hech qachon qaytmaydi (doim xato tashlaydi yoki exit) |
ClassNomi |
Shu class ob'ekti (OOP qismida) |
Nullable: ?
"Qiymat bo'lishi ham, bo'lmasligi ham mumkin":
<?php
function foydalanuvchiniTop(int $id): ?array
{
$baza = [1 => ["ism" => "Ali"], 2 => ["ism" => "Vali"]];
return $baza[$id] ?? null; // topilmasa — null
}
$user = foydalanuvchiniTop(5);
if ($user === null) {
echo "Topilmadi";
}
?array — "massiv yoki null qaytaraman, null ni tekshiring" degan ogohlantirish.
Union: |
<?php
function idniTozala(int|string $id): int
{
return (int) $id;
}
Avtomatik moslashtirish va strict_types
Bir narsa sizni hayratda qoldirishi mumkin:
<?php
function ikkiBaravar(int $son): int
{
return $son * 2;
}
echo ikkiBaravar("21"); // 42 — xato yo'q!
"21" — string, lekin PHP uni jimgina int ga aylantirdi. Bu default (yumshoq) rejim: agar qiymatni xatosiz aylantirish mumkin bo'lsa — PHP aylantiradi.
Qat'iy rejimni yoqish uchun faylning eng birinchi qatoriga:
<?php
declare(strict_types=1);
function ikkiBaravar(int $son): int
{
return $son * 2;
}
echo ikkiBaravar("21");
// TypeError: ikkiBaravar(): Argument #1 ($son) must be of type int, string given
Endi PHP hech narsani taxmin qilmaydi. Turlar mos kelmasa — xato.
[!TIP] Zamonaviy PHP loyihalarda (Laravel, Symfony paketlari) deyarli har bir fayl
declare(strict_types=1);bilan boshlanadi. Siz ham shunga odatlaning. Faqat esda tuting: formadan kelgan qiymatlar doim string — ularni funksiyaga berishdan oldin o'zingiz(int)bilan aylantirasiz.
Bitta istisno: strict_types da ham int ni float parametrga berish mumkin — bu ma'lumot yo'qotmaydi.
Nima uchun shunday?
Nima uchun PHP turlarni majburiy qilmaydi, strict_types ni ham o'chiq holda qoldiradi?
PHP 20 yildan ortiq turlarsiz yashagan va internetda milliardlab qator shunday kod bor. Turlar majburiy bo'lsa — hammasi bir kunda buzilardi. Shuning uchun tur belgilash ixtiyoriy qo'shilgan (PHP 7.0, 2015), strict_types esa har bir fayl uchun alohida yoqiladi. Bu eski kodni buzmasdan yangi kodni xavfsiz yozish imkonini beradi.
Hujjatlash: DocBlock
Ba'zan tur yetarli emas — masalan, array ichida nima borligi. Buning uchun izoh:
<?php
/**
* Mahsulotlarning umumiy narxini hisoblaydi.
*
* @param array<int, array{nom: string, narx: int, soni: int}> $mahsulotlar
* @return int Jami summa, so'mda
*/
function jamiNarx(array $mahsulotlar): int
{
$jami = 0;
foreach ($mahsulotlar as $m) {
$jami += $m['narx'] * $m['soni'];
}
return $jami;
}
PHP bu izohni tekshirmaydi, lekin muharrir (PHP Intelephense) va tahlil vositalari (PHPStan) o'qiydi va xatolarni oldindan ko'rsatadi.
Tez-tez uchraydigan xatolar
declare birinchi qatorda emas:
<?php
echo "salom";
declare(strict_types=1);
// Fatal error: strict_types declaration must be the very first statement in the script
void funksiyadan qiymat qaytarish:
<?php
function a(): void
{
return 5;
}
// Fatal error: A void function must not return a value
Qaytish turiga mos kelmaydigan qiymat:
<?php
declare(strict_types=1);
function ortacha(array $sonlar): int
{
return array_sum($sonlar) / count($sonlar); // 2.5 bo'lishi mumkin
}
echo ortacha([2, 3]);
// TypeError: ortacha(): Return value must be of type int, float returned
Yechim: qaytish turini float qiling yoki intdiv() / (int) ishlating.
Xulosa
Eslab qoling:
function nom(int $a, string $b): bool— parametr va qaytish turlari?tur— null ham bo'lishi mumkin;a|b— ikki turdan birivoid— hech narsa qaytarmaydi- Default holatda PHP mos keladigan qiymatni aylantiradi (
"21"→21) declare(strict_types=1);— faylning birinchi qatorida, qat'iy rejim- Turlar — o'zini o'zi hujjatlaydigan kod va xatoni erta ushlash
Keyingi dars
16-dars: Scope, anonim funksiyalar va arrow function (fn)