如何从 laravel 分页的第一页中删除查询字符串页?

How to remove query string page from the first page of laravel pagination?

我正在使用 分页,如下所示:

public function index()
    {
        $jobs = Job::paginate(5);
        return view('job.index', compact('jobs'));
    }

在视图中:

{{ $jobs->links() }}

生成两个典型页面时出现问题:/job/job?page=1这两个页面内容相同。

我想执行任何从分页第一页删除查询字符串 page 的操作。

我尝试了以下方法:

if ($jobs->onFirstPage()){
  $jobs->setPageName('');
} 

但这会破坏分页,即页面链接无法正确加载,所有页面的查询字符串值都会保留。

如果您关心 SEO,请添加规范标签

我不知道...

if($pageNum==1){
    return redirect()->to($path);
}

$pageNum id get Request or urself Class

$path = "/职位"

在您的路线中,为通往您的功能的路线命名:

Route::get('/yourRoute','YourController@foo')->name('yourRouteName');

然后,在控制器的函数中,使用这个:

public function foo() {
    if( request()->page=='1' )
    {
            return redirect()->route('yourRouteName',[$id]);
    }
     else {
            // Your function content
    }
}

我想你可以试试这个:

{{ $jobs->links() }}

{{ $jobs->nextPageUrl() }}

希望这对你有用!

我发现这个问题的有效解决方案是编辑分页模板

首先从项目的根目录使用以下命令发布来自供应商的分页模板:

php artisan vendor:publish --tag=laravel-pagination

现在应该可以在 resources/views/vendor/pagination/default.blade.php 找到一个文件,可以使用 str_replace() 每个页面的 url 和后退导航按钮像下面这样编辑它:

<li><a href="{{str_replace('?page=1','',$paginator->previousPageUrl())}}" title="{{__('Previous')}}" rel="prev">{{$foxPrev}}</a></li>

 <li><a href="{{str_replace('?page=1','',$url)}}">{{ $page }}</a></li>

更新:

?page=10 中发现了一个错误,因此我们应该像下面这样使用 preg_replace 而不是使用 str_replace

<li><a href="{{preg_replace('/\?page=[1]$/','',$url)}}">{{ $page }}</a></li>

更新 2:

如果使用 page 以外的页码参数的任何自定义名称,我们可以将分页器 getter 用于 $pageName 属性,如下所示在分页模板中:

<li><a href="{{preg_replace('/\?'.$paginator->getPageName().'=[1]$/','',$url)}}">{{ $page }}</a></li>

要了解更多关于如何在同一页上使用多个分页或如何从视图中自定义页码参数 $pageName,请查看 this answer

您可以像这样简单地修改视图:

@if ($page==1)
   <a href="{{ str_replace('?page=1', '', $url) }}">{{ $page }}</a>
@else
   <a href="{{ $url }}">{{ $page }}</a>
@endif

您可以扩展 LengthAwarePaginator 方法 url($page)

/**
 * Get the URL for a given page number.
 *
 * @param  int  $page
 * @return string
 */
public function url($page)
{
    if ($page <= 0) {
        $page = 1;
    }

    // If we have any extra query string key / value pairs that need to be added
    // onto the URL, we will put them in query string form and then attach it
    // to the URL. This allows for extra information like sortings storage.
    $parameters = ($page > 1) ? [$this->pageName => $page] : [];

    if (count($this->query) > 0) {
        $parameters = array_merge($this->query, $parameters);
    }

    return rtrim($this->path
        .(Str::contains($this->path, '?') ? '&' : '?')
        .http_build_query($parameters, '', '&')
        .$this->buildFragment(), '?');
}

我发现了以下作品并考虑了 page=10 个问题:

在你export your pagination views之后,进行以下2处修改:

修改 1

替换为:

{{ $paginator->previousPageUrl() }}

有了这个:

{{ preg_replace('/(?:(&|\?)page=[1])(?!\d)/ui','', $paginator->previousPageUrl()) }}

修改 2

替换为:

{{ $url }}

有了这个:

{{ preg_replace('/(?:(&|\?)page=[1])(?!\d)/ui','', $url ) }}

我是这样做的:

{{ $posts->currentPage() == 2 ? route('home') : $posts->previousPageUrl() }}

改进了 Aksi 答案

app/Services/CustomLengthAwarePaginator.php

<?php

namespace App\Services;

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class CustomLengthAwarePaginator extends LengthAwarePaginator
{
    /**
     * Get the URL for a given page number.
     *
     * @param  int  $page
     * @return string
     */
    public function url($page)
    {
        if ($page <= 0) {
            $page = 1;
        }

        // If we have any extra query string key / value pairs that need to be added
        // onto the URL, we will put them in query string form and then attach it
        // to the URL. This allows for extra information like sortings storage.
        $parameters = ($page > 1) ? [$this->pageName => $page] : [];

        if (count($this->query) > 0) {
            $parameters = array_merge($this->query, $parameters);
        }

        return $this->path()
            . (count($parameters) > 0
                ? (Str::contains($this->path(), '?') ? '&' : '?')
                : '')
            . Arr::query($parameters)
            . $this->buildFragment();
    }
}

在 AppServiceProvider.php 或另一个

public function boot()
{
    app()->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class);
}

只需使用此命令创建一个中间件

php artisan make:middleware RemovePageQuery

在中间件中编写这段代码

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RemovePageQuery
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if ($request->page == 1)
        {
            return redirect(url()->current());
        }
        
        return $next($request);
    }
}

在App/Http/Kernel.php里面添加全局中间件$middleware.

 protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\RemovePageQuery::class, //Here
        \App\Http\Middleware\TrustProxies::class,
        \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

我正在寻找解决类似问题以防止内容重复但 symfony 不是 laravel。我以自己的方式修复它并决定发布它。可能会对某人有所帮助。

在 symfony 中,我使用 KNP 分页器。它提供了分页器模板,像这样:

     <a href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>

'Query' 数组包含路由参数,如果它 == 1,任务是删除页面参数。

很简单:

    {% set page_seo = (page == 1) ? null : page %}
    <a href="{{ path(route, query|merge({(pageParameterName): page_seo})) }}">{{ page }}</a>

实际上 - 如果它 == 1,则设置为空页。