Setiap aplikasi web yang Anda pakai sebenarnya adalah dua program yang bekerja sama: satu berjalan di browser Anda (sisi client), satu berjalan di komputer penyedia layanan (sisi server). Kegagalan memahami batas antara keduanya adalah sumber kebingungan — sekaligus celah keamanan — yang paling sering menimpa pemula. Pada chapter ini kita memetakan pembagian tugas client dan server secara tegas, mengidentifikasi pekerjaan mana yang wajib dilakukan di server, lalu mempraktikkan pola dasarnya dengan sebuah contoh pengolahan data form.

Membagi Peran Browser dan Server #

Browser bertugas meminta, menerima, lalu menggambar: HTML memberi struktur, CSS memberi tampilan, dan JavaScript memberi interaksi di layar. Server bertugas menyiapkan apa yang diminta: merakit HTML, mengambil data, menjalankan aturan bisnis, dan memutuskan status tanggapan. Analogi sederhananya adalah restoran — meja pelanggan (client) hanya menerima hidangan yang sudah jadi, sementara seluruh proses memasak terjadi di dapur (server) yang tak terlihat pelanggan. Batas analogi ini perlu jelas: berbeda dengan dapur sungguhan, kita sebagai pengembang justru mengendalikan penuh apa yang terjadi di kedua sisi.

Pembagian ini punya konsekuensi teknis yang penting. Kode yang berjalan di browser dapat dilihat dan diubah oleh siapa pun, sehingga tidak boleh memuat rahasia maupun keputusan keamanan. Kode yang berjalan di server tidak pernah dikirim ke browser — hanya hasilnya — sehingga semua hal yang sensitif harus diputuskan di sana. Itulah alasan PHP, yang berjalan sepenuhnya di server, cocok menjadi penjaga logika dan data aplikasi.

Kemampuan yang Hanya Dimiliki Sisi Server #

Beberapa pekerjaan secara prinsip hanya bisa (atau hanya boleh) dilakukan di server:

  • Akses database — kredensial dan koneksi ke database tinggal di server; browser hanya menerima data yang sudah disaring dan diformat.
  • Penyimpanan rahasia — kunci API, kata sandi database, dan token privat tidak boleh pernah tampil di kode sisi client.
  • Autentikasi dan sesi — verifikasi kata sandi (dengan hashing) dan pengelolaan session adalah keputusan server; browser hanya membawa identifier sesinya.
  • Penegakan aturan bisnis — harga akhir, diskon, dan hak akses harus dihitung ulang di server karena data dari browser selalu bisa dipalsukan.
  • Akses sistem berkas — membaca dan menulis berkas, mengirim email, memanggil layanan internal: semuanya hanya mungkin dari server.

Prinsip praktisnya satu kalimat: perlakukan semua data yang datang dari browser sebagai masukan yang belum terpercaya, lalu validasi ulang di server apa pun yang sudah divalidasi JavaScript.

Alur Request Dinamis #

Diagram berikut melukiskan alur lengkap sebuah halaman dinamis yang melibatkan database:

Alurnya berjalan sebagai berikut: browser mengirim permintaan, web server menyerahkannya ke PHP, PHP membuka koneksi ke database dan menjalankan query, hasilnya dirangkai menjadi HTML, lalu HTML tersebut dikembalikan ke browser melalui web server. Ketika Anda kelak membangun aplikasi dengan framework, alur yang sama terjadi — hanya saja tahapnya sudah tertata dalam struktur routing, controller, dan template.

Contoh Pengolahan Data Form #

Mari kita praktikkan pola dasarnya: mengolah data yang dikirim browser. Contoh berikut adalah fungsi yang menerima data sapaan semacam ?nama=Budi dari query string, membersihkannya, lalu menghasilkan cuplikan HTML. Untuk bisa diuji tanpa web server, data masukan kita berikan sebagai array biasa:

php
<?php

function buatSapaan(array $input): string
{
    $nama = isset($input["nama"]) ? trim((string) $input["nama"]) : "";

    if ($nama === "") {
        return "<p>Nama belum diisi. Silakan ulangi pengisian.</p>";
    }

    $namaAman = htmlspecialchars($nama, ENT_QUOTES, "UTF-8");
    return "<p>Halo, <strong>{$namaAman}</strong>! Pesan Anda sudah kami terima.</p>";
}

