LoginSignup
9
5

More than 5 years have passed since last update.

PHP7とlaravel5.6でページネーションを実装してみた

Last updated at Posted at 2018-03-28

実際に実装する機能

  • データ(名前、テキスト)入力、保存
  • データ表示
  • ページネーション

ちなみに、laravelはHomesteadを利用しています。

フレームワークを使わないでそのままPHP7で実装

内部の処理画面

setting.php
function showData()
{
    // GETで現在のページ数を取得
    if (isset($_GET['page'])) {
        $page = (int)$_GET['page'];
    } else {
        $page = 1;
    }

    $dbh = new PDO(
     'mysql:dbname=db_name;host=localhost;charset=utf8mb4',
     'dbuser',
     'dbuser',
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]
);

    try {

        // データ抽出処理

        // 10件ずつデータを取得するSQLにて、取り出すときのスタートの位置を計算
        if ($page > 1) {
            $start = ($page * 10) - 10;
        } else {
            $start = 0;
        }

        // DBから過去のデータを1ページに10件ずつ取得
        $sel_sql = "SELECT name,text FROM table_name ORDER BY id desc LIMIT ?, 10 ";
        $sel_prepare = $dbh->prepare($sel_sql);
        $sel_prepare->bindValue(1, $start, PDO::PARAM_INT);
        $sel_prepare->execute();

        // 変数に取得内容の配列を格納
        // front.php内でも使用するため$sel_resultはグローバル宣言
        global $sel_result;
        $sel_result = $sel_prepare->fetchAll(PDO::FETCH_ASSOC);


        // pagination処理

        // 全ページ数を取得するため、DBにあるデータ数を取得
        $page_sql = "SELECT COUNT(*) id FROM table_name";
        $page_num = $dbh->prepare($page_sql);
        $page_num->execute();
        $page_num = $page_num->fetchColumn();

        // 全ページ数を取得
        // 全ページ数:データが12件だったら2ページ、31件だったら4ページ
        // front.php内でも使用するため$paginationはグローバル宣言
        global $pagination;
        $pagination = ceil($page_num / 10);

        // DBの接続を切る
        $dbh = null;

    } catch (PDOException $e) {

        echo 'データの取得が失敗しました。<br>';
        echo $e->getMessage();
        exit;
    }

フロント画面

front.php
<!DOCTYPE HTML>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>タイトル</title>
</head>
<body>
<p>入力してください</p>
<form action="front.php" method="post">
    <span>名前</span><br>
    <input type="text" name="name"><br>
    <span>テキスト</span><br>
    <textarea name="text" rows="10"></textarea><br>
    <input type="submit">
</form>
<br>
<table border="1">
    <thead>
    <th>name</th>
    <th>text</th>
    </thead>
    <tbody>
<?php

    require_once('setting.php');

    showData();

    foreach ($sel_result as $key => $val) {

        $name_before = $val['name'];
        $text_before = $val['text'];

        // 改行を反映させる
        $name_after = nl2br(str_replace('\n', "\n", $name_before));
        $text_after = nl2br(str_replace('\n', "\n", $text_before));


        echo '<tr><td>' . $name_after . ' </td>';
        echo '<td>' . $text_after . '</td></tr>';
    }

    echo '</tbody>';
    echo '</table><br>';

    // 10件ずつわけたページ先のリンクを表示
    for ($x = 1; $x <= $pagination; $x++) {
        echo '<a href="?page=' . $x . '">' . $x . '</a>';
    }


?>

<br>
<br>
</body>
</html>

Screenshot from Gyazo

色々と大変。。

laravel5.6上で実装すると

ルーティング画面

web.php
<?php

Route::get('/', 'PostController@index');
Route::post('/front/post', 'PostController@post');

コントローラー画面

PostController.php
<?php

namespace App\Http\Controllers;

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

class PostController extends Controller
{

    public function index()
    {

    $posts = Post::orderBy('created_at', 'desc')->paginate(10);

    return view('front', [
        'posts' => $posts
    ]);

    }

    public function post(Request $request)
    {

    $post = new Post();
    $post->name = $request->name;
    $post->text = $request->text;
    $post->save();

    return redirect('/');

    }

}

ビュー画面

front.blade.php
@extends('layouts.app')

@section('content')

    <div class="body">
        <div class="top">
        <p>入力してください</p>
        <form action="/front/post" method="post">
            {{ csrf_field() }}
            <span>名前</span><br>
            <input type="text" name="name"><br>
            <span>テキスト</span><br>
            <textarea name="text" rows="10"></textarea><br>
            <input type="submit">
        </form>
        </div>
        <br>
        <br>
        <br>
    {{-- データが取得できれば以下表示 --}}
    @if(count($posts) > 0)
    <div class="posts-table">
        <table border="1">
            <thead>
            <th>name</th>
            <th>text</th>
            </thead>
            <tbody>
            @foreach($posts as $post)
                <tr>
                    {{-- 改行を反映させて表示 --}}
                    <td>{!! nl2br(str_replace('\n', "\n", e($post->name))) !!}</td>
                    <td>{!! nl2br(str_replace('\n', "\n", e($post->text))) !!}</td>
                </tr>
            @endforeach
            </tbody>
        </table>
        {{-- ページリンクを表示 --}}
        {{ $posts->links() }}
    </div>
    @endif
    </div>
@endsection

Screenshot from Gyazo

コントローラー画面に$post = Post::orderBy('created_at', 'desc')->paginate(10);
ビュー画面に{{ $posts->links() }}
を付け加えるだけ。

ただしcssをviewのページで読み込んでいないと、ページネーション部分の見た目が以下のようになってしまう。
スクリーンショット 2018-03-13 15.47.07.png

なのでビューの共通部分でデフォルトで入っているcssを読み込みます。

app.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>タイトル</title>
    <link rel="stylesheet" href="{{ asset('/css/app.css') }}">
</head>

<body>
<div class="container">
    <nav class="navbar navbar-default">
    </nav>
</div>

@yield('content')
</body>
</html>

すると以下のようなページネーションが表示されます。
とっても簡単…!
スクリーンショット 2018-03-13 15.52.12.png

参考

https://readouble.com/laravel/5.6/ja/pagination.html
https://manablog.org/php-pagination/

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5