PHP ve Laravel ile Slug Oluşturma: Kapsamlı Geliştirici Rehberi

PHP ve Laravel framework ile SEO dostu slug oluşturmayı öğrenin. Str::slug helper, Eloquent model events, ve Türkçe karakter desteği için özel çözümler.

PHP dünyasının en popüler framework'ü Laravel, slug oluşturma için güçlü araçlar sunar. Bu rehberde, hem vanilla PHP hem de Laravel ile profesyonel slug implementasyonlarını inceleyeceğiz.

Vanilla PHP ile Slug Oluşturma

Temel Slug Fonksiyonu

<?php
function createSlug(string $text): string
{
    // Türkçe karakter dönüşümü
    $turkishChars = [
        'ş' => 's', 'Ş' => 's', 'ğ' => 'g', 'Ğ' => 'g',
        'ü' => 'u', 'Ü' => 'u', 'ö' => 'o', 'Ö' => 'o',
        'ç' => 'c', 'Ç' => 'c', 'ı' => 'i', 'İ' => 'i'
    ];
    
    $text = strtr($text, $turkishChars);
    $text = mb_strtolower($text, 'UTF-8');
    $text = preg_replace('/[^a-z0-9\s-]/', '', $text);
    $text = preg_replace('/[\s-]+/', '-', $text);
    $text = trim($text, '-');
    
    return $text;
}

// Kullanım
$slug = createSlug('Türkçe Başlık Örneği');
// Çıktı: turkce-baslik-ornegi

Benzersiz Slug Oluşturma

<?php
function createUniqueSlug(PDO $pdo, string $title, string $table = 'posts'): string
{
    $slug = createSlug($title);
    $originalSlug = $slug;
    $counter = 1;
    
    while (slugExists($pdo, $slug, $table)) {
        $slug = $originalSlug . '-' . $counter;
        $counter++;
    }
    
    return $slug;
}

function slugExists(PDO $pdo, string $slug, string $table): bool
{
    $stmt = $pdo->prepare("SELECT COUNT(*) FROM {$table} WHERE slug = ?");
    $stmt->execute([$slug]);
    return $stmt->fetchColumn() > 0;
}

Laravel ile Slug Oluşturma

Str::slug Helper

Laravel'in yerleşik slug helper'ı:

<?php
use Illuminate\Support\Str;

// Temel kullanım
$slug = Str::slug('Hello World');
// Çıktı: hello-world

// Özel ayırıcı
$slug = Str::slug('Hello World', '_');
// Çıktı: hello_world

// Dil desteği
$slug = Str::slug('Türkçe Başlık', '-', 'tr');
// Not: Varsayılan olarak Türkçe desteği sınırlıdır

Türkçe Karakter Desteği

Laravel için özel Türkçe slug macro'su:

<?php
// AppServiceProvider.php
use Illuminate\Support\Str;

public function boot()
{
    Str::macro('turkishSlug', function (string $title, string $separator = '-'): string {
        $turkishChars = [
            'ş' => 's', 'Ş' => 's', 'ğ' => 'g', 'Ğ' => 'g',
            'ü' => 'u', 'Ü' => 'u', 'ö' => 'o', 'Ö' => 'o',
            'ç' => 'c', 'Ç' => 'c', 'ı' => 'i', 'İ' => 'i'
        ];
        
        $title = strtr($title, $turkishChars);
        return Str::slug($title, $separator);
    });
}

// Kullanım
$slug = Str::turkishSlug('Öğrenci Başarı Çizelgesi');
// Çıktı: ogrenci-basari-cizelgesi

Eloquent Model ile Otomatik Slug

Model Events Kullanımı

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Post extends Model
{
    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($post) {
            $post->slug = $post->generateUniqueSlug($post->title);
        });
        
        static::updating(function ($post) {
            if ($post->isDirty('title')) {
                $post->slug = $post->generateUniqueSlug($post->title);
            }
        });
    }
    
    public function generateUniqueSlug(string $title): string
    {
        $slug = Str::turkishSlug($title);
        $originalSlug = $slug;
        $counter = 1;
        
        while (static::where('slug', $slug)
            ->where('id', '!=', $this->id ?? 0)
            ->exists()) {
            $slug = $originalSlug . '-' . $counter;
            $counter++;
        }
        
        return $slug;
    }
    
    public function getRouteKeyName(): string
    {
        return 'slug';
    }
}

HasSlug Trait

<?php
namespace App\Traits;

use Illuminate\Support\Str;

trait HasSlug
{
    protected static function bootHasSlug()
    {
        static::creating(function ($model) {
            $model->slug = $model->generateSlug();
        });
    }
    
    public function generateSlug(): string
    {
        $slugField = $this->slugFrom ?? 'title';
        return Str::turkishSlug($this->{$slugField});
    }
}

// Model'de kullanım
class Article extends Model
{
    use HasSlug;
    
    protected $slugFrom = 'title';
}

Spatie Laravel Sluggable Paketi

composer require spatie/laravel-sluggable
<?php
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;

class Post extends Model
{
    use HasSlug;
    
    public function getSlugOptions(): SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('title')
            ->saveSlugsTo('slug')
            ->doNotGenerateSlugsOnUpdate();
    }
}

Route Model Binding

<?php
// routes/web.php
Route::get('/blog/{post:slug}', [BlogController::class, 'show']);

// Controller
public function show(Post $post)
{
    return view('blog.show', compact('post'));
}

Best Practices

  1. Slug'ları veritabanında unique index olarak tanımlayın
  2. Model events ile otomatik slug oluşturun
  3. Route model binding kullanın
  4. Türkçe ve özel karakterleri düzgün dönüştürün
  5. Slug değişikliklerinde 301 redirect planlayın

Sonuç

Laravel, slug oluşturma için hem yerleşik helper'lar hem de paket desteği sunar. Türkçe karakter desteği için özel macro'lar oluşturarak, SEO dostu URL'ler elde edebilirsiniz.