PHP 类型安全数组:不牺牲可读性,性能提升 4 倍
sbwerewolf/language-specific 库 10.4.5 版本相较 8.4.1 版本实现 4 倍性能跃升;与当前竞品 wplake/typed(1.2.2)的性能差距已收窄至仅 2 倍。前者依赖字符串路径定位数据,后者则采用方法链式调用处理嵌套结构。
使用 wplake/typed 的示例:
use WPLake\Typed;
$response = file_get_contents(
'https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json'
);
$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$path = 'response.GeoObjectCollection.featureMember.0.GeoObject.metaDataProperty.GeocoderMetaData.Address.formatted';
// 带默认值的安全取值
$val = Typed::string($object, $path, '地址未找到');
var_dump($val);
/*
string(77)
"1, 穆罕默德·本·拉希德大道, 迪拜市中心, 迪拜, 阿拉伯联合酋长国"
*/
$isReal = Typed::stringOrNull($object, $path) !== null;
var_dump($isReal);
/* bool(true) */
sbwerewolf/language-specific 的等效实现:
use SbWereWolf\LanguageSpecific\AdvancedArrayFactory;
$response = file_get_contents('https://geocode-maps.yandex.ru/1.x/?apikey=d3893dc1-c136-4084-b9c-4db26b00463e&geocode=Mohammed+Bin+Rashid+Boulevard+1&lang=en_US&format=json');
$object = json_decode(json: $response, associative: true, flags: JSON_THROW_ON_ERROR);
$data = new AdvancedArrayFactory()->makeAdvancedArray($object);
$formatted = $data
->pull("response")
->pull("GeoObjectCollection")
->pull("featureMember")
->pull()
->pull("GeoObject")
->pull("metaDataProperty")
->pull("GeocoderMetaData")
->pull("Address")
->get("formatted")
->default("地址未找到");
$val = $formatted->str();
var_dump($val);
/*
string(77)
"1, 穆罕默德·本·拉希德大道, 迪拜市中心, 迪拜, 阿拉伯联合酋长国"
*/
$isReal = $formatted->isReal();
var_dump($isReal);
/* bool(true) */
性能基准测试
测试覆盖真实业务场景:JSON 解析(正常路径)、缺失路径处理、元素存在性校验、类型强制转换及原始值获取。
| 使用场景 | 8.4.1(优化前) | 10.4.5(优化后) | 1.2.2(wplake/typed) |
|----------|----------------|----------------|------------------------|
| JSON 正常路径解析 | 29.210 µs/次 | 6.467 µs/次 | 3.013 µs/次 |
| JSON 缺失路径解析 | 18.716 µs/次 | 5.987 µs/次 | 1.766 µs/次 |
| 元素存在性检查 | 27.237 µs/次 | 6.277 µs/次 | 2.863 µs/次 |
| 值类型强制转换 | 28.581 µs/次 | 6.740 µs/次 | 2.966 µs/次 |
| 原始值直接获取 | 30.395 µs/次 | 6.558 µs/次 | 3.015 µs/次 |
| 批量提取全部标量值 | 5.897 µs/次 | 1.878 µs/次 | 不支持 |
| 批量提取全部数组 | 7.136 µs/次 | 2.431 µs/次 | 不支持 |
10.4.5 新增特性:批量提取所有标量值与数组——此能力在 wplake/typed 中完全不可用。
核心架构演进
- 不可变
CommonValue类:默认值设定后禁止任何修改,杜绝意外状态污染。 - 确定性
pull()行为:从数组中提取时,始终返回首个元素,彻底消除非确定性风险。 - 精简 API 设计:移除冗余辅助类,将逻辑收敛至单一、连贯的执行流。
因主版本号跃迁(8.4.1 → 10.4.5),向后兼容性在语义上正式中断;但公共 API 接口保持完全一致,现有调用代码无需任何修改。
新增方法与能力
完整链式方法清单:
pull(string $key)—— 按键名提取嵌套元素pull()—— 提取数组首个元素(确定性保障)get(string $key)—— 安全取值,自动校验存在性default(mixed $fallback)—— 为缺失值设定默认回退值str()—— 强制转为字符串类型isReal()—— 判定值是否真实存在(非 null / 非空)
复杂场景示例:高效处理结构不稳定、字段可能缺失的第三方 API 响应。
为何值得关注
- 相比基线性能提升 4 倍,仅比当前性能标杆慢 2 倍;
- 完美保留链式调用的清晰可读性,彻底告别脆弱易错的字符串路径;
- 独家支持批量提取标量与数组,填补行业空白;
- 不可变性与确定性设计显著提升系统可靠性与单元测试友好度;
- 专为中级至高级工程师打造:在生产级性能与强类型安全之间取得最佳平衡。
— Editorial Team
暂无评论。