0

0

PHP中实现JSON数据数组分页的教程

DDD

DDD

发布时间:2025-11-29 10:50:02

|

746人浏览过

|

来源于php中文网

原创

PHP中实现JSON数据数组分页的教程

本教程详细介绍了如何使用php为从json文件加载的数据实现分页功能。内容涵盖了json数据的正确解析、从url获取分页参数、计算每页显示的数据范围,以及将这些逻辑整合到现有html输出中,最终实现高效且用户友好的数据展示。

在Web开发中,当需要展示大量数据时,分页是必不可少的功能。它能够将庞大的数据集分解成若干个更小的、易于管理的部分,从而提升页面加载速度和用户体验。本教程将以一个从JSON文件读取博客文章并进行分页显示的场景为例,详细讲解如何在PHP中实现这一功能。

1. JSON数据结构与预处理

首先,我们需要一个结构良好且有效的JSON文件作为数据源。原始问题中提供的JSON示例存在语法错误,特别是在email字段中。一个有效的JSON结构示例如下:

{
  "blogs": {
    "1": {
      "slug": "blog/cfsdgfdgfd",
      "cover_image": "cfsdgfdgfd.jpg",
      "author": {
        "name": "dsfdsaf",
        "image": "fdsafas",
        "email": "fdsafsa"
      },
      "heading": "fdgdfg",
      "excerpt": "sdfdsfdsaf",
      "date_added": "2019-04-25T12:21:31+10:00",
      "date_modified": "2021-12-07T14:05:12+10:00",
      "visible": "1",
      "comments": "0",
      "status": "1"
    },
    "2": {
      "slug": "blog/hxgch",
      "cover_image": "fdghhfd.jpg",
      "author": {
        "name": "fdghf",
        "image": "zhd",
        "email": "kjhgk"
      },
      "heading": "kjhkhjg",
        "excerpt": "hgfdhfd",
      "date_added": "2019-05-09T13:31:04+10:00",
      "date_modified": "2021-12-07T11:40:49+10:00",
      "visible": "1",
      "comments": "0",
      "status": "1"
    }
  }
}

在PHP中,我们使用file_get_contents()读取JSON文件内容,然后使用json_decode()将其解析为PHP数据结构。为了方便后续操作,建议将其解析为关联数组,而不是对象,通过传递true作为json_decode()的第二个参数实现:

$jsonFilePath = 'data/blogs.json'; // 替换为你的JSON文件路径
$fileData = file_get_contents($jsonFilePath);
$jsonData = json_decode($fileData, true); // 解析为关联数组

// 检查JSON解析是否成功
if ($jsonData === null && json_last_error() !== JSON_ERROR_NONE) {
    die("Error parsing JSON: " . json_last_error_msg());
}

// 提取实际的博客文章数据
$allBlogs = $jsonData['blogs'] ?? [];

2. 分页核心逻辑实现

分页的核心在于确定当前页需要显示哪些数据项。这涉及到获取当前页码、定义每页显示数量,并据此计算数据的起始和结束索引。

立即学习PHP免费学习笔记(深入)”;

2.1 获取分页参数

我们通常通过URL查询字符串(例如 ?page=2)来获取当前页码。为了程序的健壮性,需要对获取到的页码进行验证和默认值设置。

ModelGate
ModelGate

一站式AI模型管理与调用工具

下载
$itemsPerPage = 30; // 每页显示的文章数量
$currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1; // 获取当前页码,默认为第一页

// 确保页码不小于1
if ($currentPage < 1) {
    $currentPage = 1;
}

2.2 计算数据索引范围

有了当前页码和每页显示数量,我们可以计算出当前页数据在完整数据集中对应的起始索引和结束索引。

$startIndex = ($currentPage - 1) * $itemsPerPage;
$endIndex = $startIndex + $itemsPerPage;

2.3 筛选并显示当前页数据

现在,我们可以遍历所有博客文章,并结合之前计算出的索引范围来筛选出当前页需要显示的文章。同时,我们还需要保留原始代码中的过滤条件(status === '1', visible === '1', date_added 在当前日期之前)。

$filteredBlogs = [];
foreach ($allBlogs as $blogId => $blogData) {
    // 应用原始的过滤条件
    if ($blogData['status'] === '1' && $blogData['visible'] === '1' && strtotime($blogData['date_added']) <= strtotime(date('r'))) {
        $filteredBlogs[] = $blogData;
    }
}

// 获取符合条件的总文章数
$totalItems = count($filteredBlogs);

// 计算总页数
$totalPages = ceil($totalItems / $itemsPerPage);

// 确保当前页码不超过总页数
if ($currentPage > $totalPages && $totalPages > 0) {
    $currentPage = $totalPages;
    $startIndex = ($currentPage - 1) * $itemsPerPage;
    $endIndex = $startIndex + $itemsPerPage;
}

// 提取当前页的文章
$paginatedBlogs = array_slice($filteredBlogs, $startIndex, $itemsPerPage);

