PHPの結合関数?


131

多くのプログラミング言語には、合体関数があります(最初の非NULL値を返す、)。PHPは、残念ながら2009年には機能しません。

PHP自体が合体関数を取得するまで、PHPに実装する良い方法は何でしょうか?


11
関連:PHP 7 の新しいnull合体演算子 ??
kojiro

ヌル合体演算子の詳細については、ここで見つけることができます- stackoverflow.com/questions/33666256/...
ピーター

1
注意してください、PHP7はこの機能を実装しました
Grzegorz

@Grzegorz:演算子は関数ではありません。または、その関数はPHP 7で新しくどこにありましたか;)
hakre

機能によって私は機能を意味しませんでした;)特徴。正確ではなかった。ありがとうございました:)
Grzegorz 2018

回答:


194

これを行う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


25
「echo $ a?:$ b?:$ c?:$ d;」のような複数の3値ショートカットについてはどうでしょうか。作業?
ChrisR

5
配列に対して期待どおりに機能しません。たとえば、未定義の配列要素がfalseかどうかを確認しようとすると、エラーが発生します。 $input['properties']['range_low'] ?: '?'
Keyo

5
合体演算子を使用するかどうかに関係なく、未定義のインデックス通知を取得する必要があります。
ケビン

2
複数の誤った引数は最後の引数をarray() ?: null ?: false返し、を返しますfalse。オペレーターは正気です。
Brad Koch

6
これは、他の言語の合体のようにnull以外を受け入れるだけでなく、暗黙的にブール値に変換される任意の値を受け入れることに注意してください。したがって、型キャストルール
DanMan

65

PHP 7は実際の合体演算子を導入しました:

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

の前の値??が存在しない場合、またはが取得されたnull後の値である場合??

上記の?:演算子に対する改善点は、は??をスローせずに未定義の変数も処理することE_NOTICEです。


最後に、場所全体でisset()とempty()はもうありません!
George Kagan

7
まだ必要な@timeNomadは空で、nullのみをチェックします
Nabeel Khan

:安全な「falsy-合体」を取得する唯一の方法は、両方のビットを使用することである($_GET['doesNotExist'] ?? null) ?: 'fallback'
ネイサンBaulch

ただし、?:over の利点は??、空の値も結合して、結合??しないことです。JavaScriptの論理OR演算子の動作(つまり$val || 'default')と同様に、私たちの実践で最終的にnullの両方を同じ方法で処理する(つまり)場合、私?:はより実用的な合体形式であることがわかります。そして、あなたはさらにとツバメ問題を強制したい場合は、あなたもこれを主張することができます:$val ?: 'default'E_NOTICEecho @$val ?: 'default';
マット・ボルハ

29

グーグルで「php合体」の最初のヒット。

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

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


9
少しのRAMを保存し、配列にargsを複製しないでください。foreach(func_get_args()as $ arg)を実行してください{}
TravisO

17
@ [Alfred、Ciaran]-あなたは間違っています。foreach()は最初の引数を1回だけ評価して配列を取得し、それを繰り返します。
gahooa 2009

6
func_get_args()をforeach(ここでは$ arg)内に置いても、パフォーマンスの観点からは何も変わりません。
サベージマン09/12/12

7
@Savageman ...正確に...このミリ秒のパフォーマンスまたは数バイトのメモリをアプリケーションから絞り出すことを考えている場合は、おそらく間違ったパフォーマンス/メモリのボトルネックを見ているでしょう
ChrisR

4
皮肉なことに、これは今やGoogleでの「php合体」の最初のヒットです。
シェーバー

18

?:演算子が本当に好きです。残念ながら、まだ本番環境には実装されていません。だから私はこれと同等のものを使います:

function coalesce() {
  return array_shift(array_filter(func_get_args()));
}

1
これは「真の」合体であり、array_filterを使用して、渡されたn個の引数でfalse(nullを含む)と評価されるものをすべて削除します。私の推測では、配列の最初の要素の代わりにシフトを使用しています分からない。参照:php.net/manual/en/…–
Adam Tolley、

3
私はそれが好きですが、@ hakreに同意する必要があります- coalesceは、最初に遭遇したnull以外の引数を返すことになっていますFALSE。この関数は破棄しFALSEますが、おそらくopの意図は破棄されません(少なくとも、coalesce関数に必要なものはそうではありません)。
Madbreaks 2013

1
変数のみを参照渡しする必要があります
Ben Sinclair、

9

PHPが初期化されていない変数と配列インデックスを処理するため、あらゆる種類の合体関数の使用は制限されています。私はこれができるようになりたいです:

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

しかし、これにより、ほとんどの場合、PHPはE_NOTICEでエラーになります。変数を使用する前にその存在をテストする唯一の安全な方法は、empty()またはisset()で直接使用することです。合体のすべてのオプションが初期化されていることがわかっている場合は、Kevinによって提案された3項演算子が最適なオプションです。


この場合、配列共用体はかなりうまく機能します($getstuff = $_GET+$_SESSION+array('id'=>null);$id=$getstuff['id'];)。
ブリリアント

@クイルそれはどういう意味ですか?提案された解決策を参照しましたか?
Ben Sinclair

PHP 7では、この非常に一般的な操作をより簡潔にするために、素敵な新しいisset三項演算子??が導入されています。
botimer 2015

6

この関数が特定のタイプでどのように機能するかを正確に識別してください。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つに対してのみtrueを返します。


2

Ethan Kentが投稿した答えを詳しく説明します。その答えは、array_filterの内部動作のためにfalseと評価されるnull以外の引数を破棄しますが、これはcoalesce関数が通常行うことではありません。例えば:

echo 42 === coalesce(null, 0, 42) ? 'Oops' : 'Hooray';

おっとっと

これを克服するには、2番目の引数と関数定義が必要です。呼び出し可能な関数が伝える責任がある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'));
}

単ににを2番目の引数として渡すisset'isset'、そのarray_filterような運がない場合は、すばらしいでしょう。


0

私は現在これを使用していますが、PHP 5のいくつかの新機能で改善できなかったのでしょうか。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.