Menghimpun teks panjang dengan tanda kutip cepat menjadi menyiksa: pesan email, kueri SQL, dan potongan HTML penuh tanda kutip yang harus di-escape satu per satu, dan satu escape yang lupa langsung merusak seluruh string. Dua keluarga sintaks yang tersisa dari empat keluarga pada Chapter String Syntax hadir untuk masalah ini: heredoc dan nowdoc. Keduanya mengganti tanda kutip pembuka-penutup dengan penanda baris tersendiri, sehingga isi bebas berisi kutip, backslash, dan baris baru tanpa drama. Pada chapter ini kita pelajari sintaksnya, aturan indentasinya, lalu pola pemakaian nyata untuk SQL dan HTML.

Sintaks Dasar Heredoc #

Heredoc dibuka dengan <<< diikuti sebuah label, diakhiri label yang sama berdiri sendiri di awal baris. Aturan mainnya sederhana: isi dimulai tepat setelah baris pembuka dan berakhir tepat sebelum baris penutup; label mengikuti aturan penamaan identifier PHP seperti variabel tanpa tanda dolar. Mari kita lihat bentuk paling sederhananya:

php
<?php
$pesan = <<<TEKS
Halo, Budi!
Pesanan Anda sedang dikemas.
Terima kasih telah berbelanja.
TEKS;

echo $pesan;
echo "\n--- akhir pesan ---\n";

Output yang Dihasilkan:

text
Halo, Budi!
Pesanan Anda sedang dikemas.
Terima kasih telah berbelanja.
--- akhir pesan ---

Tiga baris isi tercetak apa adanya termasuk pemindahan barisnya, dan tanda --- akhir pesan --- tetap menempel di baris terakhir isi. Posisi penanda tersebut memperlihatkan satu detail penting: karakter baris baru tepat sebelum label penutup tidak dihitung sebagai bagian string, sehingga isi berakhir persis setelah kata berbelanja.. Berbeda dengan double-quoted, di dalam heredoc Anda bebas menuliskan tanda kutip tunggal maupun ganda tanpa escape — tidak ada lagi tanda pembuka yang bisa tertutup lebih awal.

Indentasi Fleksibel sejak PHP 7.3 #

Sebelum PHP 7.3, label penutup wajib berdiri di kolom nol — itulah mengapa kode lama tampak “menjorok keluar” dari fungsi yang menampungnya. Sejak PHP 7.3 label penutup boleh menjorok, dan PHP otomatis memotong indentasi sebesar itu dari setiap baris isi:

php
<?php
function buatPesan(): string
{
    return <<<TEKS
        Halo, Budi!
            Baris ini sengaja menjorok lebih dalam.
        Terima kasih.
        TEKS;
}

echo buatPesan(), "\n";

Output yang Dihasilkan:

text
Halo, Budi!
    Baris ini sengaja menjorok lebih dalam.
Terima kasih.

Label penutup menjorok delapan spasi, maka delapan spasi pertama setiap baris isi ikut terbuang: Halo, Budi! jatuh ke kolom nol. Baris kedua sengaja diberi dua belas spasi, sehingga setelah dipotong masih tersisa empat spasi — indentasi relatif di dalam isi tetap terjaga. Berkat aturan ini, heredoc dapat hidup rapi di dalam fungsi, method, atau blok percabangan tanpa merusak keterbacaan.

Aturannya pun tegas ke arah lain: setiap baris isi tidak boleh menjorok lebih dangkal daripada label penutup. Pelanggarannya ditolak sejak tahap parsing:

php
<?php
$pesan = <<<TEKS
  Baris ini menjorok 2 spasi.
      Penutup menjorok 4 spasi.
    TEKS;

echo $pesan, "\n";

Output yang Dihasilkan:

text

Parse error: Invalid body indentation level (expecting an indentation level of at least 4) in /home/z/my-project/php-course/content/php/string-dan-text-processing/heredoc-dan-nowdoc/.verify_tmp.php on line 3

Baris kedua hanya menjorok dua spasi sementara penutup meminta empat, sehingga parser menolak dengan Invalid body indentation level. PHP bahkan menyebutkan berapa level indentasi minimum yang diharapkan. Perhatikan juga bahwa campuran tab dan spasi pada indentasi akan ditolak dengan alasan serupa — pilih satu jenis, lalu konsistenlah dengannya.

Heredoc Memproses Isi Seperti Double-Quoted #

Secara pemrosesan, heredoc setara dengan double-quoted: escape sequence dikenali dan variabel diinterpolasi. Tepat karena itu, heredoc adalah rumah yang nyaman untuk teks panjang yang memuat nilai variabel:

php
<?php
$nama = "Siti";
$jumlah = 3;
$total = 225000;

$struk = <<<STRUK
Halo, {$nama}!
Anda membeli {$jumlah} item dengan total Rp{$total}.
Terima kasih telah berbelanja.
STRUK;

echo $struk, "\n";

Output yang Dihasilkan:

