BAB 7: STRING MANIPULATION

7-2: String Functions

Objectives

  • String manipulation functions
  • Search dan extract
  • Formatting functions
  • Memahami fungsi multibyte (mb_*)
  • Menggabungkan fungsi untuk membangun string baru

Kenapa Butuh Fungsi String?

PHP menyediakan ratusan function bawaan untuk memanipulasi string: memotong, mencari, mengganti, memformat, dan mengubah huruf besar/kecil. Alih-alih menulis ulang logika manual, gunakan function bawaan — lebih cepat, lebih aman, dan sudah teruji.

📊 Memuat diagram…

Fungsi string biasanya tidak mengubah variabel asli — mereka mengembalikan string baru. Kamu harus menyimpan hasilnya:

php
<?php

$teks = "HELLO";
strtolower($teks);
echo $teks;  // HELLO — tidak berubah!

$kecil = strtolower($teks);
echo $kecil;  // hello — hasil harus disimpan

?>

Length & Position

php
<?php

$text = "Hello World";

// Length
strlen($text);           // 11
mb_strlen($text);        // 11 (multi-byte safe)

// Position
strpos($text, "World");  // 6 (index)
strpos($text, "world");  // false (case-sensitive!)
stripos($text, "world"); // 6 (case-insensitive)

// Check
str_contains($text, "World");    // true (PHP 8+)
str_starts_with($text, "Hello");  // true
str_ends_with($text, "World");    // true

?>

strpos: Hati-hati dengan false!

strpos mengembalikan index jika ditemukan, atau false jika tidak. Masalahnya: index 0 juga "falsy"! Ini bug klasik:

php
<?php

$teks = "Jakarta";

// ❌ BUG: posisi 0 dianggap false!
$posisi = strpos($teks, "J");
if ($posisi) {
    echo "Ditemukan di index $posisi";
} else {
    echo "Tidak ditemukan";  // ❌ Salah! "J" ada di index 0
}

// ✅ Benar: bandingkan dengan false secara eksplisit
$posisi = strpos($teks, "J");
if ($posisi !== false) {
    echo "Ditemukan di index $posisi";  // Ditemukan di index 0
}

?>
⚠️Perhatian

Selalu bandingkan hasil strpos dengan !== false, bukan dengan truthiness biasa. Index 0 adalah posisi yang sah!

str_contains dan Keluarga Barunya (PHP 8+)

PHP 8 memperkenalkan str_contains, str_starts_with, dan str_ends_with yang mengembalikan boolean — jauh lebih aman daripada strpos:

php
<?php

$email = "user@example.com";

if (str_contains($email, "@")) {
    echo "Format email punya @";  // Output: Format email punya @
}

if (str_starts_with($email, "user")) {
    echo "Mulai dengan user";  // Output: Mulai dengan user
}

if (str_ends_with($email, ".com")) {
    echo "Domain .com";  // Output: Domain .com
}

?>
💡Tip

Di PHP 8+, pilih str_contains/str_starts_with/str_ends_with untuk pengecekan keberadaan — lebih mudah dibaca dan tidak ada jebakan false seperti strpos.

Extract & Replace

php
<?php

$text = "Hello World";

// Extract
substr($text, 0, 5);     // "Hello"
substr($text, 6);        // "World"
substr($text, -5);       // "World"

// Replace
str_replace("World", "PHP", $text);   // "Hello PHP"
str_ireplace("world", "PHP", $text);    // Case-insensitive

// Trim
trim("  spaces  ");       // "spaces"
ltrim(); rtrim();                  // Left/right only

?>

substr dengan Index Negatif

substr menerima index negatif untuk menghitung dari belakang — sangat berguna untuk ekstensi file, dsb:

php
<?php

$file = "laporan-2026.pdf";

// 4 karakter terakhir = ekstensi
$ekstensi = substr($file, -4);
echo $ekstensi;  // .pdf

// Ambil semua kecuali 4 karakter terakhir
$nama_tanpa_ekstensi = substr($file, 0, -4);
echo $nama_tanpa_ekstensi;  // laporan-2026

// Ekstensi dinamis: cari posisi titik terakhir
$posisi_titik = strrpos($file, ".");
$ekstensi2 = substr($file, $posisi_titik + 1);
echo $ekstensi2;  // pdf

?>

str_replace dengan Array

