Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 帖子可以具有相同的标题-具有唯一url的方法无法正常工作_Php_Laravel - Fatal编程技术网

Php 帖子可以具有相同的标题-具有唯一url的方法无法正常工作

Php 帖子可以具有相同的标题-具有唯一url的方法无法正常工作,php,laravel,Php,Laravel,我有下面的路径来显示一个特定的帖子详细信息页面:“{slug}”例如“如果引入的帖子的名称是“testpost” 问题是,可能存在同名的帖子,因此类似“”的url将无法正常工作。因为可以存在更多具有相同“测试帖子”名称的帖子 因此,除了slug之外,还需要在url中添加帖子的id 因此,我有一个post控制器来创建一个新的post,所以我试图在post的slug列中插入带有post id的slug:(我不知道这是否是处理此问题的好方法) 但它似乎是“未定义的类常量'id'”。你知道如何解决这个问

我有下面的路径来显示一个特定的帖子详细信息页面:“{slug}”例如“如果引入的帖子的名称是“testpost”

问题是,可能存在同名的帖子,因此类似“”的url将无法正常工作。因为可以存在更多具有相同“测试帖子”名称的帖子

因此,除了slug之外,还需要在url中添加帖子的id

因此,我有一个post控制器来创建一个新的post,所以我试图在post的slug列中插入带有post id的slug:(我不知道这是否是处理此问题的好方法)

但它似乎是“未定义的类常量'id'”。你知道如何解决这个问题吗

显示FrontController的方法以显示post详细信息视图:

public function show($slug){
        $post = Post::where('slug', $slug)->first();
        return view('post.show')->with('post',$post);
    }
路线:

Route::get('/{slug}', [
    'uses' => 'FrontController@show',
    'as'   =>'show'
]);
乔恩

做到这一点的“Laravel”方法,或者至少是最有效的方法,就是在路由中使用Post的id,而不是slug。因此,如果使用AJAX,只需将$post->id放入数据字段中,并在提交时从javascript中提取它

路线可能是这样的

Route::get("test/{post}", 'Testing\TestController@showTest');
然后在控制器上,您可以通过

$post = Post::find($post);
或者使用路由模型绑定,只需键入控制器函数:

public function showTest(Post $post){ etc }
对于上面关于在slug中设置id的另一个问题,这可能不是一个好方法。。。但是,如果需要,我建议您使用两步流程$post=create();然后$post->slug='slug'。$post->id。同样,这不是最好的方法,但它会起作用

当然,你总是可以通过这条路线传递子弹,但我想首先看看你这样做的目的是什么——这是纯粹的装饰,还是你在寻找一种识别帖子的方法?您总是可以在控制器中添加一个循环,以查找带有该段塞的所有帖子。。。但是发送id要容易得多,您将始终可以访问该id,然后按照上面的方式进行排序

希望这有帮助

$post = Post::create([
    'name' => $request->name,
    ...
    'slug' => str_slug($request->name."-".Post::id)
]);
这不起作用,因为a)模型上没有静态方法
id
,b)在实际将模型保存到数据库之前,无法获取模型的id

一个简单(而且更优雅)的解决方案是检查带有该段代码的帖子是否已经存在,如果已经存在,只在帖子中添加一个数字。这样,大多数(可能)帖子都会有一个url,但没有附加数字

大概是这样的:

// Create a slug
$slug = str_slug($request->name);
if (Post::where('slug', $slug)->first() !== null) {
  $n = 0;
  do {
    // Increase n and append it to the slug
    $newName = $slug . '-' . ++$n;
    // Iterate until the slug is NOT found in the database,
    // which means it's unique 
  } while (Post::where('slug', $newName)->first() !== null);
}

$post = Post::create([
    'name' => $request->name,
    ...
    'slug' => isset($newName) ? $newName : $slug
]);

但可能更好的方法是在slug前面加上用户名(仍然不一定是唯一的)或时间戳或其他东西

在POST可能没有唯一的slug的情况下,您应该遵循Stackoverflow方法,即
/id/slug
,其中slug除了提供友好的视图之外什么都不做

下面是这个实际问题的链接——请注意,slug实际上并不重要。当然,它会用正确的slug重定向到您的问题上,但最初slug不会做任何事情(id会):

stackoverflow.com/questions/49331496/这实际上可以是任何东西

因此,您的代码可能最终看起来像:

public function show($id, $slug){
    $post = Post::find($id)->first();

    // if you want to redirect if the slug doesn't match, like SO
    if($post->slug !== $slug) {
       return redirect()->route('post.show', ['id' => $post->id, 'slug' => $post->slug]);
    }

    return view('post.show')->with('post', $post);
}

Route::get('/{id}/{slug?}', [
    'uses' => 'FrontController@show',
    'as'   =>'post.show'
]);

谢谢你的回答。我不使用AJAX。但是这样的解决方案不可能在url中包含slug?不可能使用slug和id,例如:“?AJAX不重要-打开表单时可以在表单上添加唯一标识符(选中“表单模型绑定”)。回答你的问题,是的,你可以有一个slug和一个id,但这似乎是额外的工作——正如你所说,slug可能不是唯一的。为什么不通过保证的唯一id来实现呢?如果你想把slug推过POST只是为了看看它是什么,你可以1)在控制器中拉入你的模型并检查,或者2)将它与表单一起发送(隐藏或常规),以便它直接显示在控制器中。我不会说这是“Laravel”的方法。在url中有slug的合法使用案例。谢谢,但在该解决方案中,它似乎“缺少[Route:show][URI:{id}/{slug?}]所需的参数”。此外,我还必须将“重定向->路由(…)”更改为“重定向(…)。在重定向时已更新-缺少(),并且“as”应该是“post.show”不是“show”谢谢,但是它在视图文件上出现了错误“缺少[route:posts.show][URI:{id}/{slug?}]”。您正在传递两次“slug”并调用posts(不是post)它应该是
route('post.show',['id'=>$post->id,'slug'=>$post->slug])
注意-重定向也应该是post.show而不是show(更新的答案)
public function show($id, $slug){
    $post = Post::find($id)->first();

    // if you want to redirect if the slug doesn't match, like SO
    if($post->slug !== $slug) {
       return redirect()->route('post.show', ['id' => $post->id, 'slug' => $post->slug]);
    }

    return view('post.show')->with('post', $post);
}

Route::get('/{id}/{slug?}', [
    'uses' => 'FrontController@show',
    'as'   =>'post.show'
]);