文章详情URL不使用ID用slug和uuiid代替
在 Laravel 中,可以通过使用 slug
或 UUID
来展示文章详情和文章列表。这样可以提高 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');
这样,你就可以通过 slug
或 UUID
来展示文章列表和文章详情了。选择合适的方法取决于你的具体需求和项目要求。
====
在 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
来展示文章详情。以下是完整的步骤:
- 创建迁移文件,添加
uuid
字段。 - 在模型中设置自动生成
UUID
。 - 更新控制器以通过
uuid
查询文章。 - 在路由文件中定义相应的路由。
这样,你就可以通过 UUID
访问和显示文章详情了。