淺談PHP?8.4?核心特性
簡介:
自 PHP 8.0 發(fā)布以來,該語言經(jīng)歷了一系列重要的功能迭代與性能改進。對于開發(fā)者而言,系統(tǒng)理解這些新特性不僅是技術(shù)更新的需要,更是優(yōu)化代碼設(shè)計、降低維護成本的有效途徑。本分類將按版本梳理 PHP 8.x 的新特性。
8.4 官方手冊參考指南(含其他特性):官方鏈接
一、屬性鉤子
屬性鉤子是 Zend 引擎原生支持的屬性訪問攔截機制,在屬性讀?。?code>get)、寫入(set)時自動觸發(fā)自定義邏輯,無需額外方法調(diào)用。
告別冗余,擁抱原生。屬性鉤子的優(yōu)勢是顛覆性的:
- 原生性能:它是 Zend 引擎在語言層面直接支持的機制,性能遠優(yōu)于
__get/__set魔術(shù)方法 - 更優(yōu)雅的語法:告別重復(fù)的方法體,直接在屬性上定義存取邏輯,代碼更簡潔
- 出色的工具支持:IDE 和靜態(tài)分析工具(如 PHPStan)能原生識別屬性鉤子,告別了依賴
@property注解的時代 - 精準(zhǔn)的控制:與“一攬子”攔截的
__get/__set不同,鉤子可以精準(zhǔn)地為單個屬性定制行為,同時為未來預(yù)留擴展可能,避免了 API 的不兼容變更
語法示例:
<?php
declare(strict_types=1);
class Example
{
public string $firstName;
public string $lastName;
// 使用箭頭函數(shù)定義只讀的計算屬性 僅定義get
public string $fullName
{
get => $this->firstName .' '. $this->lastName;
}
// 使用代碼塊定義帶驗證的 setter 僅定義set
public string $email
{
set(string $value){
if(!filter_var($value, FILTER_VALIDATE_EMAIL)){
throw new InvalidArgumentException("Invalid email address");
}
$this->email = strtolower($value);
}
}
}
$example = new Example();
$example->firstName = "John";
$example->lastName = "Doe";
echo $example->fullName; // John Doe
echo '<br/>';
$example->email = "John@Example.COM";
echo $example->email; // john@example.com
使用場景:
- 賦值時數(shù)據(jù)校驗 + 清洗(最核心),寫入屬性時自動觸發(fā)
set,無需手動調(diào)用方法。例:郵箱、手機號、年齡、價格、用戶名等合法性校驗;自動去空格、轉(zhuǎn)小寫 - 讀取時自動格式化(不修改原值),讀取屬性時自動觸發(fā)
get,原值保持原始格式。例:姓名大寫、日期格式化、金額加貨幣符號、手機號脫敏 - 虛擬 / 計算屬性(無存儲,動態(tài)派生),每次讀取觸發(fā)
get計算,無存儲、不占用內(nèi)存。例:全名、訂單總價、BMI、年齡計算等無需存庫的派生字段 - 非對稱可見性(對外只讀,內(nèi)部可寫),外部寫入直接報錯,內(nèi)部寫入觸發(fā)
set。例:ID、創(chuàng)建時間、狀態(tài)等禁止外部修改的字段 - 類型自動雙向轉(zhuǎn)換(ORM / 存儲層常用),讀→轉(zhuǎn)對象 / 數(shù)組,寫→轉(zhuǎn)字符串存庫。例:數(shù)據(jù)庫存字符串,代碼用對象;數(shù)組↔JSON 互轉(zhuǎn)
- 屬性變更監(jiān)聽(日志、觸發(fā)事件、聯(lián)動更新),賦值時 set 執(zhí)行副作用邏輯。例:記錄修改日志、狀態(tài)變更時更新其他字段、觸發(fā)通知
- 防非法賦值(自動修正,不拋異常),寫入時
set自動修正值。例:庫存不能為負、價格默認 0、空值自動填充
二、不對稱可見性
在 PHP8.4 之前,類屬性的可見性 (public/protected/private) 是對稱的—— 讀取和寫入操作必須遵循相同的訪問規(guī)則。如果需要實現(xiàn) "對外只讀、對內(nèi)可寫" 的常見需求,開發(fā)者只能通過以下兩種繁瑣方式實現(xiàn):
- 私有屬性 + 公共 getter 方法
- 只讀屬性
只讀屬性的局限性在于只能在構(gòu)造函數(shù)中賦值,無法在對象生命周期內(nèi)通過類內(nèi)部方法修改。PHP8.4 的不對稱可見性 (Asymmetric Visibility),這一特性徹底改變了 PHP 中類屬性的訪問控制機制,允許開發(fā)者為屬性的讀取 (get) 和寫入 (set) 操作設(shè)置不同的可見性級別,解決了長期以來屬性封裝的痛點問題。
語法格式:{讀取可見性} {寫入可見性}(set) {類型聲明} $屬性名;
示例:
<?php
declare(strict_types=1);
class Example
{
// $orderId 讀?。簆ublic,寫入:private(僅類內(nèi)部可寫)
// $amount 讀?。簆rotected(類和子類可見),寫入:private(僅類內(nèi)部可寫)
// $status 讀?。簆ublic,寫入:protected(類和子類可寫)
public function __construct(
public private(set) int $orderId,
protected private(set) float $amount,
public protected(set) string $status = 'pending'
)
{}
// 類內(nèi)部方法可修改所有屬性
public function updateStatus(string $newStatus) :void
{
$this->status = $newStatus; // 允許,寫入可見性為protected
}
}
$order = new Example(1001, 99.99);
echo '<pre>';
// 讀取操作(符合讀取可見性)
var_dump($order->orderId); // 1001 (允許:public讀取)
var_dump($order->status); // pending (允許:public讀取)
// 寫入操作(需符合寫入可見性)
//$order->orderId = 1002; // 錯誤:private(set),外部不可寫
//$order->status = 'shipped'; // 錯誤:protected(set),外部不可寫
// 類內(nèi)部方法修改
$order->updateStatus('shipped'); // 允許:類內(nèi)部調(diào)用
var_dump($order->status); // shipped (成功修改)
不對稱可見性并非無限制,PHP 引擎實施了以下重要約束以保證類型安全和代碼一致性:
- 寫入可見性不能寬于讀取可見性:寫入操作的可見性必須等于或更嚴(yán)格于讀取可見性 。例:public 讀取不能搭配 protected 寫入以外的更寬松設(shè)置
private public(set) int $id(錯誤) - 必須有類型聲明:不對稱可見性僅適用于有顯式類型的屬性。例:
public private(set) $name(錯誤,無類型) - 靜態(tài)屬性支持:初始版本不支持靜態(tài)屬性,后續(xù)通過單獨 RFC 補充支持。例:
public private(set) static int $counter(PHP8.4.1 + 有效) - 與 readonly 不兼容:不能與
readonly關(guān)鍵字同時使用 (語義沖突) 例:public private(set) readonly int $id(錯誤)
與屬性鉤子 (Property Hooks) 的結(jié)合。PHP8.4 同時引入了屬性鉤子特性,允許為屬性添加自定義的 get/set 邏輯,與不對稱可見性完美兼容。
示例:
<?php
declare(strict_types=1);
class Example {
// 不對稱可見性:讀公開,寫私有
// 同時為 get 和 set 添加鉤子
public private(set) string $name {
get {
return 'User: ' . $this->name; // 自動添加前綴
}
set {
if ($value === '') {
throw new InvalidArgumentException('Name cannot be empty');
}
$this->name = $value; // 直接寫入后備字段,不會遞歸
}
}
public function __construct(string $name) {
$this->name = $name; // 觸發(fā) set 鉤子(私有寫)
}
}
$user = new Example('Alice');
echo $user->name; // 輸出:User: Alice
// $user->name = 'Bob'; // 錯誤:Cannot modify private(set) property
子類重寫父類的不對稱可見性屬性時,必須遵循以下規(guī)則,確保不破壞封裝契約:
- 類型兼容性:子類屬性必須與父類屬性完全相同的類型(協(xié)變 / 逆變不允許)
- 讀取可見性:子類讀取可見性不能比父類更嚴(yán)格(可保持相同或更寬松)
- 子類寫入可見性不能比父類更嚴(yán)格(可保持相同或更寬松)
- private (set) 限制:父類中聲明為
private(set)的屬性不能被子類重寫(等效于 final 屬性)
最佳實踐:
- 實體類 / 值對象(最常用):User、Product、Order 等業(yè)務(wù)實體,ID、創(chuàng)建時間、唯一編碼等屬性,外部只能讀取,僅類內(nèi)部可初始化 / 修改。
- 服務(wù)類的內(nèi)部狀態(tài)屬性:緩存服務(wù)、日志服務(wù)等,外部只讀服務(wù)狀態(tài),內(nèi)部根據(jù)操作動態(tài)更新
- 配置類的只讀配置:應(yīng)用配置、數(shù)據(jù)庫配置等,加載后外部只讀,僅初始化時內(nèi)部設(shè)置。
- 與屬性鉤子結(jié)合(驗證 / 格式化):需要對寫入值做驗證 / 格式化,但仍保持 “對外只讀、對內(nèi)可寫”。
- 父子類共享的可寫屬性:基類定義屬性,外部只讀,子類可內(nèi)部修改(用
public protected(set)) - 合理選擇可見性組合:對外只讀:
public private(set)、父子類共享寫入:public protected(set)、內(nèi)部組件可見:protected private(set)
三、#[Deprecated]
#[Deprecated]是 PHP 8.4 新增的內(nèi)置屬性,用于標(biāo)記代碼元素為已棄用,替代傳統(tǒng)的trigger_error(E_USER_DEPRECATED)手動實現(xiàn)。適用目標(biāo):函數(shù)、方法、類常量 (8.4)、全局常量 (8.5)、特質(zhì) (8.5),錯誤級別為:E_USER_DEPRECATED (區(qū)別于內(nèi)核的E_DEPRECATED),不會中斷程序執(zhí)行。
語法示例:
<?php
declare(strict_types=1);
// 簡易示例
#[\Deprecated]
function simple_function(): void {}
// 完整示例
#[\Deprecated(message:"使用new_function()替代", since: "1.5.0")]
/**
* message:棄用說明,建議包含替代方案,會顯示在警告信息中
* since:標(biāo)記棄用起始版本,便于版本管理
*/
function old_function(): void {}
class FileUploader {
#[\Deprecated(message: "使用API_VERSION_3替代")]
public const API_VERSION_2 = "2.0";
public const API_VERSION_3 = "3.0";
#[\Deprecated(
message: "請使用uploadFile()方法替代,該方法支持文件驗證",
since: "3.0.0"
)]
public function upload(string $path): void {
// 舊實現(xiàn)
}
public function uploadFile(string $path): void {
// 帶驗證的新實現(xiàn)
}
}
simple_function();// 錯誤:Deprecated: Function simple_function() is deprecated in
old_function();// 錯誤:Deprecated: Function old_function() is deprecated since 1.5.0, 使用new_function()替代 in
var_dump(FileUploader::API_VERSION_2); // 觸發(fā)棄用警告 輸出 “2.0”
$uploader = new FileUploader();
$uploader->upload("/tmp/file.txt"); // 觸發(fā)棄用警告
四、ext-dom 功能和 HTML5 支持
歷史痛點與解決方案:
傳統(tǒng) DOMDocument 依賴 libxml2 解析 HTML,而 libxml2 的 HTML 解析停留在 HTML 4 時代,存在三大問題:無法正確識別 <article>、<section> 等 HTML5 語義標(biāo)簽、解析規(guī)則與 HTML5 規(guī)范不一致,導(dǎo)致文檔結(jié)構(gòu)異常、處理嵌入式 JavaScript 等現(xiàn)代內(nèi)容時容易出錯。
PHP 8.4 引入 Lexbor 解析庫(由 Alexander Borisov 開發(fā)),專為 HTML5 設(shè)計,具備以下優(yōu)勢:完全符合 WHATWG HTML 規(guī)范,支持所有 HTML5 元素與解析規(guī)則、高性能(C 語言實現(xiàn),內(nèi)存占用低,解析速度快)、原生支持 CSS 選擇器查詢,無需額外依賴、良好的錯誤恢復(fù)機制,處理 “標(biāo)簽湯(Tag Soup)” 更健壯。
關(guān)鍵設(shè)計:
Dom\HTMLDocument與Dom\XMLDocument均繼承自抽象類Dom\Document- 舊
DOMDocument類現(xiàn)在也繼承自Dom\Document,實現(xiàn)部分新特性兼容 - 新 API 使用靜態(tài)構(gòu)造函數(shù)而非
new關(guān)鍵字創(chuàng)建實例,更符合現(xiàn)代 PHP 實踐
示例:
<?php
declare(strict_types=1);
// 1. 解析 HTML5 文檔
$html = <<<'HTML'
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>測試</title>
</head>
<body>
<div id="main"><p class="intro">PHP 8.4 新特性</p></div>
</body>
</html>
HTML;
$dom = Dom\HTMLDocument::createFromString($html);
echo '<pre>';
// 2. CSS 選擇器查詢
$intro = $dom->querySelector('#main .intro');
var_dump($intro->textContent); // 輸出: PHP 8.4 新特性
// 3. 修改內(nèi)容
$intro->innerHTML = 'PHP 8.4 <strong>DOM 新特性</strong>';
// 4. 操作類名
$intro->classList->add('highlight');
$intro->classList->remove('intro');
// 5. 序列化輸出
echo $dom->saveHTML();
五、BCMath 對象 API
在 PHP 8.4 之前,處理高精度數(shù)學(xué)運算的唯一選擇是調(diào)用 bcadd、bcsub 這類略顯晦澀的過程式函數(shù)。PHP 8.4 引入了一個全新的、面向?qū)ο蟮?API——BcMath\Number 類。它不是一個簡單的語法糖,而是為高精度計算帶來了可讀性、安全性和強大功能的全面提升。
核心特性:
- 運算符重載:支持
+、-、*、/、%、**等算術(shù)運算符及所有比較運算符,代碼更直觀易讀 - 不可變性:所有計算操作返回新對象,原對象保持不變,避免副作用
- Stringable 接口:可直接在字符串上下文中使用(如
echo $num),自動轉(zhuǎn)換為字符串表示 - 獨立精度控制:不受
bcmath.scaleINI 指令影響,每個對象和操作可單獨設(shè)置精度 - 全面方法支持:提供與傳統(tǒng) BCMath 函數(shù)對應(yīng)的面向?qū)ο蠓椒?,覆蓋所有高精度計算需求
基礎(chǔ)示例:
<?php
declare(strict_types=1);
use BcMath\Number;
echo '<pre>';
// 整數(shù)初始化,scale 自動設(shè)為 0
$num1 = new Number(100);
var_dump($num1->value, $num1->scale); // string(3) "100", int(0)
// 字符串初始化,自動解析 scale
$num2 = new Number('123.456');
var_dump($num2->value, $num2->scale); // string(3) "123.456", int(3)
// 負數(shù)支持
$num3 = new Number('-789.00');
var_dump($num3->value, $num3->scale); // string(3) "-789.00", int(2)
// 僅支持 int/string 類型參數(shù),浮點數(shù)以字符串形式傳入,傳入無效數(shù)字字符串會拋出 ValueError
//$num4 = new Number(0.1); // 錯誤:Argument #1 ($num) must be of type string|int, float given
//$num5 = new Number('abc123'); // 錯誤:Argument #1 ($num) is not well-formed
核心算數(shù)運算:
- 加法:add($num, ?int $scale = null)
- 減法:sub($num, ?int $scale = null)
- 乘法:mul($num, ?int $scale = null)
- 除法:div($num, ?int $scale = null)
- 取模:mod($num, ?int $scale = null)
- 冪運算:pow($exponent, ?int $scale = null)
- 冪模運算:powmod($exponent, $modulus, ?int $scale = null)
- 平方根:sqrt(?int $scale = null)
- 商余運算:divmod($num, ?int $scale = null)
- 向上取整:ceil()
- 向下取整:floor()
- 四舍五入:round(int $precision = 0, RoundingMode $mode = RoundingMode::HalfAwayFromZero)
- 比較兩個數(shù)值:compare($num, ?int $scale = null)
示例:
<?php
declare(strict_types=1);
use BcMath\Number;
echo '<pre>';
$num1 = new Number('5.5');
$num2 = new Number(5);
$num3 = new Number('5.0');
// 求和
var_dump($num1->add($num2, 2)); // BcMath\Number對象 value = 10.50 (scale=2)
var_dump($num1 + $num2); // BcMath\Number對象 value = 10.5
// 減法
var_dump($num1->sub($num2)); // BcMath\Number對象 value = 0.5
var_dump($num1 - $num2); // BcMath\Number對象 value = 0.5
// 乘法
var_dump($num1->mul($num2)); // BcMath\Number對象 value = 27.5
var_dump($num1 * $num2); // BcMath\Number對象 value = 27.5
// 除法
var_dump($num1->div($num2)); // BcMath\Number對象 value = 1.1
var_dump($num1 / $num2); // BcMath\Number對象 value = 1.1
// 取模
var_dump($num1->mod($num2)); // BcMath\Number對象 value = 0.5
var_dump($num1 % $num2); // BcMath\Number對象 value = 0.5
// 冪運算
var_dump($num2->pow(2));// BcMath\Number對象 value = 25
var_dump($num2 ** 2);// BcMath\Number對象 value = 25
// 平方根
var_dump(new Number(4)->sqrt()); // BcMath\Number對象 value = 2
// 商余運算
[$quotient, $remainder] = $num1->divmod($num2);
var_dump($quotient, $remainder); // BcMath\Number對象 value : quotient = 1 remainder = 0.5
// 冪模運算
var_dump(new Number(4)->powmod($num2, 5)); // BcMath\Number對象 value = 4
// 相等比較
var_dump($num2 == $num3); // true
// 嚴(yán)格比較
var_dump($num2 === $num3); // false
// 不等比較 != 或 <>
var_dump($num2 <> $num3); // false
var_dump($num2 != $num3); // false
var_dump($num2 !== $num3); // true
// 小于比較、大于比較、小于等于比較、大于等于比較
var_dump($num1 > $num2); // true
var_dump($num1 >= $num2); // true
var_dump($num2 < $num3); // false
var_dump($num2 <= $num3); // true
/** 復(fù)雜計算 鏈?zhǔn)秸{(diào)用 */
// 計算訂單總價(含折扣和稅費)
$price = new Number('99.99');
$quantity = new Number('3');
$discountRate = new Number('0.1'); // 10% 折扣
$taxRate = new Number('0.08'); // 8% 稅費
$subtotal = $price->mul($quantity, 2); // 299.97
$discount = $subtotal->mul($discountRate, 2); // 29.997 → 30.00
$tax = ($subtotal->sub($discount))->mul($taxRate, 2); // 21.5976 → 21.60
$total = ($subtotal->sub($discount))->add($tax, 2); // 291.57
var_dump($total);
最佳實踐:
- 確保 PHP 版本 ≥ 8.4,啟用 BCMath 擴展(
extension=bcmath) - 始終使用字符串初始化小數(shù)
- 顯式控制關(guān)鍵計算的精度,而非自動計算的 scale
- 鏈?zhǔn)秸{(diào)用簡化復(fù)雜計算
- 利用不可變性進行安全計算
六、新的 array_*() 函數(shù)
PHP 8.4 正式引入了四個全新的數(shù)組操作函數(shù):array_find()、array_find_key()、array_all() 和 array_any()。這些函數(shù)填補了 PHP 數(shù)組操作能力的空白,提供了更簡潔、直觀的方式來處理常見的數(shù)組查找和條件檢查任務(wù),避免了編寫冗長的循環(huán)或使用不那么直觀的現(xiàn)有函數(shù)組合。
1、array_find()
功能:按條件搜索第一個值。
語法:array_find(array $array, callable $callback): mixed
其中$array:待搜索的數(shù)組;$callback:回調(diào)函數(shù),接收兩個參數(shù)($value, $key),返回布爾值表示是否匹配
返回值:第一個使回調(diào)函數(shù)返回 true 的元素值,無匹配元素時返回 null
示例:
<?php
declare(strict_types=1);
$users = [
['id' => 1, 'name' => 'Alice', 'active' => false],
['id' => 2, 'name' => 'Bob', 'active' => true],
['id' => 3, 'name' => 'Charlie', 'active' => true]
];
// 查找第一個活躍用戶 active = true
$firstActiveUser = array_find($users, fn($user) => $user['active']);
// 查找名字以 'C' 開頭的用戶
$userWithCName = array_find($users, fn($user) => str_starts_with($user['name'], 'C'));
// 查找不存在的條件
$inactiveUserOver30 = array_find($users, fn($user) => !$user['active'] && $user['id'] > 30);
echo '<pre>';
//輸出:array(3) { ["id"]=> int(2) ["name"]=> string(3) "Bob" ["active"]=> bool(true) }
var_dump($firstActiveUser);
//輸出:array(3) { ["id"]=> int(3) ["name"]=> string(7) "Charlie" ["active"]=> bool(true) }
var_dump($userWithCName);
var_dump($inactiveUserOver30); // null
2、array_find_key()
功能:按條件搜索第一個鍵。
語法:array_find_key(array $array, callable $callback): mixed
其中$array:待搜索的數(shù)組;$callback:回調(diào)函數(shù),接收兩個參數(shù)($value, $key),返回布爾值表示是否匹配
返回值:第一個使回調(diào)函數(shù)返回 true 的元素鍵名(保留原始鍵類型),無匹配元素時返回 null
示例:
<?php
declare(strict_types=1);
$products = [
'laptop' => ['price' => 999, 'in_stock' => true],
'phone' => ['price' => 699, 'in_stock' => false],
'tablet' => ['price' => 299, 'in_stock' => true]
];
// 查找第一個有庫存的產(chǎn)品鍵名
$firstInStockKey = array_find_key($products, fn($products) => $products['in_stock']);
// 查找價格低于 500 的產(chǎn)品鍵名
$affordableProductKey = array_find_key($products, fn($product) => $product['price'] < 500);
echo '<pre>';
var_dump($firstInStockKey); // 輸出:string(6) "laptop"
var_dump($affordableProductKey); // 輸出:string(6) "tablet"
3、array_all()
功能:檢查所有元素是否滿足條件。
語法:array_all(array $array, callable $callback): bool
其中$array:待搜索的數(shù)組;$callback:回調(diào)函數(shù),接收兩個參數(shù)($value, $key),返回布爾值表示是否匹配
返回值:所有元素都使回調(diào)函數(shù)返回 true 時返回 true;只要有一個元素使回調(diào)函數(shù)返回 false,立即返回 false(短路求值);空數(shù)組時返回 true
示例:
<?php declare(strict_types=1); $numbers = [2, 4, 6, 8, 10]; // 檢查所有數(shù)字是否為偶數(shù) $allEven = array_all($numbers, fn($n) => $n % 2 === 0); // 檢查所有數(shù)字是否小于 5 $allSmall = array_all($numbers, fn($n) => $n < 5); // 空數(shù)組測試 $emptyCheck = array_all([], fn($n) => $n > 0); echo '<pre>'; var_dump($allEven); // 輸出:bool(true) var_dump($allSmall); // 輸出:bool(false) var_dump($emptyCheck); // 輸出:bool(true)
4、array_any()
功能:檢查是否存在滿足條件的元素。
語法:array_any(array $array, callable $callback): bool
其中$array:待搜索的數(shù)組;$callback:回調(diào)函數(shù),接收兩個參數(shù)($value, $key),返回布爾值表示是否匹配
返回值:只要有一個元素使回調(diào)函數(shù)返回 true,立即返回 true(短路求值);所有元素都使回調(diào)函數(shù)返回 false 時返回 false;空數(shù)組時返回 false
示例:
<?php
declare(strict_types=1);
$emails = [
'user1@example.com',
'user2@test.org',
'user3@domain.net'
];
// 檢查是否存在以 .org 結(jié)尾的郵箱
$hasOrgEmail = array_any($emails, fn($email) => str_ends_with($email, '.org'));
// 檢查是否存在以 .gov 結(jié)尾的郵箱
$hasGovEmail = array_any($emails, fn($email) => str_ends_with($email, '.gov'));
// 空數(shù)組測試
$emptyCheck = array_any([], fn($email) => str_ends_with($email, '.com'));
echo '<pre>';
var_dump($hasOrgEmail); // 輸出:bool(true)
var_dump($hasGovEmail); // 輸出:bool(false)
var_dump($emptyCheck); // 輸出:bool(false)
到此這篇關(guān)于PHP 8.4 核心特性的實現(xiàn)的文章就介紹到這了,更多相關(guān)PHP 8.4特性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于PHP導(dǎo)出Excel的小經(jīng)驗 完美解決亂碼問題
本篇文章是對PHP導(dǎo)出Excel亂碼問題的解決方法就行了詳細的分析介紹,需要的朋友參考下2013-06-06
php堆排序?qū)崿F(xiàn)原理與應(yīng)用方法
這篇文章主要介紹了php堆排序?qū)崿F(xiàn)原理與應(yīng)用方法,較為詳細的分析了堆排序的原理及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-01-01

