URL adalah alamat yang menunjuk ke sumber daya web: halaman produk, endpoint API, sampai berkas gambar. Aplikasi PHP membaca bagian-bagian URL ini untuk mengambil keputusan — nomor halaman, kata kunci pencarian, filter kategori — sehingga memahami anatomi URL menjadi keterampilan harian, bukan sekadar pelengkap teori. Pada chapter ini kita membedah URL dengan parse_url(), memparsing query string dengan parse_str(), membangunnya ulang dengan http_build_query(), dan mengenal satu kejanggalan kecil yang diam-diam dilakukan PHP terhadap nama parameter.

Anatomi URL #

Sebuah URL lengkap tersusun dari enam bagian. Perhatikan contoh berikut, lalu petaannya:

text
https://www.contoh.com:8443/produk/kategori?page=2&urut=harga#bagian-ulasan
  • scheme (https) — protokol yang dipakai; http atau https.
  • host (www.contoh.com) — nama domain server tujuan.
  • port (8443) — pintu komunikasi; bila tidak ditulis, browser memakai port bawaan (80 untuk http, 443 untuk https).
  • path (/produk/kategori) — lokasi sumber daya di dalam server.
  • query (page=2&urut=harga) — daftar parameter untuk aplikasi, diawali tanda ?.
  • fragment (#bagian-ulasan) — penunjuk bagian dokumen; diproses oleh browser dan tidak pernah dikirim ke server.

Fakta bahwa fragment tidak dikirim ke server sering mengejutkan pemula: mengubah #bagian-ulasan menjadi #lain tidak memicu request baru dan tidak akan pernah terlihat oleh skrip PHP. PHP menyediakan fungsi parse_url() untuk memecah URL menjadi array berpasangan kunci-nilai:

php
<?php
$url = 'https://www.contoh.com:8443/produk/kategori?page=2&urut=harga#bagian-ulasan';

print_r(parse_url($url));

Output yang Dihasilkan:

text
Array
(
    [scheme] => https
    [host] => www.contoh.com
    [port] => 8443
    [path] => /produk/kategori
    [query] => page=2&urut=harga
    [fragment] => bagian-ulasan
)

Hasilnya berupa array asosiatif dengan kunci sesuai nama bagian: scheme, host, port, path, query, dan fragment. Nilai port berupa integer, sedangkan bagian lain berupa string. Perhatikan bahwa query masih berupa string mentah page=2&urut=harga — memecahnya menjadi parameter perlu langkah terpisah yang kita bahas segera. Satu catatan penting: parse_url() adalah pemecah, bukan validator — fungsi ini tidak memeriksa apakah URL masuk akal secara keseluruhan. Untuk validasi, gunakan filter_var($url, FILTER_VALIDATE_URL); pada pengujian kami, URL valid mengembalikan string itu sendiri, sedangkan teks biasa mengembalikan false.

Mengambil Satu Komponen #

Sering kali kita hanya butuh satu bagian, misalnya hanya path untuk keperluan routing. parse_url() menerima konstanta komponen sebagai argumen kedua agar langsung mengembalikan bagian tersebut tanpa array perantara:

php
<?php
$url = 'https://www.contoh.com:8443/produk/kategori?page=2&urut=harga';

echo parse_url($url, PHP_URL_SCHEME) . "\n";
echo parse_url($url, PHP_URL_HOST) . "\n";
echo parse_url($url, PHP_URL_PORT) . "\n";
echo parse_url($url, PHP_URL_PATH) . "\n";
echo parse_url($url, PHP_URL_QUERY) . "\n";

Output yang Dihasilkan:

text
https
www.contoh.com
8443
/produk/kategori
page=2&urut=harga

Konstanta yang tersedia adalah PHP_URL_SCHEME, PHP_URL_HOST, PHP_URL_PORT, PHP_URL_USER, PHP_URL_PASS, PHP_URL_PATH, PHP_URL_QUERY, dan PHP_URL_FRAGMENT. Bila komponen yang diminta tidak ada pada URL — misalnya meminta PHP_URL_FRAGMENT dari URL tanpa #bagian — fungsi mengembalikan null, sehingga pemeriksaan isset() tetap perlu dilakukan sebelum memakai hasilnya.

Mem-parsing Query String dengan parse_str #

Query string berformat deretan kunci=nilai yang dipisah tanda &, dengan karakter khusus yang telah di-encode. Fungsi parse_str() memecah format tersebut menjadi array PHP:

php
<?php
$queryString = 'halaman=3&urut=harga&arah=desc';

$params = [];
parse_str($queryString, $params);

print_r($params);

Output yang Dihasilkan:

text
Array
(
    [halaman] => 3
    [urut] => harga
    [arah] => desc
)

Fungsi parse_str() mengisi array pada argumen kedua dengan pasangan kunci-nilai dari query string. Satu perilaku yang wajib diingat: seluruh nilai berupa string — pada pengujian kami, halaman=3 menghasilkan string(1) "3", bukan integer. Angka, tanda kutip, markup HTML masuk apa adanya, sehingga validasi tetap menjadi langkah berikutnya setelah parsing, bukan opsional. Kebiasaan baik berikutnya adalah selalu mengoper array hasil seperti pada contoh; alasannya dibedah pada callout di bawah.

Nama Parameter yang Ditulis Ulang PHP #

Berikut kejanggalan yang dijanjikan di pembuka chapter. PHP mengonversi karakter titik dan spasi pada nama parameter menjadi garis bawah saat mem-parsing query string. Perhatikan:

php
<?php
$queryString = 'harga.total=50000&nama pengguna=Budi';

$params = [];
parse_str($queryString, $params);

print_r($params);

Output yang Dihasilkan:

text
Array
(
    [harga_total] => 50000
    [nama_pengguna] => Budi
)

Parameter harga.total menjadi kunci harga_total, dan nama pengguna menjadi nama_pengguna — nilai tidak tersentuh, hanya nama yang ditulis ulang. Konversi ini bukan keanehan parse_str() semata: kami memverifikasi perilaku yang sama pada request web nyata, di mana URL ?harga.total=50000&nama+pengguna=Budi membuat PHP mengisi $_GET dengan kunci harga_total dan nama_pengguna. Alasan historisnya sederhana — titik dan spasi tidak sah dalam nama variabel PHP, dan mekanisme parsing ini lahir dari era ketika parameter otomatis menjadi variabel.

Membangun Query String dengan http_build_query #

Membangun query string dengan penggabungan string manual rawan kesalahan: lupa meng-encode spasi, karakter & pada nilai, hingga tanda = tidak sengaja masuk. Fungsi http_build_query() menyelesaikan semuanya dengan menerima array sebagai masukan:

php
<?php
$filter = [
    'kategori' => 'buku',
    'halaman' => 2,
    'kata kunci' => 'belajar php',
];

echo http_build_query($filter) . "\n";

Output yang Dihasilkan:

text
kategori=buku&halaman=2&kata+kunci=belajar+php

Setiap pasangan kunci-nilai di-encode lalu dirangkai dengan &: spasi pada belajar php menjadi +, dan nilai integer 2 otomatis dikonversi menjadi string. Fungsi ini juga menangani array bersarang — pada pengujian kami, array ['filter' => ['urut' => 'harga']] menghasilkan filter%5Burut%5D=harga, yaitu notasi kurung siku yang di-encode dan tetap bisa di-parse balik oleh PHP. Singkatnya, http_build_query() adalah pasangan alami parse_str().

Encoding Karakter Reserved #

Spesifikasi URL (RFC 3986) menyimpan beberapa karakter sebagai penanda struktur — antara lain spasi, &, =, ?, dan # — sehingga karakter tersebut wajib di-encode bila muncul dalam data. PHP menyediakan dua fungsi encoding dengan satu perbedaan halus:

php
<?php
$teks = 'belajar php & mysql';

echo urlencode($teks) . "\n";
echo rawurlencode($teks) . "\n";

Output yang Dihasilkan:

text
belajar+php+%26+mysql
belajar%20php%20%26%20mysql

Kedua fungsi menghasilkan encoding yang sama kecuali pada spasi: urlencode() mengubah spasi menjadi + (warisan format form lama), sedangkan rawurlencode() mengubahnya menjadi %20 sesuai RFC 3986. Panduan praktisnya: gunakan urlencode() atau http_build_query() untuk query string, dan rawurlencode() untuk path — misalnya nama berkas unik dalam URL. Pada contoh di atas, keduanya meng-encode & menjadi %26 agar tidak salah dibaca sebagai pemisah parameter.

Menggabungkan URL dan Query String #

Dua keterampilan terakhir chapter ini — mengenali bagian URL dan membangun query — kini digabungkan menjadi satu utilitas kecil yang sering dipakai di aplikasi nyata, misalnya membangun tautan halaman berikutnya:

php
<?php
function buatUrl(string $basis, array $params): string
{
    $pemisah = str_contains($basis, '?') ? '&' : '?';
    return $basis . $pemisah . http_build_query($params);
}

echo buatUrl('https://www.contoh.com/produk', ['kategori' => 'buku', 'halaman' => 2]) . "\n";
echo buatUrl('https://www.contoh.com/produk?urut=harga', ['halaman' => 2]) . "\n";

Output yang Dihasilkan:

text
https://www.contoh.com/produk?kategori=buku&halaman=2
https://www.contoh.com/produk?urut=harga&halaman=2

Fungsi buatUrl() memeriksa apakah URL dasar sudah mengandung tanda ?: bila belum, parameter pertama disambung dengan ?; bila sudah, penyambungnya &. Baris kedua contoh membuktikan percabangannya — parameter halaman menyatu mulus di belakang ?urut=harga. Dengan str_contains() dan http_build_query() di tempat yang tepat, URL hasil gabungan selalu ter-encode dengan benar.

Ringkasan #

Kini kita bisa membedah URL menjadi komponen dengan parse_url(), mem-parsing query string menjadi array dengan parse_str(), dan membangunnya ulang dengan http_build_query() beserta encoding yang benar. Kita juga telah membuktikan sendiri kejanggalan konversi nama parameter titik dan spasi menjadi garis bawah. Pada request web nyata, hasil parsing query string ini hadir di skrip Anda sebagai superglobal $_GET — topik yang dibedah tuntas pada Chapter PHP Superglobals .

Referensi #