適用於大文本文件(如日誌、小說、長文章)按固定字節長度分頁顯示,不適合數據庫記錄分頁。
<?php
class StrPage {
private $current; // 當前頁
private $file; // 文件完整內容
private $totalPage; // 總頁數
private $url; // 基礎 URL (保留其他參數)
private $pageLen; // 每頁字節長度
public function __construct($file, $len = 200) {
$this->file = file_get_contents($file);
$this->pageLen = $len;
$this->current = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$this->totalPage = $this->getTotalPage();
$this->url = $this->getUrl();
}
// 總頁數 = ceil(文件總長度 / 每頁長度)
private function getTotalPage() {
return ceil(strlen($this->file) / $this->pageLen);
}
// 解析當前 URL 保留非 page 參數
private function getUrl() {
$u = parse_url($_SERVER['REQUEST_URI']);
parse_str($u['query'] ?? '', $q);
unset($q['page']);
return $u['path'] . '?' . http_build_query($q) . '&page=';
}
// 導航鏈接生成
private function first() { return $this->current>1 ? "<a href='{$this->url}1'>首頁</a>" : ''; }
private function pre() { return $this->current>1 ? "<a href='{$this->url}".($this->current-1)."'>上一頁</a>" : ''; }
private function next() { return $this->current<$this->totalPage ? "<a href='{$this->url}".($this->current+1)."'>下一頁</a>" : ''; }
private function end() { return $this->current<$this->totalPage ? "<a href='{$this->url}{$this->totalPage}'>末頁</a>" : ''; }
// 頁碼列表
public function pageList() {
$html = '';
for ($i=1; $i<=$this->totalPage; $i++) {
$html .= ($i==$this->current)
? "<span style='font-size:20px;color:#f00'>$i</span> "
: "<a href='{$this->url}$i'>$i </a>";
}
return $html;
}
// 組合輸出樣式
public function pageStyle($style=1) {
switch($style) {
case 1: return "共{$this->totalPage}頁".$this->first().$this->pre().$this->pageList().$this->next().$this->end();
case 2: return $this->pageList();
}
}
// 獲取當前頁內容 (處理多字節字符不截斷)
public function getContents() {
$preLen = strlen($this->subStrs($this->current-1));
$currLen = strlen($this->subStrs($this->current));
return substr($this->file, $preLen, $currLen - $preLen);
}
// 計算前 N 頁實際字節長度 (UTF-8 中文佔 3 字節)
private function subStrs($page) {
$str = '';
$len = $page * $this->pageLen;
for ($i=0; $i<$len; $i++) {
if (ord($this->file[$i]) > 0xA0) { // 多字節字符
$str .= substr($this->file, $i, 3);
$i += 2;
} else {
$str .= $this->file[$i];
}
}
return $str;
}
}
?>
<?php
require 'StrPage.php';
$page = new StrPage('long_article.txt', 500); // 每頁 500 字節
echo $page->getContents(); // 正文
echo $page->pageStyle(1); // 導航
?>
file_get_contents,適合中小文件(<10MB),大文件建議流式讀取subStrs 按 UTF-8 特性 (首字節 > 0xA0 視為 3 字節字符) 計算實際字節偏移,避免半個漢字parse_url + parse_str + http_build_query 保持分頁鏈接攜帶原有查詢參數pageStyle() 支持多種輸出模式fseek + fread 流式讀取mbstring 或自動檢測StrPage 類演示了純文件分頁的核心邏輯:全量讀取 → 字節計算 → 多字節安全截取 → 參數保留導航。適合中小型靜態文本分頁展示,生產環境大文件請改用流式處理。