PHP=の "="/"&="演算子はどういう意味ですか?それらに関する情報はどこで読むことができますか?
Googleを検索しても役に立ちません。
$a &= $b
は$a = $a & $b
の短縮形であり、これは bitwise-and 演算子です。
$a =& $b
は、$ aを reference として$ bに割り当てます。
_$a =& $b
_は_$a
_を_$b
_のエイリアスに変換します。 _$a
_の値または参照が変更されると、それに応じて_$b
_の値または参照も変更されます。
これは、オブジェクトに関しては「両方が同じ場所を指す」とは異なります。_$c = $d = new AnObject(
_)を実行でき、両方の変数が同じ場所を指します。ただし、あるポイントを変更しても、他のポイントは変更されません。つまり、_$c = null
_は_$d = null
_にはなりません。ただし、_$a =& $b
_の場合、_$a = null
_は_$b = null
_になります。
注:正式には、エイリアスは実際には参照と呼ばれます。公式用語は少し誤った名称であり、確かにあいまいであるため、代わりに「エイリアス」という用語を使用することにしました。ドキュメントについては、 php.net 。を参照してください
スカラー値の場合、_=&
_は値をオブジェクトにラップするようなものであり、複数の変数間で値を普遍的に変更できます。参照(オブジェクト)によって通常渡されるタイプでは、_=&
_は参照への参照を提供します。
連想配列で作業しているときは、_=&
_を使用する傾向があります。 _$foo['bar']['foobar']
_を何度か書き換えるのではなく、_$foobar =& $foo['bar']['foobar']
_というエイリアスを作成できます。これらは、インデックスがまだ存在しない場合でも機能します。 _$foo['bar']['foobar']
_が存在しない場合、isset($foobar)
はfalseになります。エラーを引き起こさずにキーの存在をテストする前にエイリアスを作成できるため、プレーンな古い変数を使用するよりも優れています。
完了したら、エイリアスの設定を解除(unset($foobar)
)してください。そうしないと、後で変数名を再利用すると、エイリアスが指しているものはすべて上書きされてしまいます。
エイリアスは他の方法でも使用できます。割り当てに限定されません。彼らは一緒に働きます:
foreach ($a as &$b)
_$b
_に割り当てると、_$a
_の対応する値が上書きされます。完了したら_$b
_の設定を解除します。そうしないと、奇妙な問題が発生します。function foobar(&$a)
foobar
内の_$a
_への割り当ては、呼び出し元が_$a
_として渡した変数を変更します。function &foobar()
返されるものはすべて、呼び出し元が変更できます。これはエイリアスを渡すのに便利です。悪用も簡単です。$a = array(&$b)
_$a[0]
_への変更は、割り当てを含め、_$b
_に影響します。call_user_func('foobar', array(&$a))
foobar
が単一のエイリアスパラメータを取ると仮定して、foobar
が_$a
_を変更できるようになりました。これにより、_call_user_func_array
_を使用して、エイリアスパラメータを持つ関数/メソッドを呼び出すことができます。_$original = 1;
$copy = $original;
$reference =& $original;
// All three variables == 1.
$reference = 2;
// $original == 2, $reference == 2, $copy == 1
$original = 3;
// $original == 3, $reference == 3, $copy == 1
$copy = 4;
// $original == 3, $reference == 3, $copy == 4
_
_#!/usr/bin/env php
<?php
class Object
{
private $properties;
public function __construct(array $properties = array())
{
$this->properties = $properties;
}
public function __isset($key)
{
return isset($this->properties[$key]);
}
public function __unset($key)
{
unset($this->properties[$key]);
}
public function __get($key)
{
return isset($this->$key) ? $this->properties[$key] : null;
}
public function __set($key, $value)
{
$this->properties[$key] = $value;
}
public function __toString()
{
return print_r($this->properties, true);
}
}
function print_vars()
{
global $original, $ref, $refref;
echo
'$original: ', $original,
'$ref: ', $ref,
'$refref: ', $refref,
PHP_EOL;
}
$original = new Object(array('a' => 1, 'b' => 2, 'c' => 3));
$ref = $original;
$refref =& $original;
print_vars();
/*
$original: Array
(
[a] => 1
[b] => 2
[c] => 3
)
$ref: Array
(
[a] => 1
[b] => 2
[c] => 3
)
$refref: Array
(
[a] => 1
[b] => 2
[c] => 3
)
*/
$original->a = 'duck';
$ref->b = 'moose';
$refref->c = 'cow';
print_vars();
/*
$original: Array
(
[a] => duck
[b] => moose
[c] => cow
)
$ref: Array
(
[a] => duck
[b] => moose
[c] => cow
)
$refref: Array
(
[a] => duck
[b] => moose
[c] => cow
)
*/
// This carries over to $refref, but not $ref.
$original = new Object(array('x' => 1, 'y' => 2, 'z' => 3));
print_vars();
/*
$original: Array
(
[x] => 1
[y] => 2
[z] => 3
)
$ref: Array
(
[a] => duck
[b] => moose
[c] => cow
)
$refref: Array
(
[x] => 1
[y] => 2
[z] => 3
)
*/
// This does *not* carry over to $original or $ref.
$ref = new Object(array('o' => 42, 'm' => 123, 'n' => 1337));
print_vars();
/*
$original: Array
(
[x] => 1
[y] => 2
[z] => 3
)
$ref: Array
(
[o] => 42
[m] => 123
[n] => 1337
)
$refref: Array
(
[x] => 1
[y] => 2
[z] => 3
)
*/
// This *does* carry over to $original, but not $ref.
$refref = new Object(array('alpha' => 10, 'beta' => 20, 'gamma' => 30));
print_vars();
/*
$original: Array
(
[alpha] => 10
[beta] => 20
[gamma] => 30
)
$ref: Array
(
[o] => 42
[m] => 123
[n] => 1337
)
$refref: Array
(
[alpha] => 10
[beta] => 20
[gamma] => 30
)
*/
?>
_
_&=
_は_=&
_とは関係ありません。これは、一連の割り当て操作から取得されます。ここにいくつかあります:
+=
_-=
_*=
_/=
_ここでトレンドを見ますか?
2項算術演算子には通常、対応する代入演算子があります。 _@
_が_$a @ $b
_と_$a
_が数値の場合、一般に_$b
_は数値を生成する算術演算子(これは執筆時点ではありません)であるとしましょう。 (考えてください:加算、乗算、除算など)このようなことをする必要がある頻度はどれくらいですか?
_$a = $a @ $b;
_
かなり頻繁に。 _$a
_を繰り返す必要はないでしょうか? PHPを含む多くの言語は、代入演算子の配列でこれを解決します。
_$a @= $b;
_
はるかに単純で、この表記に慣れているプログラマにとっては、おそらく一目でより簡潔で説明的になります。 (慣れているので、確かに読みやすくなります。)変数を2倍にするには:
_$a *= 2;
_
すばやく、簡単で、比較的わかりやすい。 PHPを含む一部の言語では、この機能を算術を超えて拡張し、追加の1〜2回の操作を行います。特に:
_$a = $a . 'Appended text';
// Is the same as:
$a .= 'Appended text';
_
非常に便利。
_&=
_は ビットごとの算術AND演算 を表すため、_&
_はこれらの代入演算子に含まれます。 PHPのドキュメント(前述のリンクを参照))には他にもいくつかリストされていますが、それらはすべて多くのプログラミング言語に共通です。
つまり、_$a &= $b
_は_$a = $a & $b
_と同じです。