web-dev-qa-db-fra.com

Existe-t-il une meilleure méthode PHP pour obtenir la valeur par défaut par clé à partir d'un tableau (dictionnaire)?

En Python on peut faire:

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

Dans PHP on peut opter pour un opérateur trinaire comme dans:

$foo = array();
assert( (isset($foo['bar'])) ? $foo['bar'] : 'baz' == 'baz');

Je recherche une version golf. Puis-je le faire plus court/meilleur en PHP?

44
Yauhen Yakimovich

Je viens de proposer cette petite fonction d'aide:

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

Non seulement cela fonctionne pour les dictionnaires, mais pour toutes sortes de 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

Passer une variable non définie par référence ne provoque pas d'erreur NOTICE. Au lieu de cela, passer $var Par référence le définira et le définira sur null. La valeur par défaut sera également renvoyée si la variable transmise est null . Notez également le tableau généré implicitement dans l'exemple de spam/oeufs:

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

Notez que même si $var Est passé par référence, le résultat de get($var) sera une copie de $var, Pas une référence. J'espère que ça aide!

44
stepmuel

Le temps passe et PHP évolue. PHP 7 prend désormais en charge opérateur de coalescence nul , ??:

// 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';
45
Ivan Yarych

tilisez l'opérateur de contrôle d'erreur @ avec le PHP 5.3 version raccourcie de l'opérateur ternaire:

$bar = @$foo['bar'] ?: 'defaultvalue';
19
romanlv

Je trouve utile de créer une fonction comme ceci:

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

Et utilisez-le comme ceci:

$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 }";

La valeur par défaut dans ce cas est null, mais vous pouvez la définir selon vos besoins.

J'espère que cela est utile.

7
rbento

PHP 5.3 a une version raccourcie de l'opérateur ternaire:

$x = $foo ?: 'defaultvaluehere';

qui est essentiellement

if (isset($foo)) {
   $x = $foo;
else {
   $x = 'defaultvaluehere';
}

Sinon, non, il n'y a pas de méthode plus courte.

6
Marc B

Une façon "légèrement" hacky de le faire:

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

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

Évidemment, ce n'est pas vraiment la bonne façon de le faire. Mais c'est pratique dans d'autres situations. Par exemple. Je déclare souvent des raccourcis vers GET et POST variables comme ça:

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

PS: On pourrait appeler cela "l'opérateur de comparaison spécial ==$_=& Intégré":

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

PPS: Eh bien, vous pouvez évidemment utiliser simplement

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

mais c'est encore pire que l'opérateur ==$_=&. Les gens n'aiment pas beaucoup l'opérateur de suppression d'erreur, vous savez.

5
NikiC

Si vous énumérez les valeurs par défaut par clé dans un tableau, cela peut être fait de cette façon:

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

$foo = array_merge($defaults, $foo);

print_r($foo);

Ce qui se traduit par:

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

Plus il y a de paires clé/valeur pour lesquelles vous énumérez les valeurs par défaut, meilleur est le code-golf.

2
Rusty Fausak

Il y avait ne solution proposée par "Marc B" pour utiliser le raccourci ternaire $x = $foo ?: 'defaultvaluehere'; mais il donne toujours des avis. C'est probablement une faute de frappe, peut-être qu'il voulait dire ?? ou il a été écrit avant PHP version 7. Selon description ternaire :

Depuis PHP 5.3, il est possible de laisser de côté la partie médiane de l'opérateur ternaire. Expression expr1 ?: expr3 Retour expr1 si expr1 correspond à TRUE et expr3 autrement.

Mais il n'utilise pas isset à l'intérieur et produit des notifications. Pour éviter les notifications, mieux utiliser Null Coalescing Operator?? qui utilise isset à l'intérieur. Disponible en PHP 7.

L'expression (expr1) ?? (expr2) évalue à expr2 si expr1 est NULL, et expr1 sinon. En particulier, cet opérateur n'émet pas d'avis si la valeur de gauche n'existe pas, tout comme isset (). Ceci est particulièrement utile sur les clés de tableau.

Exemple # 5 Assigner une valeur par défaut

<?php
// Example usage for: Null Coalesce Operator
$action = $_POST['action'] ?? 'default';

// The above is identical to this if/else statement
if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else {
    $action = 'default';
}

?>
0