Is there a better PHP way for getting default value by key from array (dictionary)?

后端 未结 8 1116
庸人自扰
庸人自扰 2020-12-13 08:30

In Python one can do:

foo = {}
assert foo.get(\'bar\', \'baz\') == \'baz\'

In PHP one can go for a trinary operator as in:<

相关标签:
8条回答
  • 2020-12-13 08:44

    Use the error control operator @ with the PHP 5.3 shortcut version of the ternary operator:

    $bar = @$foo['bar'] ?: 'defaultvalue';
    
    0 讨论(0)
  • 2020-12-13 08:50

    Time passes and PHP is evolving. PHP 7 now supports the null coalescing operator, ??:

    // Fetches the value of $_GET['user'] and returns 'nobody'
    // if it does not exist.
    $username = $_GET['user'] ?? 'nobody';
    // This is equivalent to:
    $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
    
    // Coalescing can be chained: this will return the first
    // defined value out of $_GET['user'], $_POST['user'], and
    // 'nobody'.
    $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
    
    0 讨论(0)
  • 2020-12-13 08:51

    I just came up with this little helper function:

    function get(&$var, $default=null) {
        return isset($var) ? $var : $default;
    }
    

    Not only does this work for dictionaries, but for all kind of variables:

    $test = array('foo'=>'bar');
    get($test['foo'],'nope'); // bar
    get($test['baz'],'nope'); // nope
    get($test['spam']['eggs'],'nope'); // nope
    get($undefined,'nope'); // nope
    

    Passing a previously undefined variable per reference doesn't cause a NOTICE error. Instead, passing $var by reference will define it and set it to null. The default value will also be returned if the passed variable is null. Also note the implicitly generated array in the spam/eggs example:

    json_encode($test); // {"foo":"bar","baz":null,"spam":{"eggs":null}}
    $undefined===null; // true (got defined by passing it to get)
    isset($undefined) // false
    get($undefined,'nope'); // nope
    

    Note that even though $var is passed by reference, the result of get($var) will be a copy of $var, not a reference. I hope this helps!

    0 讨论(0)
  • 2020-12-13 08:56

    A "slightly" hacky way to do it:

    <?php
        $foo = array();
        var_dump('baz' == $tmp = &$foo['bar']);
        $foo['bar'] = 'baz';
        var_dump('baz' == $tmp = &$foo['bar']);
    

    http://codepad.viper-7.com/flXHCH

    Obviously this isn't really the nice way to do it. But it is handy in other situations. E.g. I often declare shortcuts to GET and POST variables like that:

    <?php
        $name =& $_GET['name'];
        // instead of
        $name = isset($_GET['name']) ? $_GET['name'] : null;
    

    PS: One could call this the "built-in ==$_=& special comparison operator":

    <?php
        var_dump('baz' ==$_=& $foo['bar']);
    

    PPS: Well, you could obviously just use

    <?php
        var_dump('baz' == @$foo['bar']);
    

    but that's even worse than the ==$_=& operator. People don't like the error suppression operator much, you know.

    0 讨论(0)
  • 2020-12-13 08:56

    If you enumerate the default values by key in an array, it can be done this way:

    $foo = array('a' => 1, 'b' => 2);
    $defaults = array('b' => 55, 'c' => 44);
    
    $foo = array_merge($defaults, $foo);
    
    print_r($foo);
    

    Which results in:

    Array
    (
        [b] => 2
        [c] => 44
        [a] => 1
    )
    

    The more key/value pairs that you enumerate defaults for, the better the code-golf becomes.

    0 讨论(0)
  • 2020-12-13 08:58

    I find it useful to create a function like so:

    function array_value($array, $key, $default_value = null) {
        return is_array($array) && array_key_exists($key, $array) ? $array[$key] : $default_value;
    }
    

    And use it like this:

    $params = array('code' => 7777, 'name' => "Cloud Strife"); 
    
    $code    = array_value($params, 'code');
    $name    = array_value($params, 'name');
    $weapon  = array_value($params, 'weapon', "Buster Sword");
    $materia = array_value($params, 'materia');
    
    echo "{ code: $code, name: $name, weapon: $weapon, materia: $materia }";
    

    The default value in this case is null, but you may set it to whatever you need.

    I hope it is useful.

    0 讨论(0)
提交回复
热议问题