str_replace bisa mengganti banyak pasangan sekaligus dengan array:

php
<?php

$teks = "Hari ini cuaca cerah di Bandung";

// Ganti banyak kata sekaligus
$hasil = str_replace(
    ["cerah", "Bandung"],
    ["mendung", "Surabaya"],
    $teks
);

echo $hasil;  // Hari ini cuaca mendung di Surabaya

// Penghitungan jumlah penggantian
$jumlah = 0;
str_replace("a", "o", "banana", $jumlah);
echo $jumlah;  // 3 (huruf "a" muncul 3 kali)

?>

Trim: Lebih dari Sekadar Spasi

php
<?php

// Trim menghapus whitespace: spasi, tab, newline
$input = "  \t data penting \n ";
echo trim($input);  // "data penting"

// Karakter khusus bisa ditentukan sendiri
$teks = "...Halo...";
echo trim($teks, ".");  // Halo

// ltrim = kiri saja, rtrim = kanan saja
echo ltrim("  kiri  ");  // "kiri  "
echo rtrim("  kanan ");  // "  kanan"

?>

Case Functions

php
<?php

$text = "Hello World";

strtolower($text);       // "hello world"
strtoupper($text);       // "HELLO WORLD"
ucfirst($text);          // "Hello world"
lcfirst($text);          // "hELLO wORLD"
ucwords($text);          // "Hello World"

?>

Fungsi case sangat berguna untuk normalisasi input:

php
<?php

$email_input = "  ANDI@GMAIL.COM ";

// Normalisasi: trim + lowercase -> simpan ke database
$email_bersih = strtolower(trim($email_input));
echo $email_bersih;  // andi@gmail.com

// Nama dengan kapital di tiap kata
$nama = "budi santoso";
echo ucwords($nama);  // Budi Santoso

// ucfirst: kapital hanya di huruf pertama
$judul = "pemrograman web";
echo ucfirst($judul);  // Pemrograman web

?>
💡Tip

Email dan username harus dinormalisasi (lowercase + trim) sebelum disimpan — ini mencegah duplikasi akun "Andi@mail.com" vs "andi@mail.com".

Format & Join

php
<?php

// Explode - string to array
$csv = "apple,banana,cherry";
$fruits = explode(",", $csv);  // ["apple", "banana", "cherry"]

// Implode - array to string
implode(", ", $fruits);  // "apple, banana, cherry"
join(" - ", $fruits);    // "apple - banana - cherry"

// Pad
str_pad("42", 5, "0", STR_PAD_LEFT);  // "00042"

// Repeat
str_repeat("*", 10);  // "**********"

?>

explode dan implode — Pasangan Serasi

php
<?php

// explode: string -> array (berdasarkan delimiter)
$tanggal = "2026-08-12";
$bagian = explode("-", $tanggal);
print_r($bagian);
// Output:
// Array
// (
//     [0] => 2026
//     [1] => 08
//     [2] => 12
// )

// Limit: maksimal 2 bagian
$nama = "Andi Pratama Wijaya";
$potong = explode(" ", $nama, 2);
print_r($potong);  // ["Andi", "Pratama Wijaya"]

// implode: array -> string
$kata = ["Halo", "dunia", "PHP"];
echo implode(" ", $kata);  // Halo dunia PHP

// Contoh nyata: query string
$params = ["page" => 2, "limit" => 10];
echo http_build_query($params);  // page=2&limit=10

?>

str_pad untuk Format Angka

php
<?php

// Nomor invoice selalu 5 digit
$nomor = 42;
echo str_pad($nomor, 5, "0", STR_PAD_LEFT);  // 00042

// Jam digital 2 digit
echo str_pad(7, 2, "0", STR_PAD_LEFT);  // 07

// Pad kanan untuk tabel teks
echo str_pad("Nama", 10, ".") . "|";
// Output: Nama......|

?>

Fungsi Multibyte (mb_*)

Teks Indonesia jarang masalah, tapi begitu ada emoji atau aksara non-ASCII, fungsi string biasa bisa merusak data karena mereka bekerja per byte, bukan per karakter:

php
<?php

$teks = "Halo 😀 dunia";

// strlen menghitung BYTE — emoji 😀 butuh 4 byte!
echo strlen($teks);   // 15 (bukan 12 karakter)
echo mb_strlen($teks); // 12 (jumlah karakter sebenarnya)

