Cara Membuat Judul Artikel Menjadi Alamat URL

Kemarin ada pertanyaan menarik di grup Facebook “PHP Indonesia”. Pertanyaannya begini:

Bagaimana cara membuat judul artikel menjadi alamat URL / slug.

Mungkin yang dimaksud slug adalah URL alias seperti permalink di WordPress. Misalkan seperti ini:
https://www.mawan.id/malaikat-kecil
https://www.mawan.id/harga-dirimu-tidak-abadi

malaikat-kecil dan harga-dirimu-tidak-abadi adalah slug atau URL alias. Secara fisik, di server tidak ada folder atau nama file seperti itu.

Manfaat URL alias kabarnya adalah bisa meningkatkan peringkat di mesin pencari Google. Tapi yang jelas, URL alias bisa memudahkan peng-index-an, memperbaiki keterbacaan, dan meningkatkan relevansi pencarian.

Ngomong-ngomong tentang mesin pencari, sepertinya ke depan pencarian akan lebih banyak memakai AI seperti Google Bart dan Microsoft Bing Chat. Malah bisa jadi, Google Search akan mengikuti jejak Yahoo Search dan Altavista yang telah terlebih dulu masuk museum sejarah Internet.

Native PHP

Ok. Kembali ke laptop. Saya coba menjawab pertanyaan di atas memakai Native PHP, karena bila paham algoritmanya (logikanya), maka mudah pula diterapkan di bahasa pemrograman lain, termasuk framework bahasa pemrograman.

Untuk mewujudkan keinginan seperti itu, maka kita harus membuat setting yang benar pada web server (misalkan Apache atau Nginx). Kita bisa menyalin atau memodifikasi setting untuk WordPress, karena tujuannya mirip.

Berikut ini adalah contoh Nginx Server Block.

