奇技指南
语法糖往往给程序员提供了更实用的编码方式, 可以使代码更简洁流畅, 语义更自然. 本文介绍笔者自己写的 PHP 语法糖扩展, 扩展了一种全新的 PHP 超全局变量获取方式.
本文作者范家鹏, 360 技术委员会 --web 服务端分 TC 委员.
1, 说说语法糖
首先说说 "语法糖" 这个词绝非贬义词, 它可以给我们的开发工作带来便利, 是一种轻量级便捷的写法, 既不会对语言本身的使用造成不利影响, 也不会在性能上带来损失.
通常情况下, 使用语法糖能够增加程序的可读性, 减少程序复杂性, 减少编码中出错的机会, 也对开发工程师具有友好性, 能够提升我们的开发效率.
优秀的语法糖, 应该是一种灵魂思想的注入, 简单写法的应用. 我这里用一幅图来表示:
2, 什么是 SG?
SG 全称 Superglobals, 引用全局作用域中可用的全部变量. SG 扩展了一种全新的 PHP 超全局变量获取方式.
这些超全局变量是:_SERVER,_GET,_POST,_FILES,_COOKIE,_SESSION,_REQUEST,_ENV.
当然了, 也可以应用到自定义变量场景.
非常重要的一点是: 它很简单!
2.1 项目背景
这个 idea 出发点很简单, 从扩展名称我们应该能猜到它是做什么的.
在性能最优的前提下:
能通俗易懂地简化 HTTP 参数获取方法
需要对 HTTP 参数值进行统一过滤, 转换, 解密操作
获取 HTTP 参数前, 需要进行一些 Predefined Operation
针对 HTTP 参数的一切行为, 需要同步更新对应的 PHP Superglobal
声明时才使用, 而非请求一开始就对 PHP Superglobals 扫荡式处理
在 global 语法上, 扩展一项能获取 HTTP 参数的能力
So,SG 出现就是为了解决上面这些问题而来, 它提供了一种更加甜蜜的语法, 当前已经发布了 v3.0.0.
2.2 项目地址
https://github.com/yulonghu/sg
欢迎大家来提交 Issues~
当前支持的 PHP 版本, 如下图所示:
3,SG 的特性
简单, 快速, 轻量
零拷贝访问 PHP 超全局变量, 使用 SG 会同步更新 PHP 超全局变量
支持取值前调用自定义函数, 默认情况下, 字符串变量会自动调用 PHP trim
解决使用 PHP 超全局变量时出现未定义系列的问题 (Undefined variable, Undefinedoffset)
采用静态方法时, 以小数点代替 PHP 数组维度
采用 global 声明方式时, 以下划线代替 PHP 数组维度
支持可配置的 global $variable 查找深度, 默认一级查找
4, 配置项 (PHP.INI)
配置项 | 权限 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
sg.enable | PHP_INI_SYSTEM | bool | 0 | 0 关闭 1 开启 |
sg.global_level | PHP_INI_SYSTEM | bool | 1 | 1 只支持一级查找 0 无限制查找 |
sg.func_name | PHP_INI_ALL | char | trim | 默认调用 PHP trim http://php.net/manual/en/function.trim.php 函数,也支持自定义函数 |
5,Hash Map
PHP 超全局变量 | SG key (关键字缩写) | global 声明 | 函数 |
---|---|---|---|
$GLOBALS | 无 | 无 | sg::all() |
$_SERVER | s | global $s | sg::get/set/has/del('s') |
$_GET | g | global $g | sg::get/set/has/del('g') |
$_POST | p | global $p | sg::get/set/has/del('p') |
$_FILES | f | global $f | sg::get/set/has/del('f') |
$_COOKIE | c | global $c | sg::get/set/has/del('c') |
$_SESSION | n | global $n | sg::get/set/has/del('n') |
$_REQUEST | r | global $r | sg::get/set/has/del('r') |
$_ENV | e | global $e | sg::get/set/has/del('e') |
6, 流程图
6.1 global 声明方式 (php7)
6.2 函数方式
7,API
7.1 global 声明方式
global $g_key, $p_key, $c_key, $s_key, $f_key, $n_key, $e_key, $r_key
7.2 静态方法
- bool sg::set(string $key, mixed $value)
- mixed sg::get(string $key [, mixed $default_value = null])
- bool sg::has(string $key)
- bool sg::del(string $key [, mixed $... ])
- array sg::all(void)
8, 例子
8.1 global 声明例子
- 8.1.1 sg.global_level = 1
- <?PHP
- $_GET['key'] = 'GET_test_key';
- function testGlobal()
- {
- global $g_key;
- var_dump($g_key);
- $g_key = 'NEW_GET_test_key';
- }
- testGlobal();
- var_dump(sg::get('g.key'));
- var_dump($GLOBALS['g_key']);
- var_dump($g_key);
- var_dump($_GET['key']);
以上例子输出的结果:
- string(12) "GET_test_key"
- string(16) "NEW_GET_test_key"
- string(16) "NEW_GET_test_key"
- string(16) "NEW_GET_test_key"
- string(16) "NEW_GET_test_key"
- 8.1.2 sg.global_level = 0
- <?PHP
- $_GET['key']['key1']['key2'] = 'GET_test_key';
- function testGlobal()
- {
- global $g_key_key1_key2;
- }
- testGlobal();
- var_dump(sg::get('g.key.key1.key2'));
- var_dump($GLOBALS['g_key_key1_key2']);
- var_dump($g_key_key1_key2);
- var_dump($_GET['key']['key1']['key2']);
以上例子输出的结果:
- string(12) "GET_test_key"
- string(12) "GET_test_key"
- string(12) "GET_test_key"
- string(12) "GET_test_key"
- 8.1.3 sg.func_name
- <?PHP
- ini_set('sg.func_name', 'decryptTest');
- $_POST['key'] = 'IEEgQmFuYW5hIA==';
- function decryptTest($data)
- {
- return trim(base64_decode($data));
- }
- var_dump($p_key);
以上例子输出的结果:
string(8) "A Banana"
8.2 静态方法例子
- 8.2.1 get/set/has/del()
- <?PHP
- $key = 'test';
- $val = 'A Banana';
- echo "------------------start\n";
- var_dump(sg::get($key));
- var_dump(sg::get($key, 'def'));
- var_dump(sg::has($key));
- echo "------------------set\n";
- var_dump(sg::set($key, $val));
- echo "------------------get\n";
- var_dump(sg::get($key));
- var_dump(sg::get($key, 'def'));
- var_dump(sg::has($key));
- echo "------------------del\n";
- var_dump(sg::del($key));
- echo "------------------get\n";
- var_dump(sg::get($key));
- var_dump(sg::has($key));
以上例子输出的结果:
- ------------------start
- NULL
- string(3) "def"
- bool(false)
- ------------------set
- bool(true)
- ------------------get
- string(8) "A banana"
- string(8) "A banana"
- bool(true)
- ------------------del
- bool(true)
- ------------------get
- NULL
- bool(false)
- 8.2.2 sg.func_name
- <?PHP
- ini_set('sg.func_name', 'encryptTest');
- function decryptTest($data)
- {
- return trim(base64_decode($data));
- }
- function encryptTest($data)
- {
- return base64_encode(trim($data));
- }
- sg::set('user', encryptTest('A Banana'));
- var_dump(sg::get('user'));
以上例子输出的结果:
string(8) "A Banana"
9, 性能测试
噼里啪啦说了大半天, 性能到底怎么样呢? 我在本地环境做了一个简单的 ab 测试 (ab -c100 -n10000),PHP 测试代码如下:
9.1 default - 源码
- <?PHP
- /* default.PHP */
- for($i = 0; $i < 1000; $i++) {
- if(isset($_GET['key'])) {
- var_dump(trim($_GET['key']));
- }
- }
9.2 global 声明方式 - 源码
- <?PHP
- /* sg.PHP */
- for($i = 0; $i < 1000; $i++) {
- global $g_key;
- var_dump($g_key);
- }
ab 测试的结果如下:
9.3 default - 结果
- $ ab -c100 -n10000 localhost/default.PHP?key=hello_world
- Concurrency Level: 100
- Time taken for tests: 1.615 seconds
- Complete requests: 10000
- Failed requests: 0
- Write errors: 0
- Total transferred: 251370000 bytes
- html transferred: 250000000 bytes
- Requests per second: 6190.21 [#/sec] (mean)
- Time per request: 16.155 [ms] (mean)
- Time per request: 0.162 [ms] (mean, across all concurrent requests)
- Transfer rate: 151956.36 [Kbytes/sec] received
9.4 global 声明方式 - 结果
- $ ab -c100 -n10000 localhost/sg.PHP?key=hello_world
- Concurrency Level: 100
- Time taken for tests: 1.441 seconds
- Complete requests: 10000
- Failed requests: 0
- Write errors: 0
- Total transferred: 251931544 bytes
- HTML transferred: 250557708 bytes
- Requests per second: 6938.67 [#/sec] (mean)
- Time per request: 14.412 [ms] (mean)
- Time per request: 0.144 [ms] (mean, across all concurrent requests)
- Transfer rate: 170709.87 [Kbytes/sec] received
10, 总 结
SG 具有以下优势:
兼容了当前的主流 PHP 版本
提供了一种更加甜蜜的语法, 丰富了 Superglobals 的应用
我们始终相信: 简单才是王道
注意: global 声明方式, 当前只支持不可变变量名.
(360 技术原创内容, 转载请务必保留文末二维码, 谢谢~)
关于 360 技术
360 技术是 360 技术团队打造的技术分享公众号, 每天推送技术干货内容
更多技术信息欢迎关注 "360 技术" 微信公众号
来源: https://segmentfault.com/a/1190000019436481