Wiele języków programowania ma funkcję koalescencji (zwraca pierwszą wartość inną niż NULL, przykład ). Niestety w 2009 roku PHP nie.
Jaki byłby dobry sposób na zaimplementowanie go w PHP, dopóki sam PHP nie otrzyma funkcji łączenia?
Wiele języków programowania ma funkcję koalescencji (zwraca pierwszą wartość inną niż NULL, przykład ). Niestety w 2009 roku PHP nie.
Jaki byłby dobry sposób na zaimplementowanie go w PHP, dopóki sam PHP nie otrzyma funkcji łączenia?
Odpowiedzi:
W php 5.3 jest nowy operator, który robi to: ?:
// A
echo 'A' ?: 'B';
// B
echo '' ?: 'B';
// B
echo false ?: 'B';
// B
echo null ?: 'B';
$input['properties']['range_low'] ?: '?'
array() ?: null ?: false
zwraca false
. Operator jest rzeczywiście rozsądny.
PHP 7 wprowadził prawdziwy operator koalescencji :
echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'
Jeśli wartość przed wartością ??
nie istnieje lub jest null
wartością po ??
wykonaniu.
Ulepszenie w stosunku do wspomnianego ?:
operatora polega na tym, że ??
obsługuje on również niezdefiniowane zmienne bez rzucania E_NOTICE
.
($_GET['doesNotExist'] ?? null) ?: 'fallback'
?:
Over jest ??
jednak to, że łączy również puste wartości, co ??
nie działa. Podobnie do zachowania operatora logicznego OR w JavaScript (tj. $val || 'default'
), Uważałbym ?:
za bardziej praktyczną formę łączenia, jeśli w naszej praktyce ostatecznie radzimy sobie z pustymi i zerowymi wartościami w ten sam sposób (tj $val ?: 'default'
.). A jeśli chcesz pogłębić problem i przełknąć E_NOTICE
, możesz nawet spierać się o to:echo @$val ?: 'default';
Pierwsze trafienie w wyszukiwarkę „php coalesce” w Google.
function coalesce() {
$args = func_get_args();
foreach ($args as $arg) {
if (!empty($arg)) {
return $arg;
}
}
return NULL;
}
Bardzo podoba mi się operator?:. Niestety nie został jeszcze wdrożony na moim środowisku produkcyjnym. Więc używam odpowiednika tego:
function coalesce() {
return array_shift(array_filter(func_get_args()));
}
coalesce
ma zwrócić pierwszy napotkany argument o wartości innej niż NULL , który powinien zawierać FALSE
. Ta funkcja FALSE
jednak odrzuci , prawdopodobnie nie to, co op ma na myśli (przynajmniej nie to, czego chciałbym od coalesce
funkcji).
Warto zauważyć, że ze względu na sposób traktowania przez PHP niezinicjalizowanych zmiennych i indeksów tablicowych, wszelkiego rodzaju funkcje koalescencji mają ograniczone zastosowanie. Bardzo chciałbym móc to zrobić:
$id = coalesce($_GET['id'], $_SESSION['id'], null);
Ale w większości przypadków spowoduje to błąd PHP z E_NOTICE. Jedynym bezpiecznym sposobem sprawdzenia istnienia zmiennej przed jej użyciem jest użycie jej bezpośrednio w empty () lub isset (). Operator trójskładnikowy sugerowany przez Kevina jest najlepszą opcją, jeśli wiesz, że wszystkie opcje w Twojej koalescencji są inicjowane.
$getstuff = $_GET+$_SESSION+array('id'=>null);$id=$getstuff['id'];
).
??
aby uczynić tę bardzo powszechną operację bardziej zwięzłą.
Upewnij się, że dokładnie zidentyfikowałeś, jak chcesz, aby ta funkcja działała z określonymi typami. PHP ma szeroką gamę funkcji sprawdzania typu lub podobnych, więc upewnij się, że wiesz, jak one działają. To jest przykładowe porównanie is_null () i empty ()
$testData = array(
'FALSE' => FALSE
,'0' => 0
,'"0"' => "0"
,'NULL' => NULL
,'array()'=> array()
,'new stdClass()' => new stdClass()
,'$undef' => $undef
);
foreach ( $testData as $key => $var )
{
echo "$key " . (( empty( $var ) ) ? 'is' : 'is not') . " empty<br>";
echo "$key " . (( is_null( $var ) ) ? 'is' : 'is not') . " null<br>";
echo '<hr>';
}
Jak widać, empty () zwraca prawdę dla wszystkich z nich, ale is_null () robi to tylko dla dwóch z nich.
Rozwijam odpowiedź zamieszczoną przez Ethana Kenta . Ta odpowiedź spowoduje odrzucenie niezerowych argumentów, których wynikiem jest fałsz ze względu na wewnętrzne działanie array_filter , co nie jest tym, co coalesce
zwykle robi funkcja. Na przykład:
echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';
Ups
Aby temu zaradzić, wymagany jest drugi argument i definicja funkcji. Funkcja wywoływalna jest odpowiedzialna za array_filter
określenie, czy dodać bieżącą wartość tablicy do tablicy wyników:
// "callable"
function not_null($i){
return !is_null($i); // strictly non-null, 'isset' possibly not as much
}
function coalesce(){
// pass callable to array_filter
return array_shift(array_filter(func_get_args(), 'not_null'));
}
Byłoby miło, gdybyś mógł po prostu przekazać isset
lub 'isset'
jako drugi argument array_filter
, ale nie ma takiego szczęścia.
PHP 5.3+, z zamknięciami:
function coalesce()
{
return array_shift(array_filter(func_get_args(), function ($value) {
return !is_null($value);
}));
}
Demo: https://eval.in/187365
??
dla PHP 7.