Многие языки программирования имеют функцию коалесценции (возвращает первое значение, отличное от NULL, пример). PHP, к сожалению, не делает.
Что было бы хорошим способом реализовать его в PHP?
Многие языки программирования имеют функцию коалесценции (возвращает первое значение, отличное от NULL, пример). PHP, к сожалению, не делает.
Что было бы хорошим способом реализовать его в PHP?
В php 5.3 появился новый оператор, который делает это: ?:
// A
echo 'A' ?: 'B';
// B
echo '' ?: 'B';
// B
echo false ?: 'B';
// B
echo null ?: 'B';
Источник: http://www.php.net/ChangeLog-5.php#5.3.0
PHP 7 представил реальный оператор коалесценции:
echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'
Если значение перед ??
не существует или равно null
, значение после ??
берется.
Улучшение по сравнению с упомянутым оператором ?:
состоит в том, что ??
также обрабатывает переменные undefined, не бросая E_NOTICE
.
Первый хит для "php coalesce" в google.
function coalesce() {
$args = func_get_args();
foreach ($args as $arg) {
if (!empty($arg)) {
return $arg;
}
}
return NULL;
}
Мне очень нравится оператор?:. К сожалению, он еще не реализован в моей производственной среде. Поэтому я использую эквивалент этого:
function coalesce() {
return array_shift(array_filter(func_get_args()));
}
Следует отметить, что из-за обработки PHP неинициализированных переменных и индексов массивов любая функция коалесценции имеет ограниченное применение. Я бы с удовольствием мог это сделать:
$id = coalesce($_GET['id'], $_SESSION['id'], null);
Но это в большинстве случаев вызывает ошибку PHP с E_NOTICE. Единственный безопасный способ проверить существование переменной перед ее использованием - использовать ее непосредственно в empty() или isset(). Тернарный оператор, предложенный Кевином, является лучшим вариантом, если вы знаете, что все варианты в вашем объединении, как известно, инициализируются.
Убедитесь, что вы точно определяете, как вы хотите, чтобы эта функция работала с определенными типами. PHP имеет множество функций проверки типов или подобных функций, поэтому убедитесь, что вы знаете, как они работают. Это пример сравнения is_null() и 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>';
}
Как вы можете видеть, empty() возвращает true для всех из них, но is_null() делает это только для 2 из них.
Я расширяю ответ, отвеченный Этаном Кентом. Этот ответ будет отбрасывать ненулевые аргументы, которые вычисляются как ложные из-за внутренней работы array_filter, что не является функцией coalesce
как правило, делает. Например:
echo 42 == coalesce(null, 0, 42) ? 'Oops' : 'Hooray';
К сожалению
Чтобы преодолеть это, требуется второй аргумент и определение функции. Вызываемая функция отвечает за сообщение array_filter
, следует ли добавлять текущее значение массива к массиву результатов:
// "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'));
}
Было бы неплохо, если бы вы могли просто передать isset
или 'isset'
в качестве второго аргумента в array_filter
, но не удачи.
Приветствия
В настоящее время я использую это, но мне интересно, не удалось ли его улучшить с помощью некоторых новых функций на PHP 5.
function coalesce() {
$args = func_get_args();
foreach ($args as $arg) {
if (!empty($arg)) {
return $arg;
}
}
return $args[0];
}
PHP 5.3+ с закрытием:
function coalesce()
{
return array_shift(array_filter(func_get_args(), function ($value) {
return !is_null($value);
}));
}
Демо: https://eval.in/187365