Formalar — $_GET, $_POST, $_SERVER

~20 daq · PHP · PHP va Veb

Muammodan boshlaylik

Hozirgacha barcha ma'lumotlar kod ichida yozilgan edi. Lekin haqiqiy sayt foydalanuvchidan ma'lumot oladi: qidiruv so'zi, login va parol, izoh matni, buyurtma manzili.

Brauzer bu ma'lumotni serverga qanday yuboradi va PHP uni qayerdan oladi? Javob — HTML forma va PHP ning maxsus massivlari.


HTML forma eslatmasi

<form action="qidiruv.php" method="get">
    <input type="text" name="soz">
    <button type="submit">Qidirish</button>
</form>
  • action — ma'lumot qaysi faylga yuboriladi
  • method — qanday yuboriladi: get yoki post
  • name — PHP da shu nom bilan olinadi. name siz input yuborilmaydi!

$_GET — URL orqali

Yuqoridagi formada "telefon" deb yozib yuborsangiz, brauzer shu manzilga o'tadi:

qidiruv.php?soz=telefon

? dan keyingi qism — query string. kalit=qiymat juftliklari, & bilan ajratiladi:

katalog.php?toifa=telefon&sahifa=2&saralash=narx

PHP da bular $_GET massiviga tushadi:

<?php

// katalog.php?toifa=telefon&sahifa=2
echo $_GET['toifa'];    // telefon
echo $_GET['sahifa'];   // 2  — DIQQAT: bu "2" string!

print_r($_GET);
// Array ( [toifa] => telefon [sahifa] => 2 )

Parametr bo'lmasligi ham mumkin — doim ?? bilan standart qiymat bering:

<?php

$sahifa = (int) ($_GET['sahifa'] ?? 1);
$toifa  = $_GET['toifa'] ?? 'hammasi';

GET ni formasiz ham ishlatish mumkin — oddiy havola orqali:

<a href="katalog.php?toifa=telefon&sahifa=<?= $sahifa + 1 ?>">Keyingi sahifa</a>

$_POST — so'rov tanasida

<form action="kirish.php" method="post">
    <input type="email" name="email">
    <input type="password" name="parol">
    <button type="submit">Kirish</button>
</form>

POST da ma'lumot URL da ko'rinmaydi — u so'rovning tanasida (body) yuboriladi.

<?php

$email = $_POST['email'] ?? '';
$parol = $_POST['parol'] ?? '';

GET va POST — qachon qaysi biri?

GET POST
Ma'lumot qayerda URL da ko'rinadi So'rov tanasida
Saqlash / ulashish Havolani nusxalab yuborish mumkin Mumkin emas
Hajm Cheklangan (~2000 belgi) Katta (fayllar ham)
Brauzer tarixi Saqlanadi Saqlanmaydi
Qayta yuborish Xavfsiz "Formani qayta yuborasizmi?" ogohlantirishi

Qoida:

  • Ma'lumotni o'qish (qidiruv, filtr, sahifalash) → GET
  • Ma'lumotni o'zgartirish (ro'yxatdan o'tish, buyurtma, o'chirish, login) → POST

Parolni hech qachon GET bilan yubormang — u brauzer tarixida, server loglarida va Referer sarlavhasida qoladi.

[!WARNING] POST shifrlash emas. POST ma'lumoti ham DevTools da ko'rinadi va oddiy HTTP da tarmoqda ochiq ketadi. Himoya — faqat HTTPS.


Forma va uni qayta ishlash — bitta faylda

Eng ko'p ishlatiladigan usul: forma ham, uni qayta ishlash ham bitta faylda.

<?php
// aloqa.php
declare(strict_types=1);

$xatolar = [];
$yuborildi = false;
$ism = '';
$xabar = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $ism   = trim($_POST['ism'] ?? '');
    $xabar = trim($_POST['xabar'] ?? '');

    if ($ism === '') {
        $xatolar[] = "Ismingizni kiriting";
    }
    if (mb_strlen($xabar) < 10) {
        $xatolar[] = "Xabar kamida 10 belgidan iborat bo'lsin";
    }

    if (empty($xatolar)) {
        // bu yerda bazaga saqlash yoki email yuborish bo'ladi
        $yuborildi = true;
    }
}
?>
<!DOCTYPE html>
<html lang="uz">
<body>

<?php if ($yuborildi): ?>
    <p>Rahmat, <?= htmlspecialchars($ism) ?>! Xabaringiz qabul qilindi.</p>
<?php else: ?>

    <?php foreach ($xatolar as $x): ?>
        <p style="color:red"><?= htmlspecialchars($x) ?></p>
    <?php endforeach; ?>

    <form method="post">
        <input name="ism" value="<?= htmlspecialchars($ism) ?>" placeholder="Ism">
        <textarea name="xabar" placeholder="Xabar"><?= htmlspecialchars($xabar) ?></textarea>
        <button type="submit">Yuborish</button>
    </form>