text
Halo, Siti!
Anda membeli 3 item dengan total Rp225000.
Terima kasih telah berbelanja.

Setiap {$nama}, {$jumlah}, dan {$total} diganti nilainya, termasuk Rp{$total} yang menempel huruf Rp — kurung kurawal memastikan batas variabel terbaca jelas. Bentuk ringkas $nama juga sah di dalam heredoc, tetapi kita akan selalu memakai bentuk kurung kurawal pada contoh-contoh buku ini karena lebih tahan terhadap batas identifier — alasan lengkapnya menjadi pokok bahasan Chapter String Interpolation .

Nowdoc: Versi Literal dari Heredoc #

Nowdoc adalah kembaran heredoc yang tidak memproses apa pun: label pembukanya ditulis dalam kutip tunggal (<<<'LABEL'), dan seluruh isi diperlakukan literal — tidak ada interpolasi, tidak ada escape. Kegunaannya tepat ketika teks memuat tanda dolar atau backslash yang harus bertahan apa adanya:

php
<?php
$petunjuk = <<<'PETUNJUK'
Jalankan perintah berikut di terminal:
export APP_PORT=$PORT_APLIKASI
PETUNJUK;

$javascript = <<<'JS'
const sapa = (nama) => `Halo, ${nama}!`;
JS;

echo $petunjuk, "\n";
echo $javascript, "\n";

Output yang Dihasilkan:

text
Jalankan perintah berikut di terminal:
export APP_PORT=$PORT_APLIKASI
const sapa = (nama) => `Halo, ${nama}!`;

Teks $PORT_APLIKASI dan ${nama} tercetak mentah-mentah — PHP sama sekali tidak mencoba menginterpolasinya. Contoh kedua memperlihatkan kasus favorit di dunia nyata: menyematkan potongan JavaScript yang memakai template literal ${...}, sintaks yang persis bertabrakan dengan interpolation PHP. Secara teknis nowdoc bahkan lebih literal daripada single-quoted, karena rangkaian \' pun tidak diproses.

AspekHeredoc <<<LABELNowdoc <<<'LABEL'
Setara denganDouble-quotedSingle-quoted (lebih literal)
Interpolasi variabelYaTidak
Escape sequenceDiprosesTidak diproses sama sekali
Cocok untukTeks panjang dengan nilai dinamisTeks berisi $, backslash, kode bahasa lain

Pola Umum: Menyusun SQL dan HTML #

Dua tempat yang paling diuntungkan heredoc adalah penyusunan kueri SQL dan template HTML — keduanya multi-baris, terstruktur, dan penuh tanda kutip. Untuk SQL, pola yang sehat adalah menginterpolasi nama tabel atau parameter yang sudah divalidasi, bukan masukan mentah pengguna:

php
<?php
function buatQueryLaporan(string $tabel, int $batas): string
{
    return <<<SQL
        SELECT id, nama, total
        FROM {$tabel}
        WHERE total > 0
        ORDER BY total DESC
        LIMIT {$batas}
        SQL;
}

echo buatQueryLaporan("penjualan", 10), "\n";

Output yang Dihasilkan:

text
SELECT id, nama, total
FROM penjualan
WHERE total > 0
ORDER BY total DESC
LIMIT 10

Kueri tercetak rapi lima baris tanpa satu pun escape; parameter int $batas sudah dijamin numerik oleh type declaration-nya. Untuk HTML, keunggulan heredoc bertumpuk: tanda kutip ganda atribut bebas dipakai, dan indentasi fleksibel menjaga blok tetap sejajar dengan kode PHP di sekitarnya:

php
<?php
$judul = "Belajar PHP Dasar";
$pengguna = "Budi";

$kartu = <<<HTML
    <div class="kartu">
        <h2>{$judul}</h2>
        <p>Selamat datang, {$pengguna}!</p>
    </div>
    HTML;

echo $kartu, "\n";

Output yang Dihasilkan:

text
<div class="kartu">
    <h2>Belajar PHP Dasar</h2>
    <p>Selamat datang, Budi!</p>
</div>

Penutup HTML menjorok empat spasi, sehingga isi terpotong mulai dari kolom yang sama dengan kode PHP. Pola yang sama juga nyaman dipakai untuk menyusun JSON manual — walau untuk JSON, fungsi json_encode() yang kita kenal di Section Data Processing umumnya lebih aman.

Ringkasan #

Heredoc mengganti tanda kutip dengan penanda <<<LABEL ... LABEL, memuat teks multi-baris beserta tanda kutip tanpa escape, memproses interpolation dan escape seperti double-quoted, serta sejak PHP 7.3 menanggalkan indentasi label penutup dari setiap baris isi. Nowdoc — label dikutip tunggal — adalah versi yang sepenuhnya literal dan tepat untuk teks berisi $ atau kode bahasa lain. Dengan heredoc kita berkali-kali menulis {$nama}; saatnya membedah seluruh aturan interpolation tersebut secara sistematis pada chapter berikutnya.

Referensi #