La mejor manera de dar a una variable un valor predeterminado (simular Perl||, / / =)


Me encanta hacer este tipo de cosas en Perl: $foo = $bar || $baz para asignar $baz a $foo si $bar está vacío o indefinido. También tiene $foo ||= $bletch que solo asignará $bletch a $foo si $foo no está definido o vacío.

El operador ternario en esta situación es tedioso y aburrido. Seguramente hay un método simple y elegante disponible en PHP?

¿O es la única respuesta una función personalizada que usa isset()?

Author: BoltClock, 2011-05-12

5 answers

PHP 5.3 tiene un operador abreviado ?::

$foo = $bar ?: $baz;

Que asigna $bar si no es un valor vacío (no se cómo esto sería diferente en PHP de Perl), de lo contrario $baz, y es lo mismo que esto en Perl y versiones anteriores de PHP:

$foo = $bar ? $bar : $baz;

Pero PHP no tiene un operador de asignación compuesto para esto (es decir, ningún equivalente al ||= de Perl).

Además, PHP hará ruido si $bar no está configurado a menos que desactive los avisos. También hay una diferencia semántica entre isset() y empty(). El primero devuelve false si la variable no existe, o se establece en NULL. Este último devuelve true si no existe, o se establece en 0, '', false o NULL.

 173
Author: BoltClock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-12 08:30:58

En PHP 7 finalmente tenemos una manera de hacer esto elegantemente. Se llama el operador de coalescencia null . Puedes usarlo así:

$name = $_GET['name'] ?? 'john doe';

Esto es equivalente a

$name = isset($_GET['name']) ? $_GET['name']:'john doe';
 65
Author: jpschroeder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-22 14:48:19

Un modismo común para mantenerse compatible con versiones anteriores de PHP es:

 $var = $bool   or   $var = "default";
 // If I use it, then only with excessive spaces for clarity.

Esto funciona para valores que pueden ser evaluados en contexto booleano. La ventaja aquí es que también le da dicho debug e_notice si la variable no está definida.

 7
Author: mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-12 01:59:54

Gracias por todas las grandes respuestas!

Para cualquiera que venga aquí por una posible alternativa, aquí hay algunas funciones que ayudan a eliminar el tedio de este tipo de cosas.

function set_if_defined(&$var, $test){
    if (isset($test)){
        $var = $test;
        return true;
    } else {
        return false;
    }
}

function set_unless_defined(&$var, $default_var){
    if (! isset($var)){
        $var = $default_var;
        return true;
    } else {
        return false;
    }
}

function select_defined(){
    $l = func_num_args();
    $a = func_get_args();
    for ($i=0; $i<$l; $i++){
        if ($a[$i]) return $a[$i];
    }
}

Ejemplos:

// $foo ||= $bar;
set_unless_defined($foo, $bar);

//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);

Estoy seguro de que estos pueden ser mejorados.

 7
Author: Tom Auger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-22 16:40:31

En PHP anterior a 7.* , se puede utilizar ?: para una variable indefinida que tiene errores suprimidos localmente con un @:

$foo = @$bar ?: $baz;
 1
Author: AndreyS Scherbakov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-28 11:23:08