PHP
Operatorzy
Szukaj…
Wprowadzenie
Operator to coś, co przyjmuje jedną lub więcej wartości (lub wyrażeń, w programowaniu żargonu) i daje inną wartość (tak, że sama konstrukcja staje się wyrażeniem).
Operatory można pogrupować według liczby pobranych wartości.
Uwagi
Operatory „działają” lub działają na jednym (operatory jednoargumentowe, takie jak !$a
i ++$a
), dwa (operatory binarne, takie jak $a + $b
lub $a >> $b
) lub trzy (jedynym operatorem potrójnym jest $a ? $b : $c
) wyrażenia.
Pierwszeństwo operatorów wpływa na sposób grupowania operatorów (tak jakby były nawiasy). Poniżej znajduje się lista operatorów w kolejności ich ważności (operatory w drugiej kolumnie). Jeśli w jednym rzędzie znajduje się wiele operatorów, grupowanie jest określone przez kolejność kodów, gdzie pierwsza kolumna wskazuje skojarzenie (patrz przykłady).
Stowarzyszenie | Operator |
---|---|
lewo | -> :: |
Żaden | clone new |
lewo | [ |
dobrze | ** |
dobrze | ++ -- ~ (int) (float) (string) (array) (object) (bool) @ |
Żaden | instanceof |
dobrze | ! |
lewo | * / % |
lewo | + - . |
lewo | << >> |
Żaden | < <= > >= |
Żaden | == != === !== <> <=> |
lewo | & |
lewo | ^ |
lewo | | |
lewo | && |
lewo | || |
dobrze | ?? |
lewo | ? : |
dobrze | = += -= *= **= /= .= %= &= ` |
lewo | and |
lewo | xor |
lewo | or |
Pełna informacja znajduje się na stronie Przepełnienie stosu .
Zauważ, że funkcje i konstrukcje językowe (np. print
) są zawsze oceniane najpierw, ale każda zwracana wartość zostanie użyta zgodnie z powyższymi regułami pierwszeństwa / asocjatywności. Szczególną ostrożność należy zachować, jeśli nawiasy po konstrukcji języka zostaną pominięte. Np. echo 2 . print 3 + 4;
echo 721
: część print
ocenia 3 + 4
, drukuje wynik 7
i zwraca 1
. Następnie 2
jest powtarzane, łączone ze zwracaną wartością print
( 1
).
Operatory łańcuchowe (. I. =)
Istnieją tylko dwa operatory łańcuchowe:
Łączenie dwóch ciągów (kropka):
$a = "a"; $b = "b"; $c = $a . $b; // $c => "ab"
Łączenie zadania (kropka =):
$a = "a"; $a .= "b"; // $a => "ab"
Podstawowe przypisanie (=)
$a = "some string";
powoduje, że $a
ma wartość some string
.
Wynikiem wyrażenia przypisania jest przypisywana wartość. Zauważ, że pojedynczy znak równości =
NIE jest do porównania!
$a = 3;
$b = ($a = 5);
wykonuje następujące czynności:
- Linia 1 przypisuje
3
do$a
. - Wiersz 2 przypisuje od
5
do$a
. To wyrażenie daje również wartość5
. - Wiersz 2 następnie przypisuje wynik wyrażenia w nawiasach (
5
) do$b
.
Zatem: zarówno $a
i $b
mają teraz wartość 5
.
Połączone przypisanie (+ = itp.)
Połączone operatory przypisania są skrótem do operacji na pewnej zmiennej, a następnie przypisują tę nową wartość do tej zmiennej.
Arytmetyka:
$a = 1; // basic assignment
$a += 2; // read as '$a = $a + 2'; $a now is (1 + 2) => 3
$a -= 1; // $a now is (3 - 1) => 2
$a *= 2; // $a now is (2 * 2) => 4
$a /= 2; // $a now is (16 / 2) => 8
$a %= 5; // $a now is (8 % 5) => 3 (modulus or remainder)
// array +
$arrOne = array(1);
$arrTwo = array(2);
$arrOne += $arrTwo;
Przetwarzanie wielu tablic razem
$a **= 2; // $a now is (4 ** 2) => 16 (4 raised to the power of 2)
Połączone łączenie i przypisywanie łańcucha:
$a = "a";
$a .= "b"; // $a => "ab"
Połączone binarne operatory przypisania bitowego:
$a = 0b00101010; // $a now is 42
$a &= 0b00001111; // $a now is (00101010 & 00001111) => 00001010 (bitwise and)
$a |= 0b00100010; // $a now is (00001010 | 00100010) => 00101010 (bitwise or)
$a ^= 0b10000010; // $a now is (00101010 ^ 10000010) => 10101000 (bitwise xor)
$a >>= 3; // $a now is (10101000 >> 3) => 00010101 (shift right by 3)
$a <<= 1; // $a now is (00010101 << 1) => 00101010 (shift left by 1)
Zmiana priorytetu operatora (w nawiasach)
Kolejność, w jakiej operatorzy są oceniani, jest ustalana na podstawie priorytetu operatorów (patrz także sekcja Uwagi).
W
$a = 2 * 3 + 4;
$a
otrzymuje wartość 10, ponieważ 2 * 3
jest obliczane jako pierwsze (mnożenie ma wyższy priorytet niż dodawanie), co daje wynik podrzędny 6 + 4
, który wynosi 10.
Pierwszeństwo można zmienić za pomocą nawiasów: w
$a = 2 * (3 + 4);
$a
otrzymuje wartość 14, ponieważ (3 + 4)
jest obliczana jako pierwsza.
Stowarzyszenie
Lewe stowarzyszenie
Jeśli pierwszeństwo dwóch operatorów jest równe, skojarzenie determinuje grupowanie (patrz także sekcja Uwagi):
$a = 5 * 3 % 2; // $a now is (5 * 3) % 2 => (15 % 2) => 1
*
i %
mają równe pierwszeństwo i lewe skojarzenie. Ponieważ mnożenie następuje najpierw (po lewej), jest zgrupowane.
$a = 5 % 3 * 2; // $a now is (5 % 3) * 2 => (2 * 2) => 4
Teraz operator modułu występuje najpierw (po lewej) i dlatego jest zgrupowany.
Właściwe stowarzyszenie
$a = 1;
$b = 1;
$a = $b += 1;
Zarówno $a
i $b
mają teraz wartość 2
ponieważ $b += 1
jest zgrupowane, a następnie wynik ( $b
wynosi 2
) jest przypisywany do $a
.
Operatory porównania
Równość
Do podstawowego testu równości wykorzystywany jest operator równości ==
. Aby uzyskać bardziej kompleksowe kontrole, użyj identycznego operatora ===
.
Identyczny operator działa tak samo jak operator równości, wymagając, aby jego operandy miały tę samą wartość, ale także wymaga, aby miały ten sam typ danych.
Na przykład poniższa próbka wyświetli „aib są równe”, ale nie „aib są identyczne”.
$a = 4;
$b = '4';
if ($a == $b) {
echo 'a and b are equal'; // this will be printed
}
if ($a === $b) {
echo 'a and b are identical'; // this won't be printed
}
Podczas korzystania z operatora równości ciągi liczbowe są rzutowane na liczby całkowite.
Porównanie obiektów
===
porównuje dwa obiekty, sprawdzając, czy są dokładnie tym samym wystąpieniem . Oznacza to, że new stdClass() === new stdClass()
przekształca się w false, nawet jeśli są one tworzone w ten sam sposób (i mają dokładnie takie same wartości).
==
porównuje dwa obiekty, rekurencyjnie sprawdzając, czy są one równe ( głębokie równe ). Oznacza to, że dla $a == $b
, jeśli $a
i $b
są:
- z tej samej klasy
- mają te same właściwości, w tym właściwości dynamiczne
- dla każdej właściwości
$property
zestaw$property
$a->property == $b->property
jest prawdziwa (stąd sprawdzana rekurencyjnie).
Inne powszechnie używane operatory
Zawierają:
- Większy niż (
>
) - Mniejsze niż (
<
) - Większy niż lub równy (
>=
) - Mniejsze niż lub równe (
<=
) - Nie równa się (
!=
) - Nie identycznie równe (
!==
)
- Większa niż :
$a > $b
, zwracatrue
jeśli wartość$a
jest większa niż$b
, w przeciwnym razie zwraca false.
Przykład :
var_dump(5 > 2); // prints bool(true)
var_dump(2 > 7); // prints bool(false)
- Mniejsze niż :
$a < $b
, zwracatrue
jeśli wartość$a
jest mniejsza niż$b
, w przeciwnym razie zwraca false.
Przykład :
var_dump(5 < 2); // prints bool(false)
var_dump(1 < 10); // prints bool(true)
- Większa niż lub równa :
$a >= $b
, zwracatrue
jeśli wartość$a
jest większa niż$b
lub równa$b
, w przeciwnym razie zwracafalse
.
Przykład :
var_dump(2 >= 2); // prints bool(true)
var_dump(6 >= 1); // prints bool(true)
var_dump(1 >= 7); // prints bool(false)
- Mniejszy niż lub równy :
$a <= $b
, zwracatrue
jeśli wartość$a
jest mniejsza niż$b
lub równa$b
, w przeciwnym razie zwracafalse
.
Przykład :
var_dump(5 <= 5); // prints bool(true)
var_dump(5 <= 8); // prints bool(true)
var_dump(9 <= 1); // prints bool(false)
5/6 Nie równe / identyczne z: Aby powtórzyć wcześniejszy przykład dotyczący równości, poniższa próbka wyświetli „aib nie są identyczne”, ale nie „aib nie są równe”.
$a = 4;
$b = '4';
if ($a != $b) {
echo 'a and b are not equal'; // this won't be printed
}
if ($a !== $b) {
echo 'a and b are not identical'; // this will be printed
}
Operator statku kosmicznego (<=>)
PHP 7 wprowadza nowy rodzaj operatora, którego można używać do porównywania wyrażeń. Ten operator zwróci -1, 0 lub 1, jeśli pierwsze wyrażenie jest mniejsze niż, równe lub większe niż drugie wyrażenie.
// Integers
print (1 <=> 1); // 0
print (1 <=> 2); // -1
print (2 <=> 1); // 1
// Floats
print (1.5 <=> 1.5); // 0
print (1.5 <=> 2.5); // -1
print (2.5 <=> 1.5); // 1
// Strings
print ("a" <=> "a"); // 0
print ("a" <=> "b"); // -1
print ("b" <=> "a"); // 1
Obiekty nie są porównywalne, a więc spowoduje to nieokreślone zachowanie.
Operator jest szczególnie przydatna przy pisaniu funkcję porównania zdefiniowany przez użytkownika za pomocą usort
, uasort
lub uksort
. Biorąc pod uwagę tablicę obiektów do sortowania według ich właściwości weight
, na przykład funkcja anonimowa może użyć <=>
aby zwrócić wartość oczekiwaną przez funkcje sortowania.
usort($list, function($a, $b) { return $a->weight <=> $b->weight; });
W PHP 5 wymagałoby to bardziej skomplikowanego wyrażenia.
usort($list, function($a, $b) {
return $a->weight < $b->weight ? -1 : ($a->weight == $b->weight ? 0 : 1);
});
Zerowy operator koalescencyjny (??)
Koalescencja zerowa to nowy operator wprowadzony w PHP 7. Ten operator zwraca swój pierwszy operand, jeśli jest ustawiony, a nie NULL
. W przeciwnym razie zwróci drugi operand.
Poniższy przykład:
$name = $_POST['name'] ?? 'nobody';
odpowiada zarówno:
if (isset($_POST['name'])) {
$name = $_POST['name'];
} else {
$name = 'nobody';
}
i:
$name = isset($_POST['name']) ? $_POST['name'] : 'nobody';
Ten operator można również połączyć w łańcuch (z semantyką asocjatywną):
$name = $_GET['name'] ?? $_POST['name'] ?? 'nobody';
co jest równoważne z:
if (isset($_GET['name'])) {
$name = $_GET['name'];
} elseif (isset($_POST['name'])) {
$name = $_POST['name'];
} else {
$name = 'nobody';
}
Uwaga:
Korzystając z operatora koalescencyjnego podczas konkatenacji łańcuchów, nie zapomnij użyć nawiasów ()
$firstName = "John";
$lastName = "Doe";
echo $firstName ?? "Unknown" . " " . $lastName ?? "";
Spowoduje to wyświetlenie tylko John
, a jeśli jego $ firstName ma wartość null, a $ lastName to Doe
, wyświetli Unknown Doe
. Aby John Doe
, musimy użyć nawiasów takich jak ten.
$firstName = "John";
$lastName = "Doe";
echo ($firstName ?? "Unknown") . " " . ($lastName ?? "");
Spowoduje to wyświetlenie John Doe
zamiast John
.
instanceof (operator typu)
Do sprawdzania, czy jakiś obiekt należy do określonej klasy, można używać (binarnego) instanceof
od wersji PHP 5.
Pierwszy (lewy) parametr to obiekt do przetestowania. Jeśli ta zmienna nie jest obiektem, instanceof
zawsze zwraca false
. Jeśli używane jest wyrażenie stałe, generowany jest błąd.
Drugi (prawy) parametr to klasa do porównania. Klasa może być podana jako sama nazwa klasy, zmienna łańcuchowa zawierająca nazwę klasy (nie stała ciągu!) Lub obiekt tej klasy.
class MyClass {
}
$o1 = new MyClass();
$o2 = new MyClass();
$name = 'MyClass';
// in the cases below, $a gets boolean value true
$a = $o1 instanceof MyClass;
$a = $o1 instanceof $name;
$a = $o1 instanceof $o2;
// counter examples:
$b = 'b';
$a = $o1 instanceof 'MyClass'; // parse error: constant not allowed
$a = false instanceof MyClass; // fatal error: constant not allowed
$a = $b instanceof MyClass; // false ($b is not an object)
instanceof
może być również użyty do sprawdzenia, czy obiekt należy do jakiejś klasy, która rozszerza inną klasę lub implementuje interfejs:
interface MyInterface {
}
class MySuperClass implements MyInterface {
}
class MySubClass extends MySuperClass {
}
$o = new MySubClass();
// in the cases below, $a gets boolean value true
$a = $o instanceof MySubClass;
$a = $o instanceof MySuperClass;
$a = $o instanceof MyInterface;
Aby sprawdzić, czy obiekt nie należy do jakiejś klasy, można użyć operatora not ( !
):
class MyClass {
}
class OtherClass {
}
$o = new MyClass();
$a = !$o instanceof OtherClass; // true
Zauważ, że nawiasy wokół $o instanceof MyClass
nie są potrzebne, ponieważ instanceof
ma wyższy priorytet niż !
, chociaż może sprawić, że kod będzie lepiej czytelny w nawiasach.
Ostrzeżenia
Jeśli klasa nie istnieje, zarejestrowane funkcje autoload są wywoływane, aby spróbować zdefiniować klasę (jest to temat poza zakresem tej części Dokumentacji!). W wersjach PHP wcześniejszych niż 5.1.0 operator instanceof
również wyzwalałby te wywołania, w ten sposób definiując klasę (a gdyby nie można było zdefiniować klasy, wystąpiłby błąd krytyczny). Aby tego uniknąć, użyj ciągu znaków:
// only PHP versions before 5.1.0!
class MyClass {
}
$o = new MyClass();
$a = $o instanceof OtherClass; // OtherClass is not defined!
// if OtherClass can be defined in a registered autoloader, it is actually
// loaded and $a gets boolean value false ($o is not a OtherClass)
// if OtherClass can not be defined in a registered autoloader, a fatal
// error occurs.
$name = 'YetAnotherClass';
$a = $o instanceof $name; // YetAnotherClass is not defined!
// $a simply gets boolean value false, YetAnotherClass remains undefined.
Od wersji PHP 5.1.0 zarejestrowane autoloadery nie są już wywoływane w takich sytuacjach.
Starsze wersje PHP (przed 5.0)
W starszych wersjach PHP (wcześniejszych niż 5.0) można is_a
funkcji is_a
do ustalenia, czy obiekt jest jakiejś klasy. Ta funkcja została uznana za przestarzałą w wersji PHP 5 i nieaktualna w wersji PHP 5.3.0.
Operator trójskładnikowy (? :)
Operator trójskładnikowy można traktować jako wbudowaną instrukcję if
. Składa się z trzech części. operator
i dwa wyniki. Składnia jest następująca:
$value = <operator> ? <true value> : <false value>
Jeśli operator
zostanie oceniony jako true
, wartość w pierwszym bloku zostanie zwrócona ( <true value>
), w przeciwnym razie wartość w drugim bloku zostanie zwrócona ( <false value>
). Ponieważ ustawiamy $value
na wynik naszego trójskładnikowego operatora, będzie ona przechowywać zwróconą wartość.
Przykład:
$action = empty($_POST['action']) ? 'default' : $_POST['action'];
$action
zawiera ciąg 'default'
jeśli empty($_POST['action'])
wartość true. W przeciwnym razie zawierałby wartość $_POST['action']
.
Wyrażenie (expr1) ? (expr2) : (expr3)
ocenia na expr2
jeśli expr1
wartość true
, a expr3
jeśli expr1
wartość false
.
Możliwe jest pominięcie środkowej części operatora trójskładnikowego. Wyrażenie expr1 ?: expr3
zwraca expr1
jeśli expr1
wartość PRAWDA, a expr3
przeciwnym razie. ?:
jest często nazywany operatorem Elvisa .
To zachowuje się jak operator zerowego koalescencji ??
oprócz tego ??
wymaga, aby lewy operand był dokładnie null
podczas gdy ?:
próbuje przekształcić lewy operand w wartość logiczną i sprawdzić, czy rozwiązuje on wartość logiczną false
.
Przykład:
function setWidth(int $width = 0){
$_SESSION["width"] = $width ?: getDefaultWidth();
}
W tym przykładzie setWidth
akceptuje parametr width lub default 0, aby zmienić wartość sesji width. Jeśli $width
wynosi 0 (jeśli $width
nie jest podane), co rozwiąże boolean false, zostanie użyta wartość getDefaultWidth()
. Funkcja getDefaultWidth()
nie zostanie wywołana, jeśli $width
nie rozpoznaje wartości logicznej false.
Zobacz Typy, aby uzyskać więcej informacji na temat konwersji zmiennych na wartość logiczną.
Operatory inkrementacji (++) i dekrementacji (-)
Zmienne można zwiększać lub zmniejszać o 1 za pomocą odpowiednio ++
lub --
. Mogą one poprzedzać lub odnosić zmienne i nieznacznie różnić się semantycznie, jak pokazano poniżej.
$i = 1;
echo $i; // Prints 1
// Pre-increment operator increments $i by one, then returns $i
echo ++$i; // Prints 2
// Pre-decrement operator decrements $i by one, then returns $i
echo --$i; // Prints 1
// Post-increment operator returns $i, then increments $i by one
echo $i++; // Prints 1 (but $i value is now 2)
// Post-decrement operator returns $i, then decrements $i by one
echo $i--; // Prints 2 (but $i value is now 1)
Więcej informacji na temat zwiększania i zmniejszania operatorów można znaleźć w oficjalnej dokumentacji .
Operator wykonania (``)
Operator wykonawczy PHP składa się z tylnych klawiszy (``) i służy do uruchamiania poleceń powłoki. Dane wyjściowe polecenia zostaną zwrócone i dlatego mogą być przechowywane w zmiennej.
// List files
$output = `ls`;
echo "<pre>$output</pre>";
Zauważ, że operator execute i shell_exec()
dają ten sam wynik.
Operatory logiczne (&& / AND i || / OR)
W PHP istnieją dwie wersje logicznych operatorów AND i OR.
Operator | Prawda jeśli |
---|---|
$a and $b | Zarówno $a i $b są prawdziwe |
$a && $b | Zarówno $a i $b są prawdziwe |
$a or $b | Prawda jest albo $a albo $b |
$a || $b | Prawda jest albo $a albo $b |
Pamiętaj, że &&
i ||
operatorzy mają wyższy priorytet niż and
i or
. Zobacz tabelę poniżej:
Ocena | Wynik $e | Oceniony jako |
---|---|---|
$e = false || true | Prawdziwe | $e = (false || true) |
$e = false or true | Fałszywy | ($e = false) or true |
Z tego powodu bezpieczniej jest używać &&
i ||
zamiast and
i or
.
Operatory bitowe
Prefiks operatorów bitowych
Operatory bitowe są jak operatory logiczne, ale wykonywane na bit, a nie na wartość logiczną.
// bitwise NOT ~: sets all unset bits and unsets all set bits
printf("%'06b", ~0b110110); // 001001
Operatorzy maski bitmaskowej
Bitowe AND &
: bit jest ustawiany tylko wtedy, gdy jest ustawiony w obu operandach
printf("%'06b", 0b110101 & 0b011001); // 010001
Bitowe LUB |
: bit jest ustawiany, jeśli jest ustawiony w jednym lub obu operandach
printf("%'06b", 0b110101 | 0b011001); // 111101
Bitowy XOR ^
: bit jest ustawiany, jeśli jest ustawiony w jednym operandzie, a nie ustawiony w innym operandzie, tj. Tylko jeśli ten bit jest w innym stanie w dwóch operandach
printf("%'06b", 0b110101 ^ 0b011001); // 101100
Przykładowe zastosowania masek bitowych
Tych operatorów można używać do manipulowania maskami bitowymi. Na przykład:
file_put_contents("file.log", LOCK_EX | FILE_APPEND);
Tutaj |
operator służy do łączenia dwóch masek bitowych. Chociaż +
ma taki sam efekt, |
podkreśla, że łączysz maski bitowe, a nie dodajesz dwóch normalnych liczb całkowitych skalarnych.
class Foo{
const OPTION_A = 1;
const OPTION_B = 2;
const OPTION_C = 4;
const OPTION_A = 8;
private $options = self::OPTION_A | self::OPTION_C;
public function toggleOption(int $option){
$this->options ^= $option;
}
public function enable(int $option){
$this->options |= $option; // enable $option regardless of its original state
}
public function disable(int $option){
$this->options &= ~$option; // disable $option regardless of its original state,
// without affecting other bits
}
/** returns whether at least one of the options is enabled */
public function isOneEnabled(int $options) : bool{
return $this->options & $option !== 0;
// Use !== rather than >, because
// if $options is about a high bit, we may be handling a negative integer
}
/** returns whether all of the options are enabled */
public function areAllEnabled(int $options) : bool{
return ($this->options & $options) === $options;
// note the parentheses; beware the operator precedence
}
}
W tym przykładzie (zakładając, że $option
zawsze zawiera tylko jeden bit) użyto:
- operator
^
, aby wygodnie przełączać maski bitowe. -
|
operator, aby ustawić nieco zaniedbując swój pierwotny stan lub inne bity - operator
~
konwertuje liczbę całkowitą z ustawionym tylko jednym bitem na liczbę całkowitą bez ustawionego tylko jednego bitu - operator
&
odrobinę rozbroił, używając tych właściwości&
:- Ponieważ
&=
z ustawionym bitem nic nie zrobi ((1 & 1) === 1
,(0 & 1) === 0
), robienie&=
z liczbą całkowitą bez ustawionego tylko jednego bitu spowoduje tylko rozbrojenie tego bitu , nie wpływając na inne bity. -
&=
z bitem rozbrojonym spowoduje rozbrojenie tego bitu ((1 & 0) === 0
,(0 & 0) === 0
)
- Ponieważ
- Użycie operatora
&
z inną maską bitową odfiltruje wszystkie inne bity, które nie są ustawione w tej masce bitowej.- Jeśli na wyjściu są ustawione jakieś bity, oznacza to, że dowolna z opcji jest włączona.
- Jeśli na wyjściu są ustawione wszystkie bity maski bitowej, oznacza to, że wszystkie opcje w masce bitowej są włączone.
Należy pamiętać, że te operatory porównania: ( <
>
<=
>=
==
===
!=
!==
<>
<=>
) mają wyższy priorytet niż te podmioty maski bitowej-bitową: ( |
^
&
). Ponieważ wyniki bitowe są często porównywane za pomocą tych operatorów porównania, jest to powszechna pułapka, o której należy pamiętać.
Operatorzy przesuwający bity
Przesunięcie bitowe w lewo <<
: przesuń wszystkie bity w lewo (bardziej znaczące) o podaną liczbę kroków i odrzuć bity przekraczające rozmiar int
<< $x
jest równoważne rozbrojeniu najwyższych $x
bitów i pomnożeniu przez $x
th potęgę 2
printf("%'08b", 0b00001011<< 2); // 00101100
assert(PHP_INT_SIZE === 4); // a 32-bit system
printf("%x, %x", 0x5FFFFFFF << 2, 0x1FFFFFFF << 4); // 7FFFFFFC, FFFFFFFF
Przesunięcie bitowe w prawo >>
: odrzuć najniższe przesunięcie i przesuń pozostałe bity w prawo (mniej znaczące)
>> $x
jest równoważne podzieleniu przez potęgę $x
potęgi 2 i odrzucenie części niecałkowitej
printf("%x", 0xFFFFFFFF >> 3); // 1FFFFFFF
Przykładowe zastosowania przesunięcia bitów:
Szybki podział przez 16 (lepsza wydajność niż /= 16
)
$x >>= 4;
W systemach 32-bitowych powoduje to odrzucenie wszystkich bitów w liczbie całkowitej, ustawiając wartość na 0. W systemach 64-bitowych powoduje to wyłączenie najbardziej znaczących 32 bitów i zachowanie najmniejszej liczby
$x = $x << 32 >> 32;
znaczące 32 bity, co odpowiada $x & 0xFFFFFFFF
Uwaga: W tym przykładzie printf("%'06b")
. Wyprowadza wartość w postaci 6 cyfr binarnych.
Operatory obiektowe i klasowe
Do elementów obiektów lub klas można uzyskać dostęp za pomocą operatora obiektu ( ->
) i operatora klasy (: ::
.
class MyClass {
public $a = 1;
public static $b = 2;
const C = 3;
public function d() { return 4; }
public static function e() { return 5; }
}
$object = new MyClass();
var_dump($object->a); // int(1)
var_dump($object::$b); // int(2)
var_dump($object::C); // int(3)
var_dump(MyClass::$b); // int(2)
var_dump(MyClass::C); // int(3)
var_dump($object->d()); // int(4)
var_dump($object::d()); // int(4)
var_dump(MyClass::e()); // int(5)
$classname = "MyClass";
var_dump($classname::e()); // also works! int(5)
Zauważ, że po operatorze obiektu $
nie powinno być zapisywane ( $object->a
zamiast $object->$a
). W przypadku operatora klasy tak nie jest i $
jest konieczne. Dla stałej zdefiniowanej w klasie $
nigdy nie jest używane.
Zauważ też, że var_dump(MyClass::d());
jest dozwolone tylko wtedy, gdy funkcja d()
nie odwołuje się do obiektu:
class MyClass {
private $a = 1;
public function d() {
return $this->a;
}
}
$object = new MyClass();
var_dump(MyClass::d()); // Error!
Powoduje to „Błąd krytyczny PHP: Nieprzechwycony błąd: użycie $ this, gdy nie ma kontekstu obiektowego”
Operatorzy ci porzucili skojarzenie, które można wykorzystać do „łączenia”:
class MyClass {
private $a = 1;
public function add(int $a) {
$this->a += $a;
return $this;
}
public function get() {
return $this->a;
}
}
$object = new MyClass();
var_dump($object->add(4)->get()); // int(5)
Operatorzy ci mają najwyższy priorytet (nie są nawet wspomniani w instrukcji), nawet wyższy niż clone
. A zatem:
class MyClass {
private $a = 0;
public function add(int $a) {
$this->a += $a;
return $this;
}
public function get() {
return $this->a;
}
}
$o1 = new MyClass();
$o2 = clone $o1->add(2);
var_dump($o1->get()); // int(2)
var_dump($o2->get()); // int(2)
Wartość $o1
jest dodawana przed sklonowaniem obiektu!
Zauważ, że użycie nawiasów w celu wpłynięcia na pierwszeństwo nie działało w PHP w wersji 5 i starszych (działa w PHP 7):
// using the class MyClass from the previous code
$o1 = new MyClass();
$o2 = (clone $o1)->add(2); // Error in PHP 5 and before, fine in PHP 7
var_dump($o1->get()); // int(0) in PHP 7
var_dump($o2->get()); // int(2) in PHP 7