Strings #
PHP memiliki lebih dari 100 fungsi bawaan untuk memanipulasi string — dari yang sangat sederhana seperti strlen() hingga yang kompleks seperti similar_text() dan levenshtein(). Tidak semua perlu dihapal, tapi ada sekumpulan fungsi inti yang hampir selalu muncul di kode PHP sehari-hari. Artikel ini membahas fungsi-fungsi string paling penting secara terorganisir — bukan sekadar daftar, tapi disertai konteks kapan dan bagaimana menggunakannya, termasuk fungsi mb_ untuk string multibyte (UTF-8, emoji, karakter Asia) yang wajib digunakan ketika berhadapan dengan teks non-ASCII.
Informasi Dasar String #
<?php
$teks = " Halo, Dunia PHP! ";
// Panjang string — dalam BYTE, bukan karakter
echo strlen($teks); // 20
// Panjang dalam karakter (benar untuk UTF-8)
echo mb_strlen($teks); // 20 (sama jika semua ASCII)
echo mb_strlen("日本語"); // 3 karakter (tapi 9 byte!)
echo strlen("日本語"); // 9 byte
// Cek apakah string kosong
var_dump($teks === ''); // false
var_dump(empty($teks)); // false
var_dump(empty('')); // true
var_dump(empty('0')); // true — jebakan!
Pencarian dan Pemeriksaan #
<?php
$teks = "The quick brown fox jumps over the lazy dog";
// str_contains — PHP 8.0+, cek keberadaan substring
var_dump(str_contains($teks, 'fox')); // true
var_dump(str_contains($teks, 'cat')); // false
var_dump(str_contains($teks, '')); // true — string kosong selalu ada
// str_starts_with dan str_ends_with — PHP 8.0+
var_dump(str_starts_with($teks, 'The')); // true
var_dump(str_starts_with($teks, 'the')); // false — case-sensitive!
var_dump(str_ends_with($teks, 'dog')); // true
var_dump(str_ends_with($teks, 'Dog')); // false
// strpos — posisi kemunculan pertama (0-based), false jika tidak ada
$posisi = strpos($teks, 'fox');
var_dump($posisi); // int(16)
// ANTI-PATTERN: perbandingan longgar dengan false
if (strpos($teks, 'fox') == false) { } // salah! posisi 0 == false juga true!
// BENAR: gunakan === false
if (strpos($teks, 'fox') === false) {
echo "Tidak ditemukan\n";
}
// Atau lebih baik lagi, gunakan str_contains (PHP 8.0+)
if (!str_contains($teks, 'fox')) {
echo "Tidak ditemukan\n";
}
// strrpos — posisi kemunculan TERAKHIR
$url = 'https://example.com/path/to/file.php';
$pos = strrpos($url, '/');
$file = substr($url, $pos + 1); // "file.php"
// substr_count — hitung kemunculan substring
echo substr_count("banana", "an"); // 2
echo substr_count("hello world", "l"); // 3
// Pencarian case-insensitive
$pos = stripos("Halo DUNIA", "dunia"); // 5
var_dump(str_contains(strtolower($teks), 'fox')); // cara portable case-insensitive
Pencarian dan Penggantian #
<?php
// str_replace — ganti semua kemunculan
$hasil = str_replace('fox', 'cat', "The fox and the fox");
// "The cat and the cat"
// Ganti banyak sekaligus — array ke array
$bersih = str_replace(
['<script>', '</script>', 'javascript:', 'onclick'],
['', '', '', ''],
$inputUser
);
// str_ireplace — case-insensitive
$hasil = str_ireplace('HELLO', 'Halo', "HELLO world Hello"); // "Halo world Halo"
// substr_replace — ganti di posisi tertentu
$teks = "Hello World";
$hasil = substr_replace($teks, 'PHP', 6, 5); // "Hello PHP"
// ganti 5 karakter mulai posisi 6
// preg_replace — ganti dengan regex
$bersih = preg_replace('/\s+/', ' ', "ada spasi berlebih");
// "ada spasi berlebih"
$slug = preg_replace('/[^a-z0-9]+/', '-', strtolower("Halo Dunia PHP!"));
// "halo-dunia-php-"
$slug = trim($slug, '-'); // "halo-dunia-php"
// str_repeat — ulangi string
echo str_repeat('=', 40); // ========================================
echo str_repeat('ab', 3); // ababab
// strtr — ganti karakter satu per satu (berguna untuk transliterasi)
$dari = 'áàâäãåéèêëíìîïóòôöõúùûüý';
$ke = 'aaaaaaeeeeeiiiiooooouuuuy';
$bersih = strtr($teks, $dari, $ke);
// Atau dengan array mapping
$hasil = strtr("Hello World", ['Hello' => 'Halo', 'World' => 'Dunia']);
// "Halo Dunia"
Pemisahan dan Penggabungan #
<?php
// explode — pisah string menjadi array
$csv = "apel,mangga,jeruk,anggur";
$buah = explode(',', $csv);
// ['apel', 'mangga', 'jeruk', 'anggur']
// Dengan limit — maksimal N elemen, sisa digabung di elemen terakhir
$terbatas = explode(',', $csv, 2);
// ['apel', 'mangga,jeruk,anggur']
// Limit negatif — hapus N elemen terakhir
$tanpaTerakhir = explode(',', $csv, -1);
// ['apel', 'mangga', 'jeruk']
// implode / join — gabungkan array menjadi string
$teks = implode(', ', $buah); // "apel, mangga, jeruk, anggur"
$teks = implode(' | ', $buah); // "apel | mangga | jeruk | anggur"
$teks = implode('', ['a', 'b', 'c']); // "abc"
// str_split — pecah string ke array per N karakter
$chars = str_split("Hello"); // ['H', 'e', 'l', 'l', 'o']
$chunks = str_split("Hello World", 3); // ['Hel', 'lo ', 'Wor', 'ld']
// chunk_split — pecah dengan separator (berguna untuk base64)
$base64 = base64_encode(file_get_contents('image.jpg'));
$wrapped = chunk_split($base64, 76, "\n"); // wrap tiap 76 karakter
// wordwrap — bungkus teks panjang
$paragraf = "Ini adalah teks yang sangat panjang dan perlu dibungkus pada lebar tertentu.";
$terbungkus = wordwrap($paragraf, 40, "\n", true);
Manipulasi Case #
<?php
$teks = "hello world php programming";
// Konversi case dasar
echo strtoupper($teks); // HELLO WORLD PHP PROGRAMMING
echo strtolower("HELLO"); // hello
// Kapitalisasi
echo ucfirst($teks); // Hello world php programming
echo lcfirst("HELLO"); // hELLO
echo ucwords($teks); // Hello World Php Programming
// Untuk multibyte (karakter non-ASCII)
echo mb_strtoupper("héllo wörld", 'UTF-8'); // HÉLLO WÖRLD
echo mb_strtolower("HÉLLO WÖRLD", 'UTF-8'); // héllo wörld
echo mb_convert_case("héllo wörld", MB_CASE_TITLE, 'UTF-8'); // Héllo Wörld
// camelCase → snake_case
function camelToSnake(string $teks): string
{
return strtolower(preg_replace('/(?<!^)(?=[A-Z])/', '_', $teks));
}
echo camelToSnake('camelCaseString'); // camel_case_string
echo camelToSnake('getUserById'); // get_user_by_id
// snake_case → camelCase
function snakeToCamel(string $teks): string
{
return lcfirst(str_replace('_', '', ucwords($teks, '_')));
}
echo snakeToCamel('snake_case_string'); // snakeCaseString
echo snakeToCamel('get_user_by_id'); // getUserById
Trimming dan Padding #
<?php
$teks = " Halo Dunia ";
// trim — hapus whitespace dari kedua sisi
echo trim($teks); // "Halo Dunia"
echo ltrim($teks); // "Halo Dunia " (kiri saja)
echo rtrim($teks); // " Halo Dunia" (kanan saja)
// trim dengan karakter kustom
echo trim("***Halo***", "*"); // "Halo"
echo trim("/path/to/dir/", "/"); // "path/to/dir"
// str_pad — padding untuk alignment
echo str_pad("42", 5, "0", STR_PAD_LEFT); // "00042"
echo str_pad("Halo", 10, "-", STR_PAD_BOTH); // "---Halo---"
echo str_pad("PHP", 10, " ", STR_PAD_RIGHT); // "PHP "
// Tabel yang rapi dengan str_pad
$items = [
['nama' => 'Laptop', 'harga' => 15000000],
['nama' => 'Mouse', 'harga' => 250000],
['nama' => 'Monitor', 'harga' => 5000000],
];
foreach ($items as $item) {
echo str_pad($item['nama'], 10) . str_pad(number_format($item['harga']), 12, ' ', STR_PAD_LEFT) . "\n";
}
// Laptop 15,000,000
// Mouse 250,000
// Monitor 5,000,000
Substring dan Ekstraksi #
<?php
$teks = "Hello, World!";
// substr — ambil bagian string
echo substr($teks, 7); // "World!" (dari posisi 7)
echo substr($teks, 7, 5); // "World" (5 karakter dari posisi 7)
echo substr($teks, -6); // "World!" (6 dari belakang)
echo substr($teks, -6, 5); // "World" (5 karakter, 6 dari belakang)
// mb_substr — untuk multibyte
echo mb_substr("日本語テスト", 2, 3); // "語テス" (3 karakter mulai posisi 2)
// strstr — ambil dari posisi substring ditemukan
$email = "[email protected]";
echo strstr($email, '@'); // "@example.com" (termasuk delimiter)
echo strstr($email, '@', true); // "budi" (sebelum delimiter — before=true)
// strrchr — dari kemunculan TERAKHIR
$path = "/var/www/html/index.php";
echo strrchr($path, '/'); // "/index.php"
echo ltrim(strrchr($path, '/'), '/'); // "index.php"
// basename() lebih baik untuk path:
echo basename($path); // "index.php"
echo basename($path, '.php'); // "index"
echo dirname($path); // "/var/www/html"
echo pathinfo($path, PATHINFO_EXTENSION); // "php"
Formatting dan Output #
<?php
// sprintf — format string
$nama = 'Budi';
$nilai = 95.67;
$rank = 3;
echo sprintf("Nama: %-15s Nilai: %06.2f Rank: %d", $nama, $nilai, $rank);
// "Nama: Budi Nilai: 095.67 Rank: 3"
// Format specifiers yang sering dipakai:
// %s — string
// %d — integer desimal
// %f — float (default 6 desimal)
// %.2f — float 2 desimal
// %05d — integer 5 digit dengan leading zero
// %-10s — string kiri-rata 10 char
// %10s — string kanan-rata 10 char
// number_format — format angka dengan separator ribuan
echo number_format(1234567.891); // "1,234,568"
echo number_format(1234567.891, 2); // "1,234,567.89"
echo number_format(1234567.891, 0, ',', '.'); // "1.234.568" (format Indonesia)
echo "Rp " . number_format(15000000, 0, ',', '.'); // "Rp 15.000.000"
// printf — seperti sprintf tapi langsung print
printf("Total: Rp %s\n", number_format(15000000, 0, ',', '.'));
// vsprintf / vprintf — dari array argumen
$args = ['Budi', 28, 'Jakarta'];
$teks = vsprintf("Nama: %s, Umur: %d, Kota: %s", $args);
// money_format sudah deprecated — gunakan NumberFormatter
$fmt = new NumberFormatter('id_ID', NumberFormatter::CURRENCY);
echo $fmt->format(15000000); // "Rp15.000.000,00"
echo $fmt->formatCurrency(15000000, 'IDR'); // "Rp15.000.000,00"
Hashing dan Enkripsi #
<?php
// Hash satu arah
echo md5("password"); // 5f4dcc3b5aa765d61d8327deb882cf99 — JANGAN untuk password!
echo sha1("password"); // 5baa61e4c9b93f3f0682250b6cf8331b57ff68 — JANGAN!
echo hash('sha256', "data"); // hash SHA-256
echo hash('sha512', "data"); // hash SHA-512
// Hash yang benar untuk password
$hash = password_hash('rahasia123', PASSWORD_BCRYPT);
var_dump(password_verify('rahasia123', $hash)); // true
var_dump(password_verify('salah', $hash)); // false
// Cek apakah hash perlu di-rehash (jika algoritma berubah)
if (password_needs_rehash($hash, PASSWORD_BCRYPT)) {
$hash = password_hash('rahasia123', PASSWORD_BCRYPT); // rehash
}
// HMAC — hash dengan kunci rahasia (untuk verifikasi integritas)
$secret = 'kunci-rahasia-aplikasi';
$payload = json_encode(['user_id' => 42, 'exp' => time() + 3600]);
$hmac = hash_hmac('sha256', $payload, $secret);
// Verifikasi HMAC — gunakan hash_equals untuk timing-safe comparison
$valid = hash_equals($hmac, hash_hmac('sha256', $payload, $secret));
// Enkripsi dua arah (symmetric)
$kunci = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$encrypted = sodium_crypto_secretbox('pesan rahasia', $nonce, $kunci);
$decrypted = sodium_crypto_secretbox_open($encrypted, $nonce, $kunci);
echo $decrypted; // "pesan rahasia"
// Encode/decode
echo base64_encode("data biner atau teks");
echo base64_decode("ZGF0YSBiaW5lciBhdGF1IHRla3M=");
// URL encoding
echo urlencode("harga=Rp 15.000 & nama=Budi");
// "harga%3DRp+15.000+%26+nama%3DBudi"
echo rawurlencode("harga=Rp 15.000 & nama=Budi");
// "harga%3DRp%2015.000%20%26%20nama%3DBudi" (RFC 3986 compliant)
$decoded = urldecode("harga%3DRp+15.000");
Fungsi Multibyte (mb_) #
Untuk semua operasi string yang melibatkan karakter non-ASCII (UTF-8, Unicode), selalu gunakan fungsi mb_ daripada fungsi string biasa:
<?php
$teks = "Héllo Wörld 日本語 😀";
// mb_ equivalents
echo mb_strlen($teks, 'UTF-8'); // 18 karakter
echo mb_strtoupper($teks, 'UTF-8'); // HÉLLO WÖRLD 日本語 😀
echo mb_substr($teks, 6, 5, 'UTF-8'); // Wörld
echo mb_strpos($teks, 'Wörld', 0, 'UTF-8'); // 6
// Set encoding default untuk semua fungsi mb_
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');
// Setelah set internal encoding, bisa tanpa argumen encoding:
echo mb_strlen($teks); // 18
echo mb_strtolower($teks); // héllo wörld 日本語 😀
// Deteksi encoding
$encoding = mb_detect_encoding($teks, ['UTF-8', 'ISO-8859-1', 'Windows-1252']);
// Konversi encoding
$utf8 = mb_convert_encoding($latin1String, 'UTF-8', 'ISO-8859-1');
$latin1 = mb_convert_encoding($utf8String, 'ISO-8859-1', 'UTF-8');
// mb_convert_variables — konversi seluruh variabel
mb_convert_variables('UTF-8', 'ISO-8859-1', $array); // konversi semua elemen array
// Fungsi mb_ yang penting:
// mb_strlen — panjang dalam karakter
// mb_substr — substring
// mb_strpos — posisi substring
// mb_strrpos — posisi terakhir
// mb_strtolower — lowercase
// mb_strtoupper — uppercase
// mb_convert_case — konversi case dengan mode
// mb_str_split — split ke array karakter (PHP 7.4+)
$chars = mb_str_split("日本語"); // ['日', '本', '語']
Fungsi Perbandingan dan Similaritas #
<?php
// strcmp — perbandingan binary-safe, return 0 jika sama
$cmp = strcmp("apple", "banana"); // negatif (apple < banana)
$cmp = strcmp("banana", "apple"); // positif
$cmp = strcmp("apple", "apple"); // 0
// strcasecmp — case-insensitive
var_dump(strcasecmp("HELLO", "hello")); // int(0)
// strncmp — bandingkan N karakter pertama
var_dump(strncmp("hello world", "hello PHP", 5)); // int(0) — 5 karakter pertama sama
// similar_text — persentase kemiripan dua string
similar_text("Hello", "World", $persen);
echo round($persen, 1) . "%"; // 40%
similar_text("Budi Santoso", "Budi Hartono", $persen);
echo round($persen, 1) . "%"; // 75%
// levenshtein — jumlah operasi edit minimum
echo levenshtein("kitten", "sitting"); // 3
echo levenshtein("laptp", "laptop"); // 1 — satu insertion
// soundex dan metaphone — phonetic matching
echo soundex("Robert"); // R163
echo soundex("Rupert"); // R163 — sama!
echo metaphone("Smith"); // SM0
echo metaphone("Smythe"); // SM0 — sama!
Ringkasan #
- PHP 8.0+:
str_contains,str_starts_with,str_ends_withmenggantikanstrpos() !== falseyang verbose dan rawan bug jika tidak menggunakan===.strpos()mengembalikanfalseatau integer — selalu gunakan=== falseuntuk mengecek apakah tidak ditemukan. Posisi 0 adalah valid dan sama denganfalsejika dibandingkan dengan==.- Fungsi
mb_untuk teks non-ASCII —strlen("日本語")mengembalikan 9 (byte), bukan 3 (karakter). Selalu gunakanmb_strlen,mb_substr,mb_strtolower, dll. untuk konten multibyte.password_hash+password_verifyuntuk password — jangan pernah gunakanmd5atausha1untuk hash password. GunakanPASSWORD_BCRYPTatauPASSWORD_ARGON2ID.hash_equalsuntuk perbandingan hash secara timing-safe — mencegah timing attack yang bisa mengekspos token melalui perbedaan waktu eksekusi.sprintfuntuk formatting kompleks — lebih bersih dari concatenation berulang saat ada banyak variabel dengan format tertentu.number_format($angka, 0, ',', '.')untuk format Rupiah —0desimal, koma sebagai pemisah desimal, titik sebagai pemisah ribuan.mb_internal_encoding('UTF-8')di bootstrap aplikasi memastikan semua fungsimb_menggunakan UTF-8 secara default tanpa perlu menyebut encoding di setiap pemanggilan.