SG :一个简单的PHP语法糖扩展

智数觅星人
• 阅读 10221
奇技指南
语法糖往往给程序员提供了更实用的编码方式,可以使代码更简洁流畅,语义更自然。本文介绍笔者自己写的PHP语法糖扩展,扩展了一种全新的PHP超全局变量获取方式。
本文作者范家鹏,360技术委员会--WEB服务端分TC委员。

1、说说语法糖

首先说说“语法糖”这个词绝非贬义词,它可以给我们的开发工作带来便利,是一种轻量级便捷的写法,既不会对语言本身的使用造成不利影响,也不会在性能上带来损失。

通常情况下,使用语法糖能够增加程序的可读性,减少程序复杂性,减少编码中出错的机会,也对开发工程师具有友好性,能够提升我们的开发效率。 

优秀的语法糖,应该是一种灵魂思想的注入,简单写法的应用。我这里用一幅图来表示:

SG :一个简单的PHP语法糖扩展

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版本,如下图所示:

SG :一个简单的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 函数,也支持自定义函数

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)

SG :一个简单的PHP语法糖扩展

6.2 函数方式

SG :一个简单的PHP语法糖扩展

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));
}
global $p_key;
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', 'decryptTest');

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技术原创内容,转载请务必保留文末二维码,谢谢~)

SG :一个简单的PHP语法糖扩展

关于360技术

360技术是360技术团队打造的技术分享公众号,每天推送技术干货内容

更多技术信息欢迎关注“360技术”微信公众号

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
React Hooks实现异步请求实例—useReducer、useContext和useEffect代替Redux方案
<blockquote本文是学习了2018年新鲜出炉的ReactHooks提案之后,针对<strong异步请求数据</strong写的一个案例。注意,本文假设了:<br1.你已经初步了解<codehooks</code的含义了,如果不了解还请移步<ahref"https://reactjs.org/docs/hooksintro.html
Stella981 Stella981
3年前
PHP代码静态分析工具PHPStan
<blockquote最近发现自己写的PHP代码运行结果总跟自己预想的不一样,排查时发现大多是语法错误,在运行之前错误已经种下。可能是自己粗心大意,或者说<codephpl</code检测太简单,不过的确是有一些语法错误埋藏得太深(毕竟PHP是动态语言),那么有没有办法,在代码代码正式运行之前,把语法错误全找出来呢?</blockquote<p
Stella981 Stella981
3年前
Kafka学习之(三)Centos下给PHP开启Kafka扩展(rdkafka)
Centos版本:Centos6.4,PHP版本:PHP7。在上一篇文章中使用IP为192.168.9.154的机器安装并开启了Kafka进行了简单测试,充当了Kafka服务器。本篇文章新开启一台IP为192.16.9.157的机器给PHP开启扩展。找到github的扩展下载地址,这里是phprdkafka,虽然php有一个扩展是phpkaf
Wesley13 Wesley13
3年前
Java和PHP在Web开发方面的比较
比较PHP和JSP这两个Web开发技术,在目前的情况是其实是比较PHP和Java的Web开发。以下是我就几个主要方面进行的比较:一、语言比较  PHP是解释执行的服务器脚本语言,首先php有简单容易上手的特点。语法和c语言比较象,所以学过c语言的程序员可以很快的熟悉php的开发。而java需要先学好java的语法和熟悉一些核心的
Wesley13 Wesley13
3年前
Linux下PHP安装Redis扩展
pecl.php.net,PECL库是一个PHP扩展,提供一个目录的所有已知的扩展和托管设备下载PHP扩展,PHP很多扩展都可以在这里面找到。今天主要讲解下Linux下php安装redis扩展,附有windows下redis扩展安装。1、PHP redis(https://www.oschina.net/action/GoToLink?url
Stella981 Stella981
3年前
PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)
PHP与MySQL的连接有三种API接口,分别是:PHP的MySQL扩展、PHP的mysqli扩展、PHP数据对象(PDO),下面针对以上三种连接方式做下总结,以备在不同场景下选出最优方案。PHP的MySQL扩展是设计开发允许php应用与MySQL数据库交互的早期扩展。MySQL扩展提供了一个面向过程的接口,并且是针对MySQL4.1.3或者更早版
Wesley13 Wesley13
3年前
PHP代码优化的一些重要技巧
除了要学习PHP的基本知识,比如《为开发者准备的9个实用PHP代码片段》《深入探讨PHP类的封装与继承》《PHP比较运算符的详细学习》,还要了解一些代码优化上的技巧,从而帮助我们写出更加优秀的程序。我们在编写程序时,总是想要使自己的程序占用资源最小,运行速度更快,代码量更少。PHP独特的语法混合了C、Java、Perl以及PHP自创新的语法,它可以
Stella981 Stella981
3年前
Kotlin代码检查在美团的探索与实践
背景Kotlin有着诸多的特性,比如空指针安全、方法扩展、支持函数式编程、丰富的语法糖等。这些特性使得Kotlin的代码比Java简洁优雅许多,提高了代码的可读性和可维护性,节省了开发时间,提高了开发效率。这也是我们团队转向Kotlin的原因,但是在实际的使用过程中,我们发现看似写法简单的Kotlin代码,可能隐藏着不容忽视的额外开销。本文剖析了K
Wesley13 Wesley13
3年前
SG :一个简单的PHP语法糖扩展
奇技指南语法糖往往给程序员提供了更实用的编码方式,可以使代码更简洁流畅,语义更自然。本文介绍笔者自己写的PHP语法糖扩展,扩展了一种全新的PHP超全局变量获取方式。本文作者范家鹏,360技术委员会WEB服务端分TC委员。1、说说语法糖首先说说“语法糖”这个词绝非贬义词,它可以给我们的开发工作带来便利,是一种轻量级便
Stella981 Stella981
3年前
PHP 多国语言内容管理系统(Tmaic CMS)多端全媒体解决方案
国内流行的多国语言内容管理系统(TmaicCMS)多端全媒体解决方案,国内首创多语言内容解决方案,TmaicCMS系统基于PHP7.X开发,具有很强的可扩展性,并且完全开放源代码。让TmaicCMS系统拥有简单易用、灵活扩展特性之外更安全、高效。模板设计制作简单一直是系统的一大特点,强大的标签引擎,让搭建跨终端(移动、PC)全媒体站点更简单。详情