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

PHP 中如何优雅的处理未定义变量

  •  
  •   fbzl · 2015-06-07 14:06:40 +08:00 via iPhone · 6539 次点击
    这是一个创建于 3456 天前的主题,其中的信息可能已经有所发展或是发生改变。
    没有使用框架的老程序中经常会有获取$_GET['id'],而id确不存在,开启报错时,都会看到好多报错。

    一种最原始的手动判断(一大坨,影响逻辑的代码)

    写一个判断变量是否存在的函数(用的时候感觉怪怪的)

    另一种情况是未知成员对象引用也会报错


    PS:开发环境拒绝关闭报错
    27 条回复    2015-06-08 00:02:15 +08:00
    shiny
        1
    shiny  
       2015-06-07 14:08:46 +08:00   ❤️ 2
    最低等:isset
    中级: filter_input
    终极:开发框架集成自动处理
    AlloVince
        2
    AlloVince  
       2015-06-07 14:18:21 +08:00   ❤️ 1
    $params = array_merge(['id' => ''], $_GET);

    if ($params['id'])
    ...
    zhengkai
        3
    zhengkai  
       2015-06-07 14:42:25 +08:00
    $_GET += [
    'id' => 0,
    'page' => 1,
    ];
    zhengkai
        4
    zhengkai  
       2015-06-07 14:46:28 +08:00   ❤️ 1
    这种方法一般不用在 _GET _POST 上,因为网页参数要做很多处理,没有特别声明的整数要禁止负数,字符串要确保是 utf-8 的,等等

    一般用在参数上, += 不仅仅是比 array_merge() 简短,还能避免一个坑。如果你的 key 恰好是 0,1,2 这种的,+= 是覆盖,array_merge 的话会给你搞出 3,4,5,3 个 key 变成 6 个 key ……
    MntCw
        5
    MntCw  
       2015-06-07 15:30:40 +08:00
    @shiny 调用函数也分低高级,也是醉了。

    业务逻辑理清楚,在用到相应变量时提前做处理。
    三元操作符还是挺好用的。
    fbzl
        6
    fbzl  
    OP
       2015-06-07 15:34:26 +08:00
    @shiny

    isset 有一个坑是在赋值为 null 时 会返回 false

    @zhengkai

    数字key无法合并,好坑

    += 在php 5.4才开始可以用,开始用5.3.29测试 报错(囧

    ---

    前期先用楼上的方法顶着,后期会重构自动处理,每次传值看起来都不爽
    shiny
        7
    shiny  
       2015-06-07 15:49:04 +08:00
    @MntCw 这个自己写个几年体会咯
    moro
        8
    moro  
       2015-06-07 16:06:08 +08:00
    @
    b821025551b
        9
    b821025551b  
       2015-06-07 16:17:31 +08:00 via Android
    empty配合三目
    em70
        10
    em70  
       2015-06-07 16:20:35 +08:00
    error_reporting(0)
    世界不就清静了
    zhengkai
        11
    zhengkai  
       2015-06-07 16:33:00 +08:00
    @fbzl 5.4 才能用的是 array() 可以写成 [],+= 应该是一直能用的
    fbzl
        13
    fbzl  
    OP
       2015-06-07 17:25:24 +08:00
    @zhengkai 手册上写的

    array

    (PHP 4, PHP 5)
    array — Create an array

    ---

    As of PHP 5.4.x you can now use 'short syntax arrays' which eliminates the need of this function.

    Example #1 'short syntax array'
    <?php
    $a = [1, 2, 3, 4];
    print_r($a);
    ?>

    ---



    @b821025551b

    empty()会提示'PHP Notice: Undefined index: id',就是为了避免这个问题的,我才问的


    @em70

    问题描述中特别指明了,不能关闭报错
    fbzl
        14
    fbzl  
    OP
       2015-06-07 17:52:16 +08:00
    @yangmls

    本来准备去成熟框架中找的,但是没时间去找,之后也准备用`Laravel`重构

    代码中

    return value($default);

    value 是自定义的吗?PHP中好像没有这个函数
    yangmls
        15
    yangmls  
       2015-06-07 17:57:51 +08:00   ❤️ 1
    yangmls
        16
    yangmls  
       2015-06-07 17:59:54 +08:00
    楼上的 merge 方案无法处理多重数组的情况,而 laravel 能够简单地用 array_get($arr, 'foo.bar') 来获取

    楼上的 isset 问题也考虑到了,所以用的 array_key_exists
    fbzl
        17
    fbzl  
    OP
       2015-06-07 18:03:56 +08:00
    @yangmls

    难道我搜索姿势不对,在Github上搜了195个结果,看了四五页就看不下去了
    yangmls
        18
    yangmls  
       2015-06-07 18:05:55 +08:00
    @fbzl 搜索什么?
    micate
        19
    micate  
       2015-06-07 18:14:37 +08:00
    自己实现一个类似 laravel 的 array_get() 方法是比较方便的,而且也不费电呀。
    geeglo
        20
    geeglo  
       2015-06-07 18:22:27 +08:00
    $id = empty($_GET['id']) ? 1 : intval($_GET['id']);

    这样写不会报错的呀~你是不是记错了?
    fbzl
        21
    fbzl  
    OP
       2015-06-07 18:36:57 +08:00 via iPhone
    @geeglo 前后顺序写错了,汗
    lyragosa
        22
    lyragosa  
       2015-06-07 18:41:30 +08:00
    我是直接禁用所有报错信息,眼不见为净。

    历史遗留没那么好修的
    fbzl
        23
    fbzl  
    OP
       2015-06-07 22:15:09 +08:00 via iPhone
    @lyragosa
    原来是5.2版本的,存在攻击漏洞,该升级了

    顺便为了整理下逻辑,为自己开发方便点

    看看有什么潜在漏洞后门之类的
    tcsky
        24
    tcsky  
       2015-06-07 23:40:31 +08:00
    写一个全局的 array_get函数,用来处理数组.
    skydiver
        25
    skydiver  
       2015-06-07 23:56:19 +08:00
    @fbzl 你记错了,empty不会报notice
    skydiver
        26
    skydiver  
       2015-06-07 23:56:55 +08:00
    优雅的方法就是不要直接读取全局变量$_GET $_POST,而是用框架提供的方法。
    fbzl
        27
    fbzl  
    OP
       2015-06-08 00:02:15 +08:00 via iPhone
    @skydiver

    嗯,我逻辑写错了,直接替换的isset

    现在的系统框架不完善,下一步就是重构,过渡期先找一下替代方案,还有一些小项目(随手写的)也可以用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2303 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:06 · PVG 00:06 · LAX 08:06 · JFK 11:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.