Функция объединения для PHP?


Многие языки программирования имеют функцию объединения (возвращает первое ненулевое значение, пример). PHP, к сожалению, в 2009 году этого не делает.

Какой был бы хороший способ реализовать его в PHP, пока сам PHP не получит функцию объединения?

Author: hakre, 2009-06-18

9 answers

В 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

 176
Author: Kevin, 2009-12-12 01:32:16

PHP 7 представил реальный оператор объединения:

echo $_GET['doesNotExist'] ?? 'fallback'; // prints 'fallback'

Если значение перед ?? не существует или равно null, то принимается значение после ??.

Улучшение по сравнению с упомянутым оператором ?: заключается в том, что ?? также обрабатывает неопределенные переменные, не вызывая E_NOTICE.

 57
Author: flori, 2015-11-28 20:15:39

Первый хит для "php объединяется" в Google.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
      return $arg;
    }
  }
  return NULL;
}

Http://drupial.com/content/php-coalesce

 28
Author: Will Shaver, 2009-06-18 15:51:34

Мне действительно нравится оператор ?:. К сожалению, это еще не реализовано в моей производственной среде. Поэтому я использую эквивалент этого:

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}
 17
Author: Ethan Kent, 2011-01-14 04:58:25

Стоит отметить, что из-за обработки PHP неинициализированных переменных и индексов массива любой вид функции объединения имеет ограниченное применение. Я бы хотел иметь возможность сделать это:

$id = coalesce($_GET['id'], $_SESSION['id'], null);

Но в большинстве случаев это приведет к ошибке PHP с E_NOTICE. Единственный безопасный способ проверить существование переменной перед ее использованием - использовать ее непосредственно в empty() или isset(). Троичный оператор, предложенный Кевином, является лучшим вариантом, если вы знаете, что все варианты в вашем известно, что слияния инициализируются.

 9
Author: Andrew, 2013-04-09 15:14:16

Убедитесь, что вы точно определили, как вы хотите, чтобы эта функция работала с определенными типами. 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 из них.

 6
Author: Peter Bailey, 2009-06-18 16:43:18

Я расширяю ответ, опубликованный Итаном Кентом. Этот ответ отбросит ненулевые аргументы, которые оцениваются как ложные из-за внутренней работы 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' в качестве 2-го аргумента array_filter, но не повезло.

 1
Author: Madbreaks, 2018-04-22 11:23:09

В настоящее время я использую это, но мне интересно, нельзя ли улучшить его с помощью некоторых новых функций в PHP 5.

function coalesce() {
  $args = func_get_args();
  foreach ($args as $arg) {
    if (!empty($arg)) {
    return $arg;
    }
  }
  return $args[0];
}
 0
Author: mikl, 2009-06-18 15:54:44

PHP 5.3+, с закрытиями:

function coalesce()
{
    return array_shift(array_filter(func_get_args(), function ($value) {
        return !is_null($value);
    }));
}

Демонстрация: https://eval.in/187365

 0
Author: Paulo Freitas, 2014-09-02 20:21:54