Query string adalah bagian URL yang berada setelah tanda tanya — misalnya ?halaman=2&urutkan=nama pada alamat https://blog.example.com/tugas?halaman=2&urutkan=nama. Pola ini adalah cara standar klien mengirim data opsional ke server: nomor halaman, kata kunci pencarian, filter kategori, hingga urutan tampil. Berbeda dengan route parameter yang hidup di path, query string boleh hadir, boleh absen, dan jumlah kuncinya bebas. Chapter ini membahas cara membacanya lewat object Request, perbedaan penting antara input() dan query(), query parameter berbentuk array, sampai konversi nilai boolean.

Membaca Query String di Route #

Kita mulai dengan route daftar tugas yang membaca dua query parameter. Daftarkan route berikut di routes/web.php:

php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/tugas', function (Request $request) {
    return [
        'halaman' => $request->input('halaman', 1),
        'urutkan' => $request->query('urutkan', 'terbaru'),
        'semua' => $request->all(),
    ];
});

Route::get('/cari', function (Request $request) {
    return [
        'filter' => $request->query('filter'),
        'kategori_input' => $request->input('filter.tag'),
        'kategori_query' => $request->query('filter.tag'),
        'terverifikasi' => $request->boolean('terverifikasi'),
    ];
});

Argumen kedua pada input() dan query() berperan sebagai nilai default ketika parameter tidak dikirim — sama seperti default pada route parameter opsional di chapter Route Parameters . Method all() mengembalikan seluruh sumber input sebagai array, sehingga cocok untuk melihat isi query string sekaligus.

Seluruh skenario kita uji dengan runner standar, ditambah satu eksperimen langsung pada object Request di bagian akhir:

php
<?php

// uji-query.php — jalankan dari root proyek Laravel
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;

require __DIR__.'/vendor/autoload.php';
$app = require __DIR__.'/bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

$kernel = $app->make(Kernel::class);

$permintaan = [
    'GET /tugas?halaman=2&urutkan=nama',
    'GET /tugas',
    'GET /cari?filter[tag]=php&filter[status]=aktif&terverifikasi=1',
    'GET /cari?filter[tag]=php&terverifikasi=0',
];

foreach ($permintaan as $baris) {
    [$method, $uri] = explode(' ', $baris);
    $response = $kernel->handle(
        Request::create('http://localhost:8000'.$uri, $method)
    );
    echo $baris.PHP_EOL.'→ '.$response->getContent().PHP_EOL.PHP_EOL;
}

echo '--- Eksperimen langsung pada object Request ---'.PHP_EOL;

$latihan = Request::create(
    'http://localhost:8000/tugas?halaman=2',
    'POST',
    ['nama' => 'Belajar Laravel']
);

echo 'input("halaman") = '.var_export($latihan->input('halaman'), true).PHP_EOL;
echo 'query("halaman") = '.var_export($latihan->query('halaman'), true).PHP_EOL;
echo 'input("nama")    = '.var_export($latihan->input('nama'), true).PHP_EOL;
echo 'query("nama")    = '.var_export($latihan->query('nama'), true).PHP_EOL;

Output yang Dihasilkan:

text
GET /tugas?halaman=2&urutkan=nama
→ {"halaman":"2","urutkan":"nama","semua":{"halaman":"2","urutkan":"nama"}}

GET /tugas
→ {"halaman":1,"urutkan":"terbaru","semua":[]}

GET /cari?filter[tag]=php&filter[status]=aktif&terverifikasi=1
→ {"filter":{"tag":"php","status":"aktif"},"kategori_input":"php","kategori_query":null,"terverifikasi":true}

GET /cari?filter[tag]=php&terverifikasi=0
→ {"filter":{"tag":"php"},"kategori_input":"php","kategori_query":null,"terverifikasi":false}

--- Eksperimen langsung pada object Request ---
input("halaman") = '2'
query("halaman") = '2'
input("nama")    = 'Belajar Laravel'
query("nama")    = NULL

Perbedaan input() dan query() #

Bandingkan empat baris terakhir pada output di atas. Kedua method sama-sama bisa membaca halaman dari query string, tetapi hanya input() yang mengembalikan nama dari body request POST. Perbedaan ini berasal dari sumber data yang dibaca:

MethodSumber dataKegunaan utama
input()Body request (form/JSON) dan query stringMembaca input apa pun dari mana pun
query()Hanya query stringMemastikan data benar-benar berasal dari URL

Dalam praktik, input() adalah pilihan utama karena handler tidak perlu peduli dari mana data dikirim — daftar lengkap kedua method beserta perilakunya tersedia di dokumentasi requests . Method query() kita pakai ketika kesadaran asal-usul penting — misalnya membangun link “halaman berikutnya” yang harus meneruskan seluruh parameter URL, bukan data form yang terselip di body.

Ada satu perbedaan tersembunyi yang terbukti di output route /cari: kunci kategori_input berhasil membaca filter.tag dengan sintaks dot notation, sedangkan kategori_query bernilai null. Method input() memproses kuncinya lewat helper data_get() yang mendukung dot notation untuk array bersarang, sementara query() mengakses kunci secara literal.

Parameter Array dan Nilai Boolean #

URL ?filter[tag]=php&filter[status]=aktif memakai notasi kurung siku sehingga PHP mengurai query string tersebut menjadi array ["tag" => "php", "status" => "aktif"]. Terlihat di output bahwa query('filter') mengembalikan array utuhnya, dan input('filter.tag') mengambil satu elemen di dalamnya. Pola ini sering dipakai untuk filter multi-kriteria di halaman pencarian.

Untuk parameter seperti terverifikasi=1 yang sejatinya berarti “ya/tidak”, method boolean() menerjemahkannya menjadi true atau false. Output menunjukkan terverifikasi=1 menjadi true dan terverifikasi=0 menjadi false. Nilai yang tidak hadir juga dianggap false, sehingga boolean() aman dipakai tanpa pemeriksaan has() terlebih dahulu.

Query string membuat satu route melayani banyak variasi tampilan tanpa perlu mendefinisikan route baru. Hingga kini kita berfokus pada data berupa teks dan angka; chapter berikutnya membahas input yang paling umum di aplikasi web: form HTML — termasuk upload file dan pola old input saat validasi gagal.