2009-03-11 13 views
5

Jak niektórzy ludzie wiedzą, C# ma bardzo przydatny operator ??, który ocenia i zwraca wyrażenie po prawej stronie, jeśli wyrażenie po lewej stronie ma wartość null. Jest to bardzo przydatne dla domyślnych wartości, na przykład:PHP i ?? operator

int spaces = readSetting("spaces") ?? 5; 

Jeśli readSetting nie mógł znaleźć "spaces" i zwraca null, zmienna spaces będzie posiadać wartość domyślną 5.

Można zrobić prawie to samo w JavaScript i Ruby z || operatora, jak w

var spaces = readSetting("spaces") || 5; 

chociaż nie można mieć 0 jako wartości spaces w JavaScript w tej sprawie oraz false zarówno w Ruby i JavaScript .

PHP ma or operatora i mimo to nie działa jak || w tym sensie, że nie zwraca wyrażenie z prawej strony, to nadal może być użyteczne tutaj:

$spaces = readSetting('spaces') or $spaces = 5; 

z Zauważ, że "" i "0" są również traktowane jak false w PHP, oprócz false, 0 i null w większości języków.

Pytanie brzmi, czy powinienem użyć konstrukcji z góry? Czy ma efekty uboczne oprócz traktowania dużej klasy postaci jako fałszywej? I czy istnieje lepsza konstrukcja, która jest zazwyczaj używana i zalecana przez społeczność PHP w tym zadaniu?

Odpowiedz

1

Jeśli chcesz, aby zagwarantować, że masz fałszywe lub null, a nie traktować takie rzeczy jak „0” jako „fałszywe”, można wykonać następujące czynności:

$spaces = readSetting('spaces'); 
if($spaces == null || $spaces === false) $spaces = 5; 

Operator w PHP === wyszukuje identyczne dopasowanie, więc "0", "", nie utożsamia się z fałszem. Oczywiście możesz chcieć zmienić kod zgodnie z własnymi upodobaniami, ale masz pomysł.

6

Dobrze jest być bardziej otwartym w takich przypadkach, zwłaszcza w PHP, ponieważ ma ono nieco mylące reguły konwersji typu (np. "0" jest fałszywe, jak zauważyłeś).

Jeśli chcesz zachować ścisłość, funkcja readSettings zwróci prawidłowe ustawienie lub dobrze zdefiniowaną wartość, jeśli nie zostanie znalezione żadne ustawienie, np. null. Następnie należy go używać jako:

$spaces = readSettings('spaces'); 
if (null === $spaces) { 
    $spaces = 5; 
} 

Jeśli chcesz być bardziej obfite i chcą tylko $ przestrzenie, które mają być niepusty, zastosowanie:

$spaces = readSettings('spaces'); 
if (empty($spaces)) { // or: if (!$spaces) { 
    $spaces = 5; 
} 

Można skrócić go za koszt drugie wywołanie funkcji lub brzydkie konstrukcje (nie zalecane):

$spaces = readSettings('space') ? readSettings('space') : 5; 
$spaces = ($x = readSettings('space')) ? $x : 5; // UGLY! 

Ale uważaj, jeśli chcesz 0 być prawidłową wartością $spaces!

Z Zen of Python:

Explicit jest lepszy niż niejawny.

W twoim przypadku polecam tylko dodać drugi paramter $default do readSettings():

function readSettings($key, $default=null) { 
    return isset($settings[$key]) ? $settings[$key] : $default; 
} 

$spaces = readSettings('spaces', 5); 
4

Jak na ten temat?

$spaces = ($tmp=readSettings('space')) ? $tmp : 5; 

Albo, bardziej skomplikowane, ale przy użyciu tylko jednej zmiennej:

$spaces = ($spaces=readSettings('space')) ? $spaces : 5; 
6

PHP 5.3.0 daje krótszą wersję potrójnego warunku operatora prawda: false, która wygląda następująco:

$spaces = readSettings('spaces') ?: 5;

Proszę zauważyć, że PHP 5.3.0 jest wciąż w wersji beta i nie jest jeszcze gotowy do produkcji (jest już kandydatem do wydania), ale daje też wiele nowych, świetnych rzeczy, takich jak funkcje lambda i przestrzenie nazw, więc zdecydowanie warto sprawdzić funkcje!

Oto artykuł, który opisuje nowe funkcje całkiem dobrze:

http://www.sitepoint.com/article/whats-new-php-5-3/

+0

Nie widzę żadnego odniesienia do: w połączonej artykułu. –

1

PHP 7 obsługuje teraz ?? jako operator zerowa koalescencyjnego

zerowa operatora koalescencyjny (??) został dodany cukier składniowej dla wspólnego przypadku konieczności użycia trójskładnikowy w połączeniu z isset(). Zwraca pierwszy operand, jeśli istnieje i nie ma wartości NULL; w przeciwnym razie zwraca drugi operand.

<?php 
// 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'; 
?> 

http://php.net/manual/en/migration70.new-features.php