Strings

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_with menggantikan strpos() !== false yang verbose dan rawan bug jika tidak menggunakan ===.
  • strpos() mengembalikan false atau integer — selalu gunakan === false untuk mengecek apakah tidak ditemukan. Posisi 0 adalah valid dan sama dengan false jika dibandingkan dengan ==.
  • Fungsi mb_ untuk teks non-ASCIIstrlen("日本語") mengembalikan 9 (byte), bukan 3 (karakter). Selalu gunakan mb_strlen, mb_substr, mb_strtolower, dll. untuk konten multibyte.
  • password_hash + password_verify untuk password — jangan pernah gunakan md5 atau sha1 untuk hash password. Gunakan PASSWORD_BCRYPT atau PASSWORD_ARGON2ID.
  • hash_equals untuk perbandingan hash secara timing-safe — mencegah timing attack yang bisa mengekspos token melalui perbedaan waktu eksekusi.
  • sprintf untuk formatting kompleks — lebih bersih dari concatenation berulang saat ada banyak variabel dengan format tertentu.
  • number_format($angka, 0, ',', '.') untuk format Rupiah0 desimal, koma sebagai pemisah desimal, titik sebagai pemisah ribuan.
  • mb_internal_encoding('UTF-8') di bootstrap aplikasi memastikan semua fungsi mb_ menggunakan UTF-8 secara default tanpa perlu menyebut encoding di setiap pemanggilan.

← Sebelumnya: Memcached   Berikutnya: IO →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact