2011-05-12 12 views
75

Me encanta hacer este tipo de cosas en Perl: $foo = $bar || $baz para asignar a $baz$foo si $bar está vacía o no definido. También tiene $foo ||= $bletch que solo asignará $bletch a $foo si $foo no está definido o vacío.mejor manera de darle una variable un valor por defecto (simular Perl ||, || =)

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

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

+0

Relacionado en [Codereview.SE]: http://codereview.stackexchange.com/q/12722/31433 – Palec

+1

Por cierto, los operadores de Perl con la funcionalidad deseada son '//' y '// =' y existen a partir de Perl v5.10.0. La prueba original '||' y '|| =' para el valor lógico, no para la definición. – Palec

+0

@Palec, ¿por qué una pregunta de 4 años con 29 votos ascendentes se identifica como un duplicado de una pregunta de 1 año con 6 votos ascendentes (que a su vez se marcó como un duplicado de otra pregunta?) Creo que hay un gran valor para mantener esta pregunta, ya que el título es más genérico (no hace referencia a la respuesta, es decir, isset()). –

Respuesta

154

PHP 5.3 tiene un operador de taquigrafía ?::

$foo = $bar ?: $baz; 

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

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

Pero PHP no tiene un operador de asignación para este compuesto (es decir, hay un equivalente de Perl de ||=).

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

+2

+1 Por introducirme a otra gran característica de 5.3 me estoy perdiendo en mis servidores RHEL5/PHP5.1.2. –

+0

Supongo que te refieres a 'The first returns' en lugar de' The second' en tu penúltima oración. – Toto

+12

Tenga en cuenta que si su variable no está definida, PHP lanzará avisos al respecto. Desafortunadamente, esto no reemplaza a '$ var = isset ($ var)? $ var: 'valor predeterminado'; 'Dice eso en la respuesta ... simplemente lo señala de nuevo para cualquiera que lo roce. :-D – Brad

7

Un idioma común para mantener la compatibilidad 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 los valores que se pueden evaluar en el contexto booleano. La ventaja aquí es que también le proporciona dicha depuración e_notice si la variable no está definida.

+0

¿No se emite un aviso con '$ bool? $ bool: "default" 'si' $ bool' no está definido? – BoltClock

+0

Claro, eso es lo mismo. Supuse que OP se está refiriendo a 'isset ($ var)? $ var: DEFAULT'. Pero parece que quiere evitarlos de todos modos. – mario

7

Gracias por todas las buenas respuestas!

Para cualquier otra persona que venga aquí por una posible alternativa, aquí hay algunas funciones que ayudan a quitarle el tedio a 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.

50

En PHP 7 finalmente tenemos una manera de hacer esto elegantemente. Se llama Null coalescing operator. Se puede utilizar de esta manera:

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

Esto es equivalente a

$name = isset($_GET['name']) ? $_GET['name']:'john doe'; 
+7

Para llegar a utilizar el nombre más geek, sonido fresco para un operador, nunca. –

+5

Argumentaría que el [operador de nave espacial] (http://php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op) también tiene mérito. – Mariano

1

En PHP antes de 7. *, se puede utilizar:? Durante indefinidos errores variables haber suprimido localmente con un @:

$foo = @$bar ?: $baz; 
Cuestiones relacionadas