server {
  listen 80;
  listen [::]:80;

  server_name cumacontoh.my.id www.cumacontoh.my.id;
  root /var/www/cumacontoh.my.id;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ \.php$ {
    include       fastcgi_params;
    fastcgi_pass  unix:/var/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}

Simpan di (pilih salah satu):

  • /etc/nginx/conf.d
  • /etc/nginx/sites-available kemudian dibuatkan tautan simbolik di /etc/nginx/sites-enabled

Saya lebih suka memakai pilihan pertama.

Reload Nginx.

sudo nginx -s reload

Setelah itu, buat file index,php di folder /var/www/cumacontoh.my.id

Inti Algoritma

Kunci mengubah judul artikel menjadi URL adalah dengan mengubah:

  1. Huruf besar menjadi huruf kecil.
  2. Huruf kecil dan angka tidak diubah.
  3. Simbol diubah menjadi strip (-).

Cara termudah adalah dengan memakai regex:

preg_replace('/[^a-z0-9]+/i', '-', strtolower($judul));

Sedangkan untuk mengembalikan dari slug menjadi judul artikel, kita memakai fungsi:

$param = explode('/', $_SERVER['REQUEST_URI']);

Misalkan:
https://localhost/satu/dua/tiga

Maka hasilnya adalah:
$param[1] = “satu”
$param[2] = “dua”
$param[3] = “tiga”

Untuk mengetahui judul artikel yang sebenarnya, maka cukup bandingkan isi $param[1] dengan judul artikel di database.

Tidak usah bertele-tele, langsung saja ke kode program seutuhnya. Kodenya seperti ini. Simpan dengan nama index.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Cara Membuat Judul Artikel Menjadi Alamat URL</title>
</head>
<body>
<?php
  $database = array(
    '',
    'Ini Artikel ke 1 tentang Apel',
    'Ini Artikel ke 2 tentang Belimbing',
    'Ini Artikel ke 3 tentang Cempedak',
    'Ini Artikel ke 4 tentang Delima',
  );

  $uri = $_SERVER['REQUEST_URI'];
  $param = explode('/', $uri);

  // $param[1] akan empty bila yang dibuka adalah beranda (site home).
  // Selain itu akan berisi judul artikel.

  $judul = null;
  // Mencari judul.
  // Di sini saya memakai array.
  // Pada aplikasi sesungguhnya (production), gunakan database.
  foreach ($database as $value) {
    if ($param[1] == preg_replace('/[^a-z0-9]+/i', '-', strtolower($value))) {
      $judul = $value;
      break;
    };
  };

  if (is_null($judul)) {
    echo '<p>Error: Artikel tidak ditemukan.</p>';
  }
  elseif (empty($judul)) {
    echo '<h1>Beranda</h1>';
    echo '<p>Selamat datang di website contoh mengubah judul artikel menjadi slug.</p>';
  }
  else {
    echo "<h1>$judul</h1>";
    echo "<p>Ini isi dari artikel di atas. Lorem ipsum dulur si Amed.</p>";
  };

  echo '<ol>';
  foreach ($database as $judul) {
    echo '<li>';
    if (empty($judul)) {
      echo '<a href="/">Beranda</a>';
    }
    else {
      echo '<a href="';
      echo preg_replace('/[^a-z0-9]+/i', '-', strtolower($judul));
      echo '">';
      echo $judul;
      echo '</a>';
    };
    echo '</li>';
  };
  echo '</ol>';
?>

<hr>
<p>Kembali ke <a href="https://www.mawan.net/2023/04/30/cara-membuat-judul-artikel-menjadi-alamat-url/">Mawan.NET</a></p>
</body>
</html>

Agar mudah dipahami dan dipraktikkan, script ini tidak memakai database. Saya memakai array sebagai penggantinya. Tapi untuk production, sebaiknya artikel disimpan di database, kemudian foreach diganti menjadi perintah select.

Satu hal penting yang harus selalu diingat adalah: Jangan pernah mempercayai input dari user, dalam hal ini adalah URL alias atau Slug. Bila hendak digunakan di query, selalu amankan memakai prepared statement. Bila hendak ditampilkan di halaman web, selalu difilter dengan htmlentities.

Tentang prepared statement, anda bisa mempelajari di artikel saya yang lain yang berjudul Begini Penggunaan PDO Yang Benar.

Sila dicoba dicek hasil script di atas di https://www.cumacontoh.my.id

Laravel

Bagaimana bila memakai framework PHP? Malah lebih mudah. Pada Laravel, untuk mengubah judul menjadi URL Alias / Slug, kita bisa memakai kode berikut ini:

use Illuminate\Support\Str;

$slug = Str::slug($judul);

Sedangkan pada bagian routing (file /routes/web.php), kodenya seperti ini:

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\DB;

Route::view('/', 'beranda');

Route::get('/{slug}', function ($slug) {
  // SELECT * FROM artikel
  // WHERE REGEXP_REPLACE(LOWER(judul), '[^a-z0-9]+', '-') = 'artikel-ke-1';
  $artikel = DB::table('artikel')
  ->whereRaw("REGEXP_REPLACE(LOWER(judul), '[^a-z0-9]+', '-') = ?", [$slug])
  ->first();
  if ($artikel) {
    return view('artikel', ['artikel' => $artikel]);
  }
  else {
    return view('notfound');
  }
});

Saya sengaja membuat kode yang sederhana agar mudah dipahami. Jangan lupa buat juga file-file beranda.blade.php, artikel.blade.php, dan notfound.blade.php di folder /resources/views.

Pada contoh ini, slug otomatis mengikuti judul artikel, sehingga pada tabel ‘artikel’ tidak diperlukan kolom ‘slug’. Tapi pada production di mana artikelnya banyak dan pengunjung padat, sebaiknya dibuat kolom ‘slug’ kemudian di-index agar beban pencarian record tidak terlalu berat.

Semoga artikel ini bermanfaat.

Web Hosting

Leave a Reply