<?php endif; ?>

</body>
</html>

Muhim jihatlar:

  1. $_SERVER['REQUEST_METHOD'] === 'POST' — forma yuborildimi yoki sahifa shunchaki ochildimi
  2. action yozilmagan — forma o'sha faylning o'ziga yuboriladi
  3. Xato bo'lsa, foydalanuvchi kiritgan qiymatlar value ga qaytariladi — qaytadan yozish shart emas
  4. Har bir chiqarishda htmlspecialchars() — nima uchunligi keyingi darsda

Checkbox, select va massivlar

<select name="shahar">
    <option value="toshkent">Toshkent</option>
    <option value="samarqand">Samarqand</option>
</select>

<label><input type="checkbox" name="obuna" value="1"> Yangiliklarga obuna</label>

<label><input type="checkbox" name="qiziqish[]" value="php"> PHP</label>
<label><input type="checkbox" name="qiziqish[]" value="mysql"> MySQL</label>
<label><input type="checkbox" name="qiziqish[]" value="js"> JS</label>
<?php

$shahar = $_POST['shahar'] ?? '';
$obuna  = isset($_POST['obuna']);          // belgilanmagan checkbox UMUMAN yuborilmaydi
$qiziqishlar = $_POST['qiziqish'] ?? [];   // name="...[]" → massiv keladi

print_r($qiziqishlar);   // ['php', 'mysql']

Belgilanmagan checkbox yuborilmasligi — ko'p xatolarning manbai. Shuning uchun isset() bilan tekshiriladi.


$_SERVER — so'rov haqida ma'lumot

<?php

echo $_SERVER['REQUEST_METHOD'];   // GET yoki POST
echo $_SERVER['REQUEST_URI'];      // /katalog.php?sahifa=2
echo $_SERVER['HTTP_HOST'];        // localhost:8000
echo $_SERVER['REMOTE_ADDR'];      // 127.0.0.1 — foydalanuvchi IP manzili
echo $_SERVER['HTTP_USER_AGENT'];  // Mozilla/5.0 ... — brauzer
echo $_SERVER['SCRIPT_NAME'];      // /katalog.php

[!WARNING] $_SERVER dagi HTTP_ bilan boshlanadigan qiymatlar (HTTP_USER_AGENT, HTTP_REFERER, HTTP_HOST) brauzerdan keladi — ularni foydalanuvchi soxtalashtirishi mumkin. Ularga ishonmang va tekshirmasdan HTML ga chiqarmang.


$_REQUEST — nima uchun ishlatmaslik kerak

$_REQUEST — $_GET, $_POST va $_COOKIE aralashmasi. Qulay ko'rinadi, lekin ma'lumot qayerdan kelgani noma'lum bo'lib qoladi. POST bilan kelishi kerak bo'lgan "o'chirish" buyrug'i GET havola orqali ham ishlab ketadi. Har doim aniq manbani ishlating.


Nima uchun shunday?

Nima uchun $_GET, $_POST dagi hamma qiymatlar string, sahifa=2 bo'lsa ham?

Chunki HTTP — matnli protokol. Brauzer serverga baytlar ketma-ketligini yuboradi, unda "bu son" degan belgi yo'q. 2 — bu shunchaki "2" belgisi. PHP turini taxmin qilmaydi: aylantirish — sizning vazifangiz. Shu sababli strict_types yoqilganda ham formadan kelgan qiymatni avval (int) ga o'tkazish kerak.


Tez-tez uchraydigan xatolar

name atributini unutish — input yuboriladi, deb o'ylaysiz, lekin $_POST bo'sh.

Kalit mavjudligini tekshirmaslik:

echo $_POST['email'];
// Warning: Undefined array key "email" — sahifa birinchi marta ochilganda

Sahifani yangilash (F5) — forma qayta yuboriladi. Buyurtma ikki marta tushadi. Yechim — POST dan keyin redirect (PRG usuli), 23-darsda.


Xulosa

Eslab qoling:

  • $_GET — URL dagi parametrlar; o'qish, qidiruv, filtr uchun
  • $_POST — forma tanasidagi ma'lumot; o'zgartirish, login uchun
  • Hamma qiymatlar — string; doim ?? standart va kerak bo'lsa (int)
  • $_SERVER['REQUEST_METHOD'] — forma yuborilganini aniqlash
  • Belgilanmagan checkbox umuman kelmaydi — isset()
  • name="x[]" — massiv sifatida keladi
  • $_REQUEST dan qoching

Keyingi dars

20-dars: Ma'lumotni tekshirish — filter_var, htmlspecialchars, XSS