文章详情URL不使用ID用slug和uuiid代替

在 Laravel 中,可以通过使用 slugUUID 来展示文章详情和文章列表。这样可以提高 URL 的可读性和安全性。以下是实现方法和代码示例:

方法一:使用 Slug

数据库字段

首先,在 posts 表中添加 slug 字段:

Schema::table('posts', function (Blueprint $table) {
    $table->string('slug')->unique()->comment('文章的唯一别名');
});

模型设置

Post 模型中,确保 slug 字段可以被填充:

class Post extends Model
{
    protected $fillable = ['title', 'content', 'slug'];
    
    // 生成slug的方法
    public static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->slug = Str::slug($post->title);
        });
    }

    // 这里你可以定义更多的方法和关系
}

控制器

在控制器中使用 slug 来查询文章详情:

class PostController extends Controller
{
    // 展示文章列表
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    // 展示单篇文章详情
    public function show($slug)
    {
        $post = Post::where('slug', $slug)->firstOrFail();
        return view('posts.show', compact('post'));
    }
}

路由

在路由文件中定义使用 slug 的路由:

use Illuminate\Support\Facades\Route;

Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{slug}', [PostController::class, 'show'])->name('posts.show');

方法二:使用 UUID

数据库字段

posts 表中添加 uuid 字段:

Schema::table('posts', function (Blueprint $table) {
    $table->uuid('uuid')->unique()->comment('文章的唯一标识符');
});

模型设置

Post 模型中,确保 uuid 字段可以被填充:

use Illuminate\Support\Str;

class Post extends Model
{
    protected $fillable = ['title', 'content', 'uuid'];

    // 生成UUID的方法
    public static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->uuid = (string) Str::uuid();
        });
    }

    // 这里你可以定义更多的方法和关系
}

控制器

在控制器中使用 uuid 来查询文章详情:

class PostController extends Controller
{
    // 展示文章列表
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    // 展示单篇文章详情
    public function show($uuid)
    {
        $post = Post::where('uuid', $uuid)->firstOrFail();
        return view('posts.show', compact('post'));
    }
}

路由

在路由文件中定义使用 uuid 的路由:

use Illuminate\Support\Facades\Route;

Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{uuid}', [PostController::class, 'show'])->name('posts.show');

选择哪种方法

  • Slug:适用于 SEO 友好的 URL,适合公开展示的文章或内容。
  • UUID:适用于需要唯一标识和防止暴力破解的情况,适合保密性要求高的内容。

完整示例

以下是一个完整的示例,展示如何使用 slug

迁移文件

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddSlugToPostsTable extends Migration
{
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->string('slug')->unique()->comment('文章的唯一别名');
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('slug');
        });
    }
}

Post 模型

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

class Post extends Model
{
    protected $fillable = ['title', 'content', 'slug'];

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->slug = Str::slug($post->title);
        });
    }
}

PostController 控制器

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    public function show($slug)
    {
        $post = Post::where('slug', $slug)->firstOrFail();
        return view('posts.show', compact('post'));
    }
}

路由文件

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{slug}', [PostController::class, 'show'])->name('posts.show');

这样,你就可以通过 slugUUID 来展示文章列表和文章详情了。选择合适的方法取决于你的具体需求和项目要求。

====

在 Laravel 中,$table->uuid() 是一种合法的写法,用于创建 UUID 字段。uuid 方法会生成一个 CHAR(36) 类型的字段来存储 UUID。你的写法是正确的。

以下是详细的示例,包括如何创建迁移文件来添加 uuid 字段:

创建迁移文件

创建带 uuid 字段的表

如果你正在创建一个新的表,并希望包含一个 uuid 字段,可以这样写:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->uuid('uuid')->unique()->comment('唯一标识符');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

添加 uuid 字段到现有的表

如果你需要向现有的表中添加 uuid 字段,可以这样写:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddUuidToPostsTable extends Migration
{
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->uuid('uuid')->unique()->comment('唯一标识符')->after('id');
        });
    }

    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropColumn('uuid');
        });
    }
}

在模型中设置 uuid

确保每次创建新的 Post 实例时自动生成 UUID

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

class Post extends Model
{
    protected $fillable = ['title', 'content', 'uuid'];

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->uuid = (string) Str::uuid();
        });
    }
}

控制器和路由

控制器

使用 uuid 来查询文章详情:

use App\Models\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    public function show($uuid)
    {
        $post = Post::where('uuid', $uuid)->firstOrFail();
        return view('posts.show', compact('post'));
    }
}

路由

在路由文件中定义使用 uuid 的路由:

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{uuid}', [PostController::class, 'show'])->name('posts.show');

总结

通过上述配置,你可以在数据库中使用 uuid 字段,并通过 uuid 来展示文章详情。以下是完整的步骤:

  1. 创建迁移文件,添加 uuid 字段。
  2. 在模型中设置自动生成 UUID
  3. 更新控制器以通过 uuid 查询文章。
  4. 在路由文件中定义相应的路由。

这样,你就可以通过 UUID 访问和显示文章详情了。

posted @ 2024-05-15 16:21  Laravel自学开发  阅读(22)  评论(0编辑  收藏  举报