次のコードが与えられます:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
is_valid($string)
が返される場合false
、phpインタープリターはまだ後の条件をチェックしup_to_length($string)
ますか?
もしそうなら、それがする必要がないのになぜそれは余分な仕事をするのですか?
次のコードが与えられます:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
is_valid($string)
が返される場合false
、phpインタープリターはまだ後の条件をチェックしup_to_length($string)
ますか?
もしそうなら、それがする必要がないのになぜそれは余分な仕事をするのですか?
はい、PHPインタープリターは「レイジー」です。つまり、条件を評価するために可能な限り最小限の数の比較を実行します。
それを確認したい場合は、これを試してください:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
はい、そうです。これは、短絡評価に依存するちょっとしたトリックです。場合によっては、3値として記述したい小さなifステートメントがある場合があります。例:
if ($confirmed) {
$answer = 'Yes';
} else {
$answer = 'No';
}
次のように書き直すことができます:
$answer = $confirmed ? 'Yes' : 'No';
しかし、yesブロックでも何らかの関数を実行する必要がある場合はどうなるでしょうか。
if ($confirmed) {
do_something();
$answer = 'Yes';
} else {
$answer = 'No';
}
まあ、短絡評価のために、三元として書き直すことはまだ可能です:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
この場合、式(do_something()|| true)は、3値の全体的な結果を変更することはありませんがtrue
、の戻り値を無視して、3値条件が維持されることを保証しますdo_something()
。
ビット演算子&
はとです|
。それらは常に両方のオペランドを評価します。
論理演算子はAND
、、、、、およびOR
です。&&
||
AND
およびOR
よりも優先順位が低く&&
なり||
ます。以下の例を参照してください。
PHPマニュアルから:
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;
この例では、e
はtrue
、にf
なりますfalse
。
&&
私の現在の調査によると、PHPにはJavaScriptと同じ短絡演算子がないようです。
私はこのテストを実行しました:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
PHP 7.0.8は1
、ではなく、を返しCabbage
ました。
いいえ、最初の条件が満たされない場合、他の条件はチェックされなくなります。
私は独自の短絡評価ロジックを作成しました。残念ながら、これはjavascriptsのクイック構文のようなものではありませんが、おそらくこれは便利なソリューションです。
$short_circuit_isset = function($var, $default_value = NULL) {
return (isset($var)) ? : $default_value;
};
$return_title = $short_circuit_isset( $_GET['returntitle'], 'God');
// Should return type 'String' value 'God', if get param is not set
次のロジックをどこから取得したか思い出せませんが、次のことを行うと、
(isset($var)) ? : $default_value;
疑問符の後に、真の条件変数を再度書き込む必要をスキップできます。例:
(isset($super_long_var_name)) ? $super_long_var_name : $default_value;
非常に重要な観察として、このように三項演算子を使用すると、変数が1つだけではないため、比較が行われると、その比較の値が渡されることに気付くでしょう。例えば:
$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
私の選択:PHPでの短絡評価を信頼しないでください...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
条件1の2番目の部分|| saySomething()は無関係です。これは、常にtrueを返すためです。残念ながら、saySomething()は評価され、実行されます。
短絡式の正確な論理を誤解しているかもしれませんが、これは「可能な限り最小限の比較を行う」ようには見えません。
さらに、パフォーマンスの問題だけでなく、比較の中で割り当てを行ったり、単に比較する以外に違いを生む何かをしたりすると、異なる結果になる可能性があります。
とにかく...注意してください。
補足:遅延チェックを回避して条件のすべての部分を実行する場合は、次のように論理積を使用する必要があります。
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
これは、たとえば、最初の関数がfalseを返した場合でも、2つの関数を呼び出す必要がある場合に役立ちます。