SG :一個簡單的PHP語法糖擴展

奇技指南
語法糖每每給程序員提供了更實用的編碼方式,可使代碼更簡潔流暢,語義更天然。本文介紹筆者本身寫的PHP語法糖擴展,擴展了一種全新的PHP超全局變量獲取方式。
本文做者範家鵬,360技術委員會--WEB服務端分TC委員。

一、說說語法糖

首先說說「語法糖」這個詞絕非貶義詞,它能夠給咱們的開發工做帶來便利,是一種輕量級便捷的寫法,既不會對語言自己的使用形成不利影響,也不會在性能上帶來損失。php

一般狀況下,使用語法糖可以增長程序的可讀性,減小程序複雜性,減小編碼中出錯的機會,也對開發工程師具備友好性,可以提高咱們的開發效率。 git

優秀的語法糖,應該是一種靈魂思想的注入,簡單寫法的應用。我這裏用一幅圖來表示:程序員

二、什麼是SG?

SG 全稱 Superglobals,引用全局做用域中可用的所有變量。SG擴展了一種全新的PHP超全局變量獲取方式。 github

這些超全局變量是:_SERVER,_GET,_POST,_FILES,_COOKIE,_SESSION,_REQUEST,_ENV。 shell

固然了,也能夠應用到自定義變量場景。數組

很是重要的一點是:它很簡單微信

2.1 項目背景

這個idea出發點很簡單,從擴展名稱咱們應該能猜到它是作什麼的。ide

在性能最優的前提下: 函數

  • 能通俗易懂地簡化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超全局變量,使用SG會同步更新PHP超全局變量 
  • 支持取值前調用自定義函數,默認狀況下,字符串變量會自動調用 PHP trim 
  • 解決使用PHP超全局變量時出現未定義系列的問題 (Undefined variable, Undefinedoffset) 
  • 採用靜態方法時,以小數點代替PHP數組維度 
  • 採用global聲明方式時,如下劃線代替PHP數組維度
  • 支持可配置的global $variable查找深度,默認一級查找

四、配置項(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 函數,也支持自定義函數

五、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.1 global 聲明方式(PHP7)

6.2 函數方式

七、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.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"

九、性能測試

噼裏啪啦說了大半天,性能到底怎麼樣呢?我在本地環境作了一個簡單的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

十、總  結

SG具備如下優點:

  • 兼容了當前的主流PHP版本 
  • 提供了一種更加甜蜜的語法,豐富了Superglobals的應用
  • 咱們始終相信:簡單纔是王道

注意:global 聲明方式,當前只支持不可變變量名。

(360技術原創內容,轉載請務必保留文末二維碼,謝謝~)

關於360技術

360技術是360技術團隊打造的技術分享公衆號,天天推送技術乾貨內容

更多技術信息歡迎關注「360技術」微信公衆號

相關文章
相關標籤/搜索