// substr bisa memotong di tengah byte -> karakter rusak
echo substr($teks, 5, 1);     // bisa menghasilkan karakter aneh
echo mb_substr($teks, 5, 1);  // 😀 (utuh)

// lowercase untuk teks dengan aksara
echo mb_strtolower("HÉLLO");   // héllo (benar)
echo strtolower("HÉLLO");      // hÉLLO (salah, É tidak diproses)

?>
⚠️Perhatian

Untuk aplikasi yang menangani teks user (nama, komentar, pesan), gunakan fungsi mb_* (mb_strlen, mb_substr, mb_strtolower) — fungsi biasa bisa memotong emoji/aksara menjadi karakter rusak.

Common Mistakes

Mistake 1: Melupakan bahwa fungsi string mengembalikan nilai baru

php
<?php

$nama = "andi";

// ❌ Tidak menyimpan hasil
strtoupper($nama);
echo $nama;  // andi — tidak berubah!

// ✅
$nama = strtoupper($nama);
echo $nama;  // ANDI

?>

Mistake 2: strpos + truthiness (sudah dibahas di atas)

php
<?php

$teks = "PHP itu seru";

// ❌ Posisi 0 lolos sebagai false
if (strpos($teks, "PHP")) {
    echo "Ketemu";
} else {
    echo "Tidak ketemu";  // ❌ padahal "PHP" ada di index 0!
}

// ✅
if (strpos($teks, "PHP") !== false) {
    echo "Ketemu";  // Ketemu
}

?>

Mistake 3: explode dengan delimiter yang tidak ada

php
<?php

$teks = "tanpa-koma";

// Jika delimiter tidak ada, seluruh string jadi 1 elemen
$hasil = explode(",", $teks);
print_r($hasil);  // ["tanpa-koma"]

// Jangan asumsi jumlah elemen!
// $a = $hasil[1];  // ❌ Undefined array key 1

?>

Mistake 4: Menghitung karakter dengan strlen untuk teks unicode

php
<?php

$nama = "José";

echo strlen($nama);    // 5 (é butuh 2 byte di UTF-8!)
echo mb_strlen($nama); // 4 (karakter sebenarnya)

// Kalau batas "maksimal 10 karakter" dipakai strlen,
// user dengan nama beraksara dihitung tidak adil.

?>

Pro Tips

  1. Rantai fungsi sering dipakai: strtolower(trim($input)) — baca dari dalam ke luar.
  2. Normalisasi input (trim + lowercase) sebelum validasi dan simpan.
  3. str_contains untuk pengecekan di PHP 8+; strpos !== false untuk PHP 7.
  4. mb_* untuk teks user — jangan remehkan emoji dan aksara.
  5. Gunakan implode + explode untuk membangun/memecah format data (CSV, tag, slug).
  6. Periksa dokumentasi PHP untuk function yang jarang dipakai — banyak parameter opsional berguna (misal limit di explode).

Exercise

  1. Buat function untuk capitalize setiap kata
  2. Parse CSV string dengan explode
  3. Buat slug dari judul: "Hello World" -> "hello-world"
  4. Ambil ekstensi file dari "foto-profil.JPG" (hasil akhir: "jpg" lowercase) menggunakan strrpos + substr + strtolower.
  5. Normalisasi daftar email [" ANDI@Gmail.COM ", "budi@yahoo.com", ""] — tampilkan versi bersih, buang yang kosong.
  6. Buat function singkatan(string $nama): string yang mengembalikan inisial, misal "Andi Pratama" -> "AP" (petunjuk: explode + substr).

Summary

KategoriFungsiKegunaan
Panjangstrlen, mb_strlenJumlah karakter
Posisistrpos, stripos, strrposIndex kemunculan
Cek (PHP 8)str_contains, str_starts_with, str_ends_withBoolean check
Potongsubstr, mb_substrEkstrak bagian
Gantistr_replace, str_ireplaceReplace string
Bersihkantrim, ltrim, rtrimHapus whitespace/karakter
Casestrtolower, strtoupper, ucfirst, ucwordsFormat huruf
Pecah/gabungexplode, implode/joinString <-> array
Formatstr_pad, str_repeatPadding & pengulangan

Klik tombol ini setelah menyelesaikan materi

📝

Quiz Bab 7

Uji pemahamanmu tentang String Manipulation