3. 整合数据展示与HTML输出

将上述分页逻辑与原始的HTML输出代码结合。注意,由于我们将JSON解析为关联数组,所以访问数据时需要使用方括号[]而不是箭头->。

foreach ($paginatedBlogs as $values){
    // 注意:原始代码中有一个 `foreach ($data as $key => $values)` 的嵌套循环,
    // 但在处理 `json_decode($fileData, true)` 后的 `$allBlogs` 时,
    // `$values` 已经是单个博客对象的数据,不需要额外的嵌套循环。
    // 如果原始JSON的结构要求,可能需要调整。这里假设 `$values` 直接是博客数据。

    echo '
        <article class="col-12 col-md-6 col-xl-4 mb-4" itemscope itemtype="https://schema.org/Article">
            <div class="blog-article" data-href="{{domain}}/' . strip_tags($values['slug']) . '">
                <link itemprop="image" href="{{cdn}}/uploads/' . str_replace('blog/', '', strip_tags($values['cover_image'])) . '" />
                <picture>
                    <img  itemprop="thumbnailUrl" class="lazy img-fluid" alt="' . strip_tags($values['heading']) . '" title="' . strip_tags($values['heading']) . '" height="253" width="450" />
                </picture>

                <h3 itemprop="headline">' . strip_tags($values['heading']) . '</h3>

                <div class="d-flex align-items-center flex-wrap align-content-start mt-3">
                    <figure>
                        <img  class="lazy" alt="Photo of ' . strip_tags($values['author']['name']) . '" title="Photo of ' . strip_tags($values['author']['name']) . '" height="45" width="45" />
                    </figure>

                    <div class="author" itemprop="author">' . strip_tags($values['author']['name']) . '</div> <time itemprop="datePublished" datetime="' . date('c', strtotime($values['date_added'])) . '" class="date">' . date('d F Y', strtotime($values['date_added'])) . '</time>
                </div>

                <p>' . strip_tags($values['excerpt']) . '</p>

                <a href="{{domain}}/' . strip_tags($values['slug']) . '" title="Read: ' . strip_tags($values['heading']) . '" itemprop="url">Continue Reading <i class="icon-right-1"></i></a>
            </div>
        </article>
    ';
}

4. 完整示例代码

下面是一个将所有部分整合在一起的完整PHP脚本示例。请根据您的实际情况替换$jsonFilePath、{{domain}}和{{cdn}}等占位符,并确保imageLoad函数已定义。

<?php

// 模拟 imageLoad 函数,实际应用中请替换为您的实现
function imageLoad($path, $width, $height) {
    // 这是一个占位符函数,实际应根据您的图片处理逻辑返回正确的URL
    return $path; // 示例:直接返回路径
}

// 1. JSON数据准备与解析
$jsonFilePath = 'data/blogs.json'; // 替换为你的JSON文件路径
if (!file_exists($jsonFilePath)) {
    die("JSON file not found: " . $jsonFilePath);
}

$fileData = file_get_contents($jsonFilePath);
$jsonData = json_decode($fileData, true); // 解析为关联数组

if ($jsonData === null && json_last_error() !== JSON_ERROR_NONE) {
    die("Error parsing JSON: " . json_last_error_msg());
}

$allBlogs = $jsonData['blogs'] ?? [];

// 2. 分页核心逻辑实现
$itemsPerPage = 30; // 每页显示的文章数量
$currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1; // 获取当前页码,默认为第一页

// 确保页码不小于1
if ($currentPage < 1) {
    $currentPage = 1;
}

// 过滤符合条件的博客文章
$filteredBlogs = [];
foreach ($allBlogs as $blogId => $blogData) {
    // 应用原始的过滤条件
    if (isset($blogData['status']) && $blogData['status'] === '1' &&
        isset($blogData['visible']) && $blogData['visible'] === '1' &&
        isset($blogData['date_added']) && strtotime($blogData['date_added']) <= strtotime(date('r'))) {
        $filteredBlogs[] = $blogData;
    }
}

$totalItems = count($filteredBlogs); // 符合条件的总文章数
$totalPages = ceil($totalItems / $itemsPerPage); // 计算总页数

// 确保当前页码不超过总页数
if ($totalPages > 0 && $currentPage > $totalPages) {
    $currentPage = $totalPages;
} elseif ($totalPages == 0) { // 如果没有符合条件的文章
    $currentPage = 1;
}

$startIndex = ($currentPage - 1) * $itemsPerPage;
// 从过滤后的文章数组中提取当前页的文章
$paginatedBlogs = array_slice($filteredBlogs, $startIndex, $itemsPerPage);

