V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanjiapeng
V2EX  ›  PHP

一个超级简单的 PHP 超全局变量管理扩展

  •  
  •   fanjiapeng · 2019-03-31 16:28:53 +08:00 · 3633 次点击
    这是一个创建于 2062 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个超级简单的 PHP 超全局变量管理扩展(自卖自夸)

    English Document

    介绍

    SG 全称 Superglobals,它的诞生为了方便快捷操作 PHP 预定义的超全局变量,用户定义的超全局变量。

    如果在非 CLI 模式,SG 默认托管 PHP 预定义的超全局变量, 包括常用 $_GET,$_POST,$_COOOKIE,$_SERVER,$_FILES。

    使用 SG 类,可以大大的减少我们的 PHP 代码量,提高我们的开发效率。

    亮点功能

    • 简单,快速,轻量
    • 零拷贝访问全局变量
    • 支持自动过滤前后空格PHP trim
    • 解决操作 PHP 全局变量时出现未定义系列的问题 (Undefined variable, Undefined offset)

    安装

    PHP 版本支持包括

    • PHP 5.4 +
    • PHP 7.0 +

    下载源码

    git clone https://github.com/yulonghu/sg.git
    

    Linux 系统,编译 SG 扩展

    $ /path/to/php/bin/phpize
    $ ./configure --with-php-config=/path/to/php/bin/php-config
    $ make && make install
    

    php.ini ,添加、开启扩展

    extension=sg.so
    
    [sg]
    sg.enable = On
    

    重启 php 进程,就安装成功啦。

    提供的方法

    mixed sg::get(string $key [, mixed $default_value = null])
    bool sg::set(string $key, mixed $value)
    bool sg::has(string $key)
    bool sg::del(string $key)
    

    支持的 INI 配置项

    sg.enable = On/Off
    sg.auto_trim = On/Off ; Strip whitespace with PHP trim
    

    详细例子

    获取 PHP 预定义的超全局变量

    (表格好像不好用呢,这样凑合看吧~)

    |传统的获取方式 (短) | 新获取方式|
    | ------------- | ------------- |
    |$_GET['key']    | sg::get('g.key')|
    |$_POST['key']   | sg::get('p.key')|
    |$_COOKIE['key'] | sg::get('c.key')|
    |$_SERVER['key'] | sg::get('s.key')|
    |$_FILES['key']  | sg::get('f.key')|
    
    |传统的获取方式 (长) | 新获取方式|
    | ------------- | ------------- |
    |$_GET['key']['key1']['key2']    | sg::get('g.key.key1.key2')|
    |$_POST['key']['key1']['key2']   | sg::get('p.key.key1.key2')|
    |$_COOKIE['key']['key1']['key2'] | sg::get('c.key.key1.key2')|
    |$_SERVER['key']['key1']['key2'] | sg::get('s.key.key1.key2')|
    |$_FILES['key']['key1']['key2']  | sg::get('f.key.key1.key2')|
    
    |传统的获取方式 (isset + trim) | 新获取方式|
    | ------------- | ------------- |
    |$key = isset($_GET['key']) ? trim($_GET['key']) : null;       | $key = sg::get('g.key');|
    |$key = isset($_POST['key']) ? trim($_POST['key']) : null;     | $key = sg::get('p.key');|
    |$key = isset($_COOKIE['key']) ? trim($_COOKIE['key']) : null; | $key = sg::get('c.key');|
    |$key = isset($_SERVER['key']) ? trim($_SERVER['key']) : null; | $key = sg::get('s.key');|
    |$key = isset($_FILES['key']) ? trim($_FILES['key']) : null;   | $key = sg::get('f.key');|
    

    设置超全局变量

    bool sg::set(string $key, mixed $value)

    <?php
    var_dump(sg::set('test', 'test apple'));
    var_dump(sg::set('user.0.0', 'user 0 apple'));
    var_dump(sg::set('user.0.1', 'user 1 apple'));
    var_dump(sg::set('user.a.a', 'user a apple'));
    var_dump(sg::set('user.a.b', 'user b apple'));
    
    // 以下方式不推荐,更新 PHP 预定义的超全局变量值
    var_dump(sg::set('g.key', 'value'));
    var_dump(sg::set('p.key', 'value'));
    var_dump(sg::set('c.key', 'value'));
    var_dump(sg::set('s.key', 'value'));
    var_dump(sg::set('f.key', 'value'));
    

    以上例子输出的结果:

    bool(true)
    bool(true)
    bool(true)
    bool(true)
    bool(true)
    
    bool(true)
    bool(true)
    bool(true)
    bool(true)
    bool(true)
    

    mixed sg::get(string $key [, mixed $default_value = null])

    <?php
    var_dump(sg::get('test', 'test apple'));
    var_dump(sg::get('user');
    var_dump(sg::get('not_found', 'def');
    var_dump(sg::get('user.1.2.3.4'));
    

    以上例子输出的结果:

    string(10) "test apple"
    array(2) {
      [0]=>
      array(2) {
        [0]=>
        string(12) "user 0 apple"
        [1]=>
        string(12) "user 1 apple"
      }
      ["a"]=>
      array(2) {
        ["a"]=>
        string(12) "user a apple"
        ["b"]=>
        string(12) "user b apple"
      }
    }
    string(3) "def"
    NULL
    

    bool sg::has(string $key)

    <?php
    var_dump(sg::has('test'));
    var_dump(sg::has('not_found'));
    

    以上例子输出的结果:

    bool(true)
    bool(false)
    

    bool sg::del(string $key)

    <?php
    var_dump(sg::del('test'));
    var_dump(sg::del('user.0.1'));
    var_dump(sg::get('user');
    

    以上例子输出的结果:

    bool(true)
    bool(true)
    array(2) {
      [0]=>
      array(1) {
        [0]=>
        string(12) "user 0 apple"
      }
      ["a"]=>
      array(2) {
        ["a"]=>
        string(12) "user a apple"
        ["b"]=>
        string(12) "user b apple"
      }
    }
    

    sg.auto_trim

    演示自动过滤前后空格的例子, 支持两种方式开启自动过滤。

    为了获得最佳性能,如果满足 trim 条件, sg 将改变原始值。避免每次取值时重复做 trim 操作。

    <?php
    ini_set('sg.auto_trim', 1);
    function One() {
        var_dump(sg::set('test', ' test apple ')); // Auto-call PHP trim
    }
    function Two() {
        var_dump(sg::get('test'));
    }
    

    以上例子输出的结果:

    bool(true)
    string(10) "test apple"
    

    License

    SG is open source software under the PHP License v3.01

    9 条回复    2019-04-05 22:48:36 +08:00
    dvaknheo
        1
    dvaknheo  
       2019-03-31 17:18:27 +08:00
    DNMVCS::SG()->_GET / _POST 系列是为了解决 Swoole 环境下不能直接用 $_GET 的问题。

    简单,快速,轻量
    零拷贝访问全局变量
    支持自动过滤前后空格 PHP trim
    //不要给默认变量加额外的功能,而是让开发者手动知道

    解决操作 PHP 全局变量时出现未定义系列的问题 (Undefined variable, Undefined offset)
    //php7 本身的 ?? 操作符号就够了

    如果觉得超全局变量不够优雅,那么等 PHP 官方出函数再说吧。
    unicloud
        2
    unicloud  
       2019-03-31 18:16:14 +08:00 via iPhone
    这不是语法糖吗?
    masker
        3
    masker  
       2019-03-31 18:57:59 +08:00 via Android
    我觉得 env 库更好用点
    sunmonster
        4
    sunmonster  
       2019-03-31 20:56:21 +08:00
    很奇怪为什么会有这样的需求,一般做项目会使用框架,不会直接操作$_GET 这种系统全局变量的,会遵循 psr-7 规范,如果是自定义全局变量,不是应该尽量避免使用吗?如果是全局配置参数,把变量放在 ini 或 yaml 文件不是更方便,如果是分布式配置可以使用 consul 管理,我不知道这种扩展的应用场景在哪里
    GM
        5
    GM  
       2019-03-31 21:26:41 +08:00
    php7 的 ?? 语法了解一下:

    $value = $_GET['key']['key1']['key2']['key3']['key4'] ?? "default_value";
    fanjiapeng
        6
    fanjiapeng  
    OP
       2019-04-01 14:54:09 +08:00
    @GM
    ?? 是 PHP7 引进的,名为 null 合并运算符,just like isset(),这种写法可能容易出错,也多了代码量。还少了一个 trim 函数的调用。
    GM
        7
    GM  
       2019-04-01 16:19:32 +08:00
    @fanjiapeng
    $value = sg::get('g.key.key1.key2.key3.key4', ' default_value');这样能减少代码量?你是不是对代码量有什么误解。。。

    至于 sg::get() 函数的静默 trim,你确定这样符合用户的意图?
    jamblues
        8
    jamblues  
       2019-04-02 23:33:19 +08:00
    可以考虑加上参数声明类型或者 trim, like this:
    sg::get('key:trim');
    sg::get('key:int');
    sg::get('key:trim:strip_tags');
    dvaknheo
        9
    dvaknheo  
       2019-04-05 22:48:36 +08:00
    sg::get('key:trim');
    那还不如
    trim(sg::get('key'));
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5592 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 06:07 · PVG 14:07 · LAX 22:07 · JFK 01:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.