PHP CMS中如何将archive.php搜索结果循环插入其他页面
问题根源
你使用的<?php insert('archive.php?s=test'); ?>方法无法生效,原因是insert()是系统提供的模板文件加载函数,只会按照传入的字符串查找本地的模板文件,不会解析URL参数,也不会触发对应的路由逻辑,系统会尝试查找名为archive.php?s=test的文件,自然无法得到想要的结果。
实现方案
你可以直接复用现有系统的搜索逻辑和loop.php模板,不需要修改原有功能代码,按照下面的步骤操作即可:
方案1:单页面快速实现(无需修改公共文件)
直接在需要展示搜索结果的页面中添加以下两段代码即可:
- 首先添加数据查询代码,修改
$search_keyword为你需要的搜索词,$show_post_num为你要展示的文章数量:
<?php // 自定义配置 $search_keyword = 'test'; // 要搜索的关键词 $show_post_num = 5; // 要展示的文章数量 // 复用系统原有搜索逻辑,无需修改 $postModel = new PostModel; $feedModel = new FeedModel; $categoryModel = new CategoryModel; $feedsTable = $feedModel->getTable(); $postsTable = $postModel->getTable(); $categoriesTable = $categoryModel->getTable(); $filters['sort'] = 'post-publish-date'; if (mb_strlen($search_keyword) > 3) { $filters['where'][] = ["{$postsTable}.post_title", 'LIKE', "%{$search_keyword}%"]; $filters['where'][] = ["{$postsTable}.post_content", 'LIKE', "%{$search_keyword}%", 'OR']; } $fields[] = "{$postsTable}.post_id, {$postsTable}.post_category_id, {$postsTable}.post_title, {$postsTable}.post_excerpt, {$postsTable}.post_featured_image, {$postsTable}.post_type, {$postsTable}.post_source, {$postsTable}.post_pubdate, {$postsTable}.created_at, {$postsTable}.post_hits"; $fields[] = "{$feedsTable}.feed_name, {$feedsTable}.feed_id, {$feedsTable}.feed_logo_url"; $fields[] = "{$categoriesTable}.category_name, {$categoriesTable}.category_slug, {$categoriesTable}.category_icon"; $sql = $postModel->select($fields) ->leftJoin( $feedsTable, "{$postsTable}.post_feed_id", '=', "{$feedsTable}.feed_id" )->leftJoin( $categoriesTable, "{$postsTable}.post_category_id", '=', "{$categoriesTable}.category_id" )->limit($show_post_num, 0); $sql = $postModel->applyModelFilters($sql, $filters); $stmt = $sql->execute(); $search_posts = $stmt->fetchAll(); ?>
- 然后在需要展示列表的位置添加渲染代码,完全复用你现有的模板,样式和原搜索页完全一致:
<div class="row"> <?php if (has_items($search_posts)) : ?> <?php foreach ($search_posts as $t['loop']) : ?> <div class="col-12 mb-3"> <?php insert('partials/loop.php'); ?> </div> <?php endforeach; ?> <?php else : ?> <?php insert( 'partials/empty.php', [ 'empty_message' => __('nothing-found-archive', _T) ] ); ?> <?php endif; ?> </div>
方案2:封装公共函数(多页面复用推荐)
如果你需要在多个页面调用不同关键词的搜索结果,可以把查询逻辑封装成公共函数,后续调用更简洁:
- 先在系统的公共函数文件中添加如下函数:
/** * 根据关键词获取搜索结果列表 * @param string $keyword 搜索关键词 * @param int $limit 返回结果数量 * @return array 搜索结果数组 */ function get_search_posts(string $keyword, int $limit = 10): array { $postModel = new PostModel; $feedModel = new FeedModel; $categoryModel = new CategoryModel; $feedsTable = $feedModel->getTable(); $postsTable = $postModel->getTable(); $categoriesTable = $categoryModel->getTable(); $filters['sort'] = 'post-publish-date'; if (mb_strlen($keyword) > 3) { $filters['where'][] = ["{$postsTable}.post_title", 'LIKE', "%{$keyword}%"]; $filters['where'][] = ["{$postsTable}.post_content", 'LIKE', "%{$keyword}%", 'OR']; } $fields[] = "{$postsTable}.post_id, {$postsTable}.post_category_id, {$postsTable}.post_title, {$postsTable}.post_excerpt, {$postsTable}.post_featured_image, {$postsTable}.post_type, {$postsTable}.post_source, {$postsTable}.post_pubdate, {$postsTable}.created_at, {$postsTable}.post_hits"; $fields[] = "{$feedsTable}.feed_name, {$feedsTable}.feed_id, {$feedsTable}.feed_logo_url"; $fields[] = "{$categoriesTable}.category_name, {$categoriesTable}.category_slug, {$categoriesTable}.category_icon"; $sql = $postModel->select($fields) ->leftJoin( $feedsTable, "{$postsTable}.post_feed_id", '=', "{$feedsTable}.feed_id" )->leftJoin( $categoriesTable, "{$postsTable}.post_category_id", '=', "{$categoriesTable}.category_id" )->limit($limit, 0); $sql = $postModel->applyModelFilters($sql, $filters); $stmt = $sql->execute(); return $stmt->fetchAll(); }
- 之后在任意页面需要展示搜索结果时,只要调用函数获取数据,再用上述的渲染代码即可:
<?php // 示例:获取关键词test的前5条搜索结果 $search_posts = get_search_posts('test', 5); ?> <!-- 此处插入上述渲染代码即可 -->
补充说明
- 上述所有逻辑完全复用你现有系统的查询规则、渲染模板,和原搜索页的结果、样式完全一致,不需要额外调整样式
- 如果你需要展示带分页的搜索结果,直接复用原archive方法中的分页逻辑,把查询代码里的固定偏移量
0替换成分页参数对应的偏移值即可
内容的提问来源于stack exchange,提问作者Mortan
相关产品推荐
相关产品推荐

