web-dev-qa-db-ja.com

PHPのC#のnull結合演算子(??)

PHPにC#の??のように機能する三項演算子などはありますか?

C#の??は簡潔で短いですが、PHPでは、次のようにする必要があります。

// This is absolutely okay except that $_REQUEST['test'] is kind of redundant.
echo isset($_REQUEST['test'])? $_REQUEST['test'] : 'hi';

// This is perfect! Shorter and cleaner, but only in this situation.
echo null? : 'replacement if empty';

// This line gives error when $_REQUEST['test'] is NOT set.
echo $_REQUEST['test']?: 'hi';
50
dpp

PHP 7は null合体演算子 を追加します:

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

また、phpの3項演算子 ?: (php> = 5.3のみ)を書く簡単な方法も見ることができます。

// Example usage for: Short Ternary Operator
$action = $_POST['action'] ?: 'default';

// The above is identical to
$action = $_POST['action'] ? $_POST['action'] : 'default';

また、C#との比較は公平ではありません。 "PHPあなたは次のようなことをする必要があります"-C#では、存在しない配列/辞書項目にアクセスしようとすると、実行時エラーも発生します。

60
zerkms

Null Coalesce Operator 、(??)が PHP 7 で受け入れられ、実装されました。 short ternary operator?:)とは異なり、??は、配列にアクセスしようとしたときに発生するE_NOTICEを抑制します。キーがあります。 RFCの最初の例は次のとおりです。

$username = $_GET['user'] ?? 'nobody';
// equivalent to: $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

??演算子は、E_NOTICEを防ぐためにissetを手動で適用する必要がないことに注意してください。

50
kojiro

関数を使用します。明らかにそれはオペレーターではありませんが、あなたのアプローチよりもきれいに見えます:

function isset_or(&$check, $alternate = NULL)
{
    return (isset($check)) ? $check : $alternate;
}

使用法:

isset_or($_REQUEST['test'],'hi');
9
LukLed

PHP 7より前のバージョンではありません。issetを使用する必要がある場合、使用するパターンはisset($var) ? $var : nullです。次を含む?:演算子はありませんissetの特性。

6
deceze

??はC#ではバイナリであり、3進数ではありません。そして、PHP 7.の前のPHP.

4
Dani

PHP 5.6現在、同じ演算子は存在しませんが、同様に動作する関数を作成できます。

_/**
 * Returns the first entry that passes an isset() test.
 *
 * Each entry can either be a single value: $value, or an array-key pair:
 * $array, $key.  If all entries fail isset(), or no entries are passed,
 * then first() will return null.
 *
 * $array must be an array that passes isset() on its own, or it will be
 * treated as a standalone $value.  $key must be a valid array key, or
 * both $array and $key will be treated as standalone $value entries. To
 * be considered a valid key, $key must pass:
 *
 *     is_null($key) || is_string($key) || is_int($key) || is_float($key)
 *         || is_bool($key)
 *
 * If $value is an array, it must be the last entry, the following entry
 * must be a valid array-key pair, or the following entry's $value must
 * not be a valid $key.  Otherwise, $value and the immediately following
 * $value will be treated as an array-key pair's $array and $key,
 * respectfully.  See above for $key validity tests.
 */
function first(/* [(array $array, $key) | $value]... */)
{
    $count = func_num_args();

    for ($i = 0; $i < $count - 1; $i++)
    {
        $arg = func_get_arg($i);

        if (!isset($arg))
        {
            continue;
        }

        if (is_array($arg))
        {
            $key = func_get_arg($i + 1);

            if (is_null($key) || is_string($key) || is_int($key) || is_float($key) || is_bool($key))
            {
                if (isset($arg[$key]))
                {
                    return $arg[$key];
                }

                $i++;
                continue;
            }
        }

        return $arg;
    }

    if ($i < $count)
    {
        return func_get_arg($i);
    }

    return null;
}
_

使用法:

_$option = first($option_override, $_REQUEST, 'option', $_SESSION, 'option', false);
_

これは、isset()を満たす変数が見つかるまで各変数を試行します。

  1. _$option_override_
  2. _$_REQUEST['option']_
  3. _$_SESSION['option']_
  4. false

4がなかった場合、デフォルトはnullになります。

注:参照を使用するより簡単な実装がありますが、これには テストされた項目がまだ存在しない場合はnullに設定する の副作用があります。これは 問題になる可能性があります 配列のサイズまたは真実性が重要な場合。

1
Zenexer