// 3. 整合数据展示与HTML输出
?>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客文章列表 - 分页</title>
    <!-- 引入您的CSS框架,例如Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .blog-article { border: 1px solid #eee; padding: 15px; margin-bottom: 15px; }
        .pagination-container { margin-top: 20px; }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="my-4">最新博客文章</h1>
        <div class="row">
            <?php
            if (empty($paginatedBlogs)) {
                echo '<div class="col-12"><p>没有找到符合条件的文章。</p></div>';
            } else {
                foreach ($paginatedBlogs as $values){
                    // 假设 {{domain}} 和 {{cdn}} 是您前端框架或配置中定义的常量或变量
                    // 这里为了示例,我们直接使用占位符
                    $domain = 'https://yourdomain.com';
                    $cdn = 'https://yourcdn.com';

                    echo '
                        <article class="col-12 col-md-6 col-xl-4 mb-4" itemscope itemtype="https://schema.org/Article">
                            <div class="blog-article" data-href="' . $domain . '/' . strip_tags($values['slug']) . '">
                                <link itemprop="image" href="' . $cdn . '/uploads/' . str_replace('blog/', '', strip_tags($values['cover_image'])) . '" />
                                <picture>
                                    <img  itemprop="thumbnailUrl" class="lazy img-fluid" alt="' . strip_tags($values['heading']) . '" title="' . strip_tags($values['heading']) . '" height="253" width="450" />
                                </picture>

                                <h3 itemprop="headline">' . strip_tags($values['heading']) . '</h3>

                                <div class="d-flex align-items-center flex-wrap align-content-start mt-3">
                                    <figure>
                                        <img  class="lazy" alt="Photo of ' . strip_tags($values['author']['name']) . '" title="Photo of ' . strip_tags($values['author']['name']) . '" height="45" width="45" />
                                    </figure>

                                    <div class="author" itemprop="author">' . strip_tags($values['author']['name']) . '</div> <time itemprop="datePublished" datetime="' . date('c', strtotime($values['date_added'])) . '" class="date">' . date('d F Y', strtotime($values['date_added'])) . '</time>
                                </div>

                                <p>' . strip_tags($values['excerpt']) . '</p>

                                <a href="' . $domain . '/' . strip_tags($values['slug']) . '" title="Read: ' . strip_tags($values['heading']) . '" itemprop="url">Continue Reading <i class="icon-right-1"></i></a>
                            </div>
                        </article>
                    ';
                }
            }
            ?>
        </div>

        <!-- 分页导航 -->
        <nav aria-label="Page navigation" class="pagination-container">
            <ul class="pagination justify-content-center">
                <?php if ($currentPage > 1): ?>
                    <li class="page-item">
                        <a class="page-link" href="?page=<?php echo $currentPage - 1; ?>" aria-label="Previous">
                            <span aria-hidden="true">&laquo;</span>
                        </a>
                    </li>
                <?php endif; ?>

                <?php for ($i = 1; $i <= $totalPages; $i++): ?>
                    <li class="page-item <?php echo ($i == $currentPage) ? 'active' : ''; ?>">
                        <a class="page-link" href="?page=<?php echo $i; ?>"><?php echo $i; ?></a>
                    </li>
                <?php endfor; ?>

                <?php if ($currentPage < $totalPages): ?>
                    <li class="page-item">
                        <a class="page-link" href="?page=<?php echo $currentPage + 1; ?>" aria-label="Next">
                            <span aria-hidden="true">&raquo;</span>
                        </a>
                    </li>
                <?php endif; ?>
            </ul>
        </nav>
    </div>

    <!-- 引入您的JS库,例如Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <!-- 如果有图片懒加载,也需要引入相关JS -->
</body>
</html>

5. 注意事项与扩展

  • JSON数据有效性: 在实际项目中,务必确保JSON文件的格式正确。无效的JSON会导致json_decode返回null,并可能导致程序错误。使用json_last_error()和json_last_error_msg()可以帮助调试。
  • 错误处理: 对$_GET['page']等用户输入进行严格的验证和过滤,防止SQL注入(虽然这里是文件读取,但好的习惯很重要)或XSS攻击。确保页码是正整数,且在有效范围内。
  • 分页导航: 完整的教程应包含生成“上一页”、“下一页”以及所有页码链接的逻辑。上述示例代码已包含一个基本的Bootstrap风格分页导航。
  • 性能优化: 对于非常大的JSON文件,每次请求都读取并解析整个文件可能会影响性能。可以考虑将数据缓存起来,或者如果数据量巨大且更新不频繁,将其存储到数据库中,利用数据库的索引和分页功能。
  • 代码安全性: 原始代码中使用了strip_tags()来清理输出内容,这是一个良好的安全实践,可以防止XSS攻击。在任何输出用户生成或外部数据到HTML的地方都应进行适当的清理。
  • imageLoad函数: 示例中的imageLoad是一个占位符。在您的实际应用中,它可能是一个根据图片路径、尺寸等参数生成优化图片URL的自定义函数。

通过遵循这些步骤和最佳实践,您可以有效地为PHP应用程序中的JSON数据实现健壮且用户友好的分页功能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1134

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

381

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2194

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

380

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1703

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

586

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

440

2024.04.29

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号