// Simulasi data yang biasanya dikirim browser melalui URL ?nama=Budi
echo buatSapaan(["nama" => "Budi"]) . "\n";
echo buatSapaan(["nama" => "  Siti  "]) . "\n";
echo buatSapaan(["nama" => ""]) . "\n";
echo buatSapaan([]) . "\n";

Output yang Dihasilkan:

text
<p>Halo, <strong>Budi</strong>! Pesan Anda sudah kami terima.</p>
<p>Halo, <strong>Siti</strong>! Pesan Anda sudah kami terima.</p>
<p>Nama belum diisi. Silakan ulangi pengisian.</p>
<p>Nama belum diisi. Silakan ulangi pengisian.</p>

Mari kita bedah fungsi buatSapaan() baris per baris:

  1. Baris 3 (function buatSapaan(array $input): string): fungsi menerima satu parameter bertipe array dan dijamin mengembalikan string — kontrak yang jelas bagi pemanggilnya.
  2. Baris 5: isset() memeriksa apakah kunci nama ada; trim() membuang spasi di awal dan akhir teks; cast (string) memastikan nilainya diperlakukan sebagai teks. Jika kunci tidak ada, nilainya string kosong.
  3. Baris 7 sampai 9: early return — begitu diketahui nama kosong, fungsi langsung mengembalikan pesan peringatan tanpa memproses lebih jauh.
  4. Baris 11 (htmlspecialchars(..., ENT_QUOTES, "UTF-8")): mengubah karakter <, >, ", dan ' menjadi bentuk aman (&lt;, &gt;, dan sejenisnya) agar teks dari pengguna tidak bisa disusupi tag HTML atau skrip berbahaya.
  5. Baris 12: nilai yang sudah aman dijalin ke dalam template HTML melalui string interpolation.

Terlihat pada output bahwa " Siti " otomatis bersih dari spasi berlebih, sedangkan input kosong maupun data yang tidak memiliki kunci nama sama-sama ditolak dengan pesan yang ramah. Logika inilah yang pada aplikasi sesungguhnya dipicu oleh data dari browser.

Versi Web dari Handler yang Sama #

Di lingkungan web, data query string otomatis tersedia bagi PHP melalui superglobal $_GET. Handler versi web-nya tampak seperti ini:

php
<?php
$nama = isset($_GET["nama"]) ? trim((string) $_GET["nama"]) : "";

if ($nama === "") {
    http_response_code(422);
    echo "Nama wajib diisi.";
    exit;
}

echo "Halo, " . htmlspecialchars($nama, ENT_QUOTES, "UTF-8") . "!";

Ketika browser meminta URL seperti sapa.php?nama=Budi, PHP mengisi $_GET["nama"] dengan nilai "Budi" sebelum kode dijalankan, dan pengguna melihat Halo, Budi!. Penulis menguji perilaku ini dengan built-in web server PHP dan curl: URL dengan parameter kosong menghasilkan pesan Nama wajib diisi. dengan status HTTP 422, sedangkan parameter nama=<script> menghasilkan teks yang sudah di-escape sehingga skrip tersebut tampil sebagai teks biasa, bukan dijalankan browser. Contoh ini tidak dieksekusi otomatis di course karena memerlukan web server; kita akan mempraktikkannya langsung pada Section Menjalankan Program PHP.

Ringkasan #

Browser dan server berbagi peran yang tegas: browser menggambar hasil, server memutuskan segalanya yang sensitif — akses data, autentikasi, aturan bisnis, dan rahasia aplikasi. Data dari browser selalu diperlakukan sebagai masukan yang belum terpercaya dan dibersihkan sebelum dipakai maupun ditampilkan. Pola validasi-escape pada contoh form di atas adalah cikal bakal seluruh pemrosesan input yang akan Anda tulis di framework sekalipun. Dengan kontrak client-server yang jelas ini, kita sekarang siap melihat lebih dalam ke jantung PHP yang mengeksekusi semua itu: runtime dan Zend Engine.

Referensi #