Certyfikat ZendPHP

Podstawy PHP

Podstawowe funkcje językowe

Wszystkie instrukcje w PHP muszą być zakończone średnikiem. Wyjątkiem jest sytuacja, gdy instrukcja jest ostatnią instrukcją przed znacznikiem zamykającym. Białe znaki nie mają znaczenia semantycznego w PHP. Nie ma potrzeby dostosowywania kodu, ale większość standardów kodowania wymusza to, aby poprawić czytelność kodu. Białe znaki mogą nie pojawiać się pośrodku nazw funkcji, nazw zmiennych lub słów kluczowych. Wiele instrukcji jest dozwolonych w jednym wierszu. Bloki kodu są oznaczone symbolami nawiasu klamrowego {}. Nazwy konstrukcji i funkcji języka PHP nie rozróżniają wielkości liter, ale w nazwach zmiennych już tak

ECHO "Hello World"; // Działa
$variable = "Hello World";
echo $VARIABLE; // Nie będzie działać

Wstawianie PHP na strony internetowe

Chociaż PHP jest ogólnym językiem skryptowym i może być używany do innych celów, najczęściej jest wdrażany jako język skryptowy po stronie serwera używany do tworzenia stron internetowych. Parser PHP nie analizuje niczego, co nie jest zawarte w znacznikach wskazujących skrypt PHP. Treść poza tagami PHP jest po prostu wyprowadzana bez kontroli. Pozwala to na osadzenie PHP w HTML. Istnieje kilka sposobów rozgraniczenia skryptu PHP, ale powszechnie stosuje się tylko dwa pierwsze:



Znacznik echo umożliwia łatwe echo zmiennej PHP, a skrócony znacznik ułatwia czytanie dokumentu HTML. Jest powszechnie stosowany w szablonach, w których chcesz wyprowadzać kilka wartości w różnych pozycjach na stronie. Dzięki krótkiej składni kod szablonu jest znacznie bardziej uporządkowany. Jego użycie jest najłatwiejsze do zrozumienia, gdy jest wyświetlane wraz z odpowiednikiem w standardowych kodach otwarcia. Dwa poniższe znaczniki są identyczne:

< ?= $variable ? >
< ?php echo $variable ? >

Uwaga : Instrukcja echo jest ostatnią instrukcją przed zamykającym znacznikiem, więc nie wymaga średnika, aby ją zakończyć.

Możesz używać logiki PHP między otwierającym a zamykającym znacznikiem, jak w tym przykładzie:

Saldo:
if ($bankBalance > 0): ?>
< p class="black" >
< ?php else: ?>
< p class="red" >
< ?php endif; ? >
< ?= $bankBalance? >
< /p >

Przejdźmy przez kod:

1. Parser PHP wyświetli Saldo: bez oceny, ponieważ nie ma go w tagach PHP.
2. Znacznik PHP sprawdza następnie, czy saldo jest większe od zera, i kończy działanie. Znacznik < p class = "black" > jest generowany tylko wtedy, gdy ten warunek jest spełniony; w przeciwnym razie generowany jest znacznik < p class = "red" >.
3. Używamy składni znacznika echo do wyprowadzania zmiennej $bankBalance.
4. Wreszcie znacznik zamykający akapitu jest wyprowadzany bez analizowania, ponieważ skrypt PHP został zamknięty.

Uwaga" To podejście działa również przy użyciu składni nawiasów klamrowych instrukcji if.

W programach PHP dość często pomija się znacznik zamykający ?> w pliku. Jest to akceptowalne dla parsera i jest użytecznym sposobem zapobiegania problemom z pojawieniem się znaków nowej linii po znaczniku zamykającym.
Te znaki nowej linii są wysyłane jako wyjście przez interpreter PHP i mogą zakłócać nagłówki HTTP lub powodować inne niezamierzone skutki uboczne. Nie zamykając skryptu w pliku PHP, zapobiega się wysyłaniu znaków nowej linii.

Wskazówka: Powszechnym standardem kodowania jest pominięcie znacznika zamykającego w dołączonych plikach, ale nie jest to wymóg PHP.

Konstrukcje językowe

Konstrukcje językowe różnią się od funkcji tym, że są zapiezone bezpośrednio w języku. Konstrukcje językowe mogą być rozumiane bezpośrednio przez analizator składni i nie trzeba ich rozkładać. Z drugiej strony funkcje są mapowane i upraszczane do zestawu konstrukcji językowych przed ich analizą. Konstrukcje językowe nie są funkcjami, dlatego nie można ich używać jako funkcji wywołania zwrotnego. Przestrzegają reguł, które różnią się od funkcji, jeśli chodzi o parametry i użycie nawiasów. Na przykład echo nie zawsze wymaga nawiasów podczas wywoływania, a jeśli wywołujesz go z więcej niż jednym argumentem, nie możesz używać nawiasów.

< ?php
// jeden parametr, bez nawiasów
echo "hello\r\n";
// dwa parametry, nawiasy kwadratowe (błąd składniowy)
//echo('hello', 'world');
// dwa parametry, bez nawiasów
echo 'hello', 'world';

Ponadto echo nie zwraca wartości, podczas gdy każda funkcja zawsze zwraca wartość (lub null) .
Strona PHP Manual na temat zastrzeżonych słów kluczowych1 ma pełną listę, ale oto niektóre z konstrukcji, które powinieneś znać:

Konstrukcja : Użycie

assert: polecenie debugujące, aby przetestować warunek i zrobić coś, jeśli nie jest to prawda.
echo: Wyprowadzanie wartości na standardowe wyjście.
print: Wyprowadzanie wartości na standardowe wyjście.
exit: Opcjonalnie wysyłanie komunikatu i kończenie programu.
die: To jest alias exit.
return: Kończy funkcję i zwraca kontrolę do zakresu wywołującego lub, jeśli jest wywoływany w zasięgu globalnym, kończy program.
include: Zawiera plik i ocenia go. PHP wyświetli ostrzeżenie, jeśli plik nie zostanie znaleziony lub nie będzie można go odczytać.
include_once: Jeśli podasz include_once, PHP upewni się, że plik będzie zawierany tylko jeden raz.
require: PHP dołącza plik i ocenia go. Jeśli plik nie zostanie znaleziony lub nie będzie można go odczytać, wygenerowany zostanie błąd krytyczny.
require_once: Jak w przypadku include_once, ale zamiast ostrzeżenia zostanie wygenerowany błąd krytyczny.
eval: Argument jest oceniany jako PHP i wpływa na zasięg wywoływania.
empty: Zwraca wartość logiczną w zależności od tego, czy zmienna jest pusta czy nie. Puste zmienne obejmują zmienne null, puste ciągi, tablice bez elementów, wartości liczbowe 0, wartość ciągu 0 i logiczne wartości false.
isset: Zwraca true, jeśli zmienna została ustawiona, a false w przeciwnym razie.
unset :Czyści zmienną.
list: Przypisuje wiele zmiennych jednocześnie z tablicy.

Jednym z możliwych trudnych pytań egzaminacyjnych, które mogą się pojawić, jest zrozumienie niewielkiej różnicy między print a echo. Konstrukcja echo nie zwraca wartości, nawet zerowej, dlatego nie nadaje się do użycia wewnątrz wyrażenia. Konstrukcja print zwróci jednak wartość. Powodem, dla którego nie należy używać funkcji include_once() i require_once() przez cały czas, jest problem z wydajnością. PHP śledzi listę plików, które zostały dołączone w celu obsługi funkcjonalności tych funkcji. Wymaga to pamięci, więc te funkcje są raczej używane, gdy są konieczne, a nie na korzyść dołączenia lub wymagania.

Komentarze

Istnieją trzy style oznaczania komentarzy:

# Komentarze w stylu Perla
// Komentarze w stylu C.
/ *
Komentarz wieloliniowy
* /
Dokumentacja API może dodatkowo być zgodna ze standardami zewnętrznymi, takimi jak te stosowane w projekcie PHPDocumentor. To narzędzie bada komentarze w stylu interfejsu API i automatycznie tworzy dla Ciebie dokumentację. Dokumentacja API wygląda bardzo podobnie do komentarzy wielowierszowych:

/ **
Dokumentacja API ma dwie gwiazdki, nie jest to rozróżnienie składni PHP, ale tylko konwencja.
* /

Reprezentowanie liczb

Istnieją cztery sposoby wyrażenia liczby całkowitej w skrypcie PHP:

Notacja : Przykład : Uwaga

Dziesiętna : 1234
Binarna : 0b10011010010 : Identyfikowana przez wiodące 0b lub 0B
Ósemkowa : l 02322 : Identyfikowane przez wiodące 0
Szesnastkowa : 0x4D2 : Identyfikowany przez wiodące 0x lub 0X

Liczby zmiennoprzecinkowe (nazywane podwójnymi w niektórych innych językach) mogą być wyrażone albo w standardowym formacie dziesiętnym, albo w formacie wykładniczym

Format : Przykład

Dziesiętna : 123,456
Wykładnicza : 0,123456e3 lub 0,123456E3

Uwaga " Litera "e" w postaci wykładniczej nie rozróżnia wielkości liter, podobnie jak inne litery używane w formatach liczb całkowitych


Zmienne

W tej sekcji skupię się na tym, jak PHP obsługuje zmienne. Zakładam, że masz wystarczająco dużo doświadczenia z PHP, że nie muszę wyjaśniać, co są zmienne ani jak ich używać. Przyjrzymy się różnym typom zmiennych, które oferuje PHP, jak zmienić typ zmiennej i jak sprawdzić, czy zmienna jest ustawiona, czy nie.

Typy Zmiennych

PHP to luźno napisany język. Ważne jest, aby nie myśleć, że zmienne PHP nie mają typu. Zdecydowanie tak, po prostu mogą zmienić typ w czasie wykonywania i nie muszą jawnie deklarować swojego typu podczas inicjalizacji. PHP niejawnie rzutuje zmienną na typ danych wymagany dla operacji. Na przykład, jeśli operacja wymaga liczby, takiej jak operacja dodawania (+), wówczas PHP skonwertuje operandy na format numeryczny. Zostaniesz wprowadzony do żonglowania typami później i będziesz potrzebować znać zasady, których przestrzega PHP przy zmianie typu zmiennej. Na razie musisz tylko wiedzieć, że zmienne PHP mają typ, ten typ może się zmienić i chociaż możesz jawnie zmienić typ PHP robi to dla Ciebie pośrednio. PHP ma trzy kategorie zmiennych - skalarne, złożone i zasobów. Zmienna skalarna to taka, która może przechowywać tylko jedną wartość na raz. Zmienne złożone mogą zawierać jednocześnie kilka wartości. Zmienna zasobu wskazuje na coś, co nie jest rodzime dla PHP, jak uchwyt dostarczony przez system operacyjny do pliku lub połączenia z bazą danych. Tych zmiennych nie można rzutować. Wreszcie PHP ma typ null, który jest używany dla zmiennych, dla których nie ustawiono wartości. Możesz także przypisać wartość null do zmiennej, ale nie możesz rzutować na typ null w PHP 7.1.

Typy skalarne

Istnieją cztery typy skalarne:

Typ : Alias : Zawiera

Boolean : bool : Prawda czy fałsz
Integer : int : Liczba całkowita ze znakiem
Float: : : Dane numeryczne podwójne lub zmiennoprzecinkowe ze znakiem
String : : : Uporządkowany zbiór danych binarnych

Niektóre typy mają aliasy. Rozważmy na przykład ten kod, który pokazuje, że bool to alias boolean:

< ? php
$a = (boolean) true;
$b = (bool) true;
var_dump ($ a === $ b); // bool (true)

Łańcuchy w PHP nie są po prostu listą znaków. Wewnętrznie łańcuchy PHP zawierają informacje o ich długości i nie są zakończone zerem. Oznacza to, że mogą zawierać informacje binarne, takie jak plik obrazu odczytany z dysku. Innymi słowy, ciągi PHP są binarnie bezpieczne.

Typy złożone

Istnieją dwa typy kompozytów: tablice i obiekty. Każdy z nich ma własną sekcję

Rzutowanie zmiennych

Jest to bardzo ważna część zrozumienia PHP, a nawet bardzo doświadczeni programiści mogą nie być świadomi niektórych zasad, których PHP używa do rzutowania zmiennych. PHP niejawnie rzutuje zmienne na typ wymagany do wykonania operacji. Możliwe jest również jawne rzutowanie zmiennych za pomocą jednej z dwóch opcji:

•  Użyj operatora rzutowania
•  Użyj funkcji PHP

Operatory rzutowania są używane przez umieszczenie nazwy typu danych, który chcesz rzutować, w nawiasach przed nazwą zmiennej. Na przykład:

< ? php
$a = "123"; // $a jest łańcuchem
$a = (int)$ a; // $a jest teraz liczbą całkowitą
$a = (bool)$ a; // $a jest teraz logiczne i jest prawdziwe

Możesz rzutować zmienną na null, jak w poniższym przykładzie, ale to zachowanie jest przestarzałe w PHP 7.2, więc nie powinieneś tego robić, mimo że PHP 7.1 to obsługuje

< ? php
$a = "Hello World";
$a = (unset)$ a; // Przestarzałe w PHP 7.2
var_dump ($a); // NULL

Istnieją również funkcje PHP, które przekonwertują zmienną na typ danych. Są one nazywane w sposób, który jest samo dokumentujący: floatval, intval, strval i boolval. Dodatkowo funkcja intdiv potencjalnie rzutuje liczbę double na liczbę całkowitą, gdy zwróci wynik liczb całkowitych z podzielenia dwóch liczb całkowitych. Możesz także wywołać funkcję settype dla zmiennej, która przyjmuje żądany typ danych jako drugi argument.
Należy pamiętać o niektórych zasadach dotyczących rzutowania zmiennych w PHP. Powinieneś uważnie przeczytać stronę podręcznika na temat żonglowania typami, ponieważ istnieje wiele potknięć i pułapek w żonglowaniu typami. Upewnij się także, że czytasz strony, do których prowadzi link ze strony żonglerki typu. Zamiast wyczerpująco wymieniać reguły, skupię się na niektórych regułach, które mogą być sprzeczne z intuicją lub często się mylą. Rzutowanie z liczby zmiennoprzecinkowej na liczbę całkowitą nie zaokrągla wartości w górę lub w dół, ale raczej obcina część dziesiętną.

< ? php
a = 1234,56;
echo (int)$ a; // 1234 (nie 1235)
$ a = -1234,56
echo (int) $a; // -1234

Niektóre ogólne zasady rzutowania na Boolean są następujące:

o Puste tablice i łańcuchy są rzutowane na false.
o Ciągi zawsze mają wartość logiczną true, chyba że mają wartość, którą PHP uważa za "pustą".
o Ciągi zawierające liczby mają wartość true, jeśli liczba nie jest zerem. Przypomnij sobie, że takie ciągi zwracają wartość false, gdy wywoływana jest dla nich funkcja empty().
o Każda liczba całkowita (lub liczba zmiennoprzecinkowa), która nie jest zerem, jest true, więc liczby ujemne są true.

Obiekty mogą mieć zdefiniowaną magiczną metodę __toString (). Może to być przeciążone, jeśli chcesz mieć niestandardowy sposób rzutowania obiektu na ciąg. Konwersja ciągu na liczbę powoduje 0, chyba że ciąg zaczyna się od prawidłowych danych liczbowych. Domyślnie zmiennym typem numeru rzutowania będzie liczba całkowita, chyba że napotkamy wykładnik lub punkt dziesiętny, w którym to przypadku będzie liczbą zmiennoprzecinkową. Oto przykładowy skrypt, który pokazuje niektóre konwersje ciągów:

< ?php
$examples = [
"godzina 12",
"Wpół do jedenastej",
"12.30",
"7,2e2 minuty po północy"
];
foreach ($examples as $example) {
$result = 0 + $example;
var_dump($result);
}
/*
Dane wyjściowe:
int(12)
int(0)
double(12,3)
double(720)
*/

Liczba zmiennoprzecinkowa i liczby całkowite

Zachowaj ostrożność podczas rzutowania między liczbami zmiennoprzecinkowymi a liczbami całkowitymi. Podręcznik PHP ma bardzo dobry przykład tego, w jaki sposób wewnętrzne szczegóły implementacji typów numerycznych mogą mieć sprzeczne z intuicją wyniki:

< ?php
echo (int) ( (0.1+0.7) * 10 ); // 7
echo (int) ( (0.1+0.5) * 10); // 6

Można się spodziewać, że pierwszy przykład wyświetli 8, ale w rzeczywistości wewnętrzna reprezentacja zmiennoprzecinkowa jest tylko nieco mniejsza niż 8. Kiedy PHP przekształci liczbę zmiennoprzecinkową na liczbę całkowitą, zaokrągla się w kierunku zera, więc staje się 7. Powodem tego jest że niektóre liczby są wymierne przy podstawie 10, ale są niewymierne przy podstawie 2. Chociaż 0,7 można wyrazić jako liczbę wymierną przy podstawie 10, to gdy jest wyrażone pry podstawie 2, jest niewymierne. Ponieważ dostępna jest ograniczona liczba bitów do przechowywania liczby, nieuniknione jest wystąpienie pewnej utraty precyzji. Liczby całkowite PHP są zawsze ze znakiem. Zakres wartości, które może przyjąć liczba całkowita, będzie zależeć od systemu, na którym działa PHP. Możesz określić rozmiar liczby całkowitej w bajtach w czasie wykonywania, sprawdzając stałą PHP_INT_SIZE. Stałe PHP_INT_MAX i PHP_INT_MIN podadzą ci wartości maksymalne i minimalne, które mogą być przechowywane odpowiednio w liczbach całkowitych. Istnieją podobne stałe dla innych typów liczbowych. Są one wymienione na stronie podręcznika PHP o zarezerwowanych stałych.

Przestroga : Nie należy polegać na precyzji zmiennoprzecinkowej do ostatniej cyfry

Należy unikać testowania liczb zmiennoprzecinkowych bezpośrednio pod kątem równości, a raczej testować, czy są one takie same do określonego stopnia dokładności, jak w tym przykładzie:

< ?php
$pi = 3.14159625;
$indiana = 3.2;
$epsilon = 0.00001; // stopień błędu
if(abs($pi - $indiana) < $epsilon) {
echo "Te wartości wyglądają dla mnie tak samo";
} else {
echo "Te wartości są różne";
}

Ten kod sprawdza, czy wartości są takie same, do pięciu stopni dokładności. Ten skrypt wyświetli "Te wartości są różne", ponieważ różnica jest większa niż zdefiniowany przez nas stopień błędu.

Nazewnictwo Zmiennych

Zmienne PHP zaczynają się od symbolu dolara $, a nazwy zmiennych PHP są zgodne z następującymi zasadami:

•  W nazwach rozróżniana jest wielkość liter
•  Nazwy mogą zawierać litery, cyfry i znak podkreślenia
•  Nazwy nie mogą zaczynać się cyfrą

Konwencje kodowania różnią się w zależności od zastosowania camelCase, StudlyCase lub snake_case, ale wszystkie te formaty są poprawnymi formatami nazw zmiennych PHP PHP dopuszcza również nazwy zmiennych. Najlepiej ilustruje to przykład:

< ? php
$a = "foo";
$$ a = "bar"; // $a to "foo", więc zmienna $foo jest ustawiona
echo $foo; // bar

PHP 7 zawsze ocenia dostęp ściśle od lewej do prawej. Starsze wersje miały skomplikowany zestaw reguł określających sposób oceny tego rodzaju składni. Na szczęście PHP 7 jest prostsze i spójniejsze i nie będę się martwił wyjaśnianiem starszych wersji. Oto bardziej skomplikowany przykład ilustrujący, jak PHP ocenia od lewej do prawej:

< ? php
$a = "foo";
$$a ['bar'] = 'Mroczny kod';
// to twierdzenie przechodzi
assert ($$a ['bar'] === $foo ['bar']);
var_dump ($foo);
/ *
tablica (1) {
["bar"] =>
tablica (1) {
["baz"] =>
string (10) "Mroczny kod"
}
}
* /

stnieje kilka ostrzeżeń dotyczących używania nazw zmiennych zmiennych. Mogą mieć wpływ na bezpieczeństwo kodu, a także mogą powodować, że będzie on nieco nieprzejrzysty

Sprawdzanie, czy została ustawiona zmienna

Polecenie isset() zwróci true, jeśli zmienna została ustawiona, a false w przeciwnym razie. Lepiej jest użyć tej funkcji zamiast sprawdzania, czy zmienna ma wartość null, ponieważ nie spowoduje to wygenerowania ostrzeżenia przez PHP. Polecenie empty() zwróci true, jeśli zmienna nie jest ustawiona i nie wygeneruje ostrzeżenia. To nie jest kuloodporny sposób na sprawdzenie, czy zmienna jest ustawiona.

Uwaga : Pamiętaj, że ciąg "0" jest uważany za pusty, ale w rzeczywistości jest ustawiony.

Zmienne stają się nieustawione, gdy stają się poza zasięgiem i można użyć polecenia unset(), aby ręcznie wyczyścić zmienną. W dalszej części zobaczymy, że garbage collector jest odpowiedzialny za zwolnienie pamięci przydzielonej zmiennym, które zostały zwolnione

Stałe

Stałe są podobne do zmiennych, ale są niezmienne. Mają te same reguły nazewnictwa co zmienne, ale zgodnie z konwencją będą miały wielkie litery. Można je zdefiniować za pomocą funkcji define, jak pokazano:

< ?php
define('PI', 3.142);
echo PI;
define('UNITS', ['MILES_CONVERSION' => 1.6, 'INCHES_CONVERSION' => '2.54']);
echo "5km w milach to " . 5 * UNITS['MILES_CONVERSION'];
/*
3.1425km w milach to 8
*/

Trzeci parametr definicji jest opcjonalny i wskazuje, czy w nazwie stałej rozróżniana jest wielkość liter, czy nie. Możesz także użyć słowa kluczowego const do zdefiniowania stałych. Stałe mogą zawierać tylko tablice lub wartości skalarne, a nie zasoby ani obiekty.

< ?php
const UNITS = ['MILES_CONVERSION' => 1.6, 'INCHES_CONVERSION' => '2.54'];
echo "5km w milach to" . 5 * UNITS['MILES_CONVERSION'];
/*
5kmw milach 8
*/

Do utworzenia stałej przestrzeni nazw można użyć tylko słowa kluczowego const, tak jak w tym przykładzie, w którym tworzymy stałe w przestrzeni nazw "Foo", a następnie próbujemy odwoływać się do nich w przestrzeni nazw "Bar".

< ?php
namespace Foo;
const AVOCADO = 6.02214086;
// używając define()wygeneruj ostrzeżenie
define(MOLE, 'hill');
namespace Bar;
echo \Foo\AVOCADO;
//odwołanie do stałej, którą próbowaliśmy zdefiniować (), powoduje błąd krytyczny
echo \Foo\MOLE;

Nie można przypisać zmiennej do stałej.
Możesz użyć statycznych wartości skalarnych, aby zdefiniować stałą, jak poniżej:

const STORAGE_PATH = __DIR__. '/przechowywanie';

Uwaga : użycie stałej "magicznej" __DIR__, która jest ustawiana przez PHP w czasie wykonywania i zawiera ścieżkę, w której skrypt znajduje się w systemie plików.

Funkcja constant() służy do pobierania wartości stałej.

< ? php
const MILES_CONVERSION = 1.6;
echo "Jest". constant("MILES_CONVERSION"). "mil na kilometr";
/ *
Jest 1,6 mil na kilometr
* /

Zmienne Superglobalne

PHP ma kilka zmiennych superglobalnych, które są automatycznie dostępne dla skryptu. Zmienne te są dostępne w każdym zakresie. Możesz zmienić wartości zmiennych superglobalnych, ale ogólnie sugeruje się raczej przypisanie superglobalnej zmiennej o zasięgu lokalnym i zmodyfikowanie tej. Musisz wiedzieć, co każda ze zmiennych superglobalnych przechowuje:

$_GLOBALS : Tablica zmiennych, które istnieją w zasięgu globalnym.
$_SERVER : Tablica informacji o ścieżkach, nagłówkach i innych informacjach istotnych dla środowiska serwera.
$_GET : Zmienne wysłane w żądaniu GET.
$_POST : Zmienne wysłane w żądaniu POST.
$_FILES : Tablica asocjacyjna plików, które zostały przesłane w ramach żądania testu POST.
$_COOKIE: Tablica asocjacyjna zmiennych przekazywanych do bieżącego skryptu za pośrednictwem pliki cookie HTTP.
$_SESSION : Tablica asocjacyjna zawierająca zmienne sesji dostępne dla bieżącego skryptu.
$_REQUEST : Zmienne żądania POST, GET i COOKIE.
$_ENV : Tablica asocjacyjna zmiennych przekazywanych do bieżącego skryptu za pomocą metody środowiska.

Superglobalna zmienna $_SERVER ma wiele kluczy i powinieneś się z nimi zapoznać. Podręcznik PHP ma ich listę i powinieneś się upewnić, że przeczytałeś stronę podręcznika i zrozumiałeś wszystkie klucze.

Wskazówka : Zauważ, że $_SERVER ['argv'] zawiera argumenty wysłane do skryptu, które różnią się od $_ENV. Znajomość tego poziomu szczegółowości jest wymagana do egzaminu certyfikacyjnego

Magiczne Stałe

Stałe magiczne to te, które PHP zapewnia automatycznie każdemu działającemu skryptowi. Istnieje wiele zarezerwowanych stałych i trzeba znać stałe błędów, a także powszechnie używane stałe predefiniowane

Stała : Zawartość

__LINE__ : Bieżący numer wiersza wykonywanego skryptu PHP
__FILE__ :Pełna nazwa (w tym dowiązania symboliczne) i ścieżka do pliku w trakcie wykonania
__CLASS__: Nazwa wykonywanej klasy
__METHOD__ :Nazwa wykonywanej metody klasy
__FUNCTION__ :Nazwa wykonywanej funkcji
__TRAIT__: Przestrzeń nazw i nazwa cechy, w której działa kod
__NAMESPACE__ :Bieżąca przestrzeń nazw

Uwaga : Wartość tych magicznych stałych zmienia się w zależności od miejsca ich użycia


Operatory

Arytmetyka

Powinieneś rozpoznać funkcje arytmetyczne:

Dodawanie : 1 + 2.3
Odejmowanie : 4 - 5
Dzielenie : 6/7
Mnożenie : 8 * 9
Modulo : 10% 11 : Daje pozostałą część dzielenia 10 przez 11
Potęgowanie : 12 ** 13 : Podnosi 12 do potęgi 13

Te operatory arytmetyczne przyjmują dwa argumenty, dlatego nazywane są binarnymi.
Następujące jednoargumentowe operatory pobierają tylko jeden argument, a ich umieszczenie przed zmienną lub po niej zmienia sposób działania. W PHP są dwa jednoargumentowe operatory, mianowicie prefix i postfix. Są one nazwane po tym, czy operator pojawia się przed zmienną, na którą wpływa, czy po niej.

•  Jeśli operator pojawi się przed zmienną (prefix), wówczas interpreter najpierw ją oceni, a następnie zwróci zmienioną zmienną.
•  Jeśli operator pojawia się za zmienną (postfiks), wówczas interpreter zwróci zmienną taką, jaka była przed wykonaniem instrukcji, a następnie zwiększy zmienną.

Pokażmy ich wpływ na zmienną $a, którą ustawiamy na 1, a następnie działamy:



Operatory logiczne

PHP używa zarówno operatorów logicznych symboli, jak i słów. Operatory postaci symboli są oparte na C.



Najlepiej jest nie mieszać formy słowa (np. and) i symbolu (np. &&) w tym samym porównaniu, ponieważ operatory mają różne pierwszeństwo. Najbezpieczniej jest trzymać się wyłącznie użycia symbolu. W tym przykładzie widzimy, że pierwszeństwo operatorów powoduje, że zmienne $true i $pravda nie są takie same, mimo że wykonujemy "ten sam" operator logiczny, aby je uzyskać. Dzieje się tak, ponieważ operatory logiczne i / lub mają niższy priorytet niż operator równości =.

< ?php
$a = true;
$b = false;
$truth = $a and $b; // true
$pravda = $a && $b; // false assert($truth === $pravda);
/ *
Ostrzeżenie: assert(): assert ($truth === $ pravda) nie powiodło się
* /

Operator trójskładnikowy

PHP implementuje operator trójskładnikowy w tym samym formacie, co inne języki przodków C. Ogólny format jest następujący:

warunek? wyrażenie1: wyrażenie2;

Jeśli warunek jest spełniony, wyrażenie1 zostanie wyliczone; w przeciwnym razie wyrażenie2 jest wyliczane.

Oto przykład, który sprawdza warunek isset($ a) i przypisuje odpowiednio wartość ciągu "true" lub "false" do $b.

< ?php
$a = 'foo';
$b = (isset($a)) ? 'true' : 'false';
echo $b; // true

Powyższa składnia jest identyczna z następującą instrukcją if:

< ?php
$a = 'foo';
if (isset($a)) {
$b = 'true';
} else {
$b = 'false';
}
echo $b; // true

Jeśli prawdziwa wartość zostanie pominięta w potrójnym operatorze, wówczas instrukcja jest oceniana jako wyrażenie, jak następuje:

< ?php
$a = true;
$b = $a ?: 'foo';
echo $b; // 1

Ta skrócona wersja operatora trójskładnikowego nie nadaje się do testowania, czy istnieje zmienna, ponieważ w tym przypadku interpreter wyświetli ostrzeżenie

Operator koalescencyjny NULL

Operator koalescencyjny NULL jest tylko specjalnym przypadkiem operatora trójskładnikowego. Pozwala uporządkować składnię używaną podczas używania isset do przypisywania wartości domyślnej do zmiennej.

< ?php
//Długa składnia trójskładnikowa
$sortDirection = (isset($_GET['sort_dir'])) ? $_GET['sort_dir'] : 'ASC';
// Równoważna składnia przy użyciu zerowego operatora koalescencyjnego
$sortDirection = $_GET['sort_dir'] ?? 'ASC';
// Operator zerowej koalescencji może być powiązany
$sortDirection = $_GET['sort_dir'] ?? $defaultSortDir ?? 'ASC';
// Operator Elvisa wywołuje E_NOTICE jeśli zmienna GET nie jest ustawiona
$sortDirection = $_GET['sort_dir'] ?: 'ASC';

Lepiej jest zastosować operator zerowania-koalescencji nad Elvisem, ponieważ operator zerowania-koalescencji nie zgłasza błędu powiadomienia, jeśli zmienna nie jest ustawiona.

Spaceship

Operator spaceship służy do porównywania dwóch różnych wartości i jest szczególnie przydatny do pisania wywołań zwrotnych dla funkcji sortowania, które zajmiemy się później. Zwraca -1, 0 lub 1, gdy lewy operand jest odpowiednio mniejszy, równy lub większy niż prawy

Operacja : Wartość

1 &hAarr; 0 : 1
1 <=> 1 : 0
1 <=> 2 : -1
"jabłka" <=> "Banany" : 1
"Jabłka" <=> "banany" : -1

Operator statku kosmicznego stosuje standardowe reguły porównywania PHP

Operatory Bitowe

Operatory bitowe działają na bitach liczb całkowitych reprezentowanych w postaci binarnej. Użycie ich na innym typie zmiennej spowoduje, że PHP rzutuje zmienną na liczbę całkowitą przed jej użyciem. Istnieją trzy standardowe logiczne operatory bitowe:

Operator : Operacja : Opis

& : Bitowe AND : Wynik będzie miał ustawiony bit, jeśli oba bity operandów zostały ustawione
| : Bitowe OR : Jeśli jeden lub oba operandy mają ustawiony bit, wynik będzie miał ustawiony ten bit
^ : Bitowe XOR : Jeśli jeden i tylko jeden operand (nie oba) ma ustawiony bit, wynik będzie miał ustawiony bit.

Spójrzmy na 50 i 25 jako przykład. W trzech wierszach umieściłem reprezentacje binarne w komentarzach. Możesz zobaczyć, że obliczyłem binarną reprezentację $c sprawdzając, czy bit w tej pozycji jest ustawiony na $a i $b. W tym przypadku tylko jeden taki bit jest prawdziwy w obu pozycjach.

< ?php
$a = 50; // 0b110010
$b = 25; // 0b011001
$c = 50 & 25; // 0b010000
echo $c; // 16

Przesunięcie bitów

PHP ma także operatory do przesuwania bitów w lewo i prawo. Efektem tych operatorów jest przesunięcie wzoru bitowego wartości w lewo lub w prawo podczas wstawiania bitów ustawionych na 0 w nowo utworzonych pustych przestrzeniach. Aby zrozumieć, jak działają te operatory, wyobraź sobie liczbę reprezentowaną w postaci binarnej, a następnie wszystkie jedynki i zera przesuwane są w lewo lub w prawo. Poniższa tabela pokazuje przesunięte bity, jeden w prawo i jeden w lewo.



W formacie binarnym umieszczono wystarczającą liczbę zer wiodących, aby łatwiej było zobaczyć wzór tego, co się dzieje. Widać, że kiedy przesunęliśmy się w prawo, bit z prawej został "zgubiony". Kiedy przesuwamy w lewo, wstawiamy nowe bity, które są ustawione na 0 po prawej stronie. Ważne jest zachowanie ostrożności podczas korzystania z operacji bitowych do wykonywania obliczeń, ponieważ rozmiar przepełnienia liczb całkowitych może się różnić w zależności od środowiska, w którym wdrożony jest PHP. Na przykład, chociaż system 64-bitowy będzie miał taki sam wynik dla obu operacji, w 32-bitowym systemie całkowitym nie będzie:

< ?php
$x = 1;
echo $x << 32;
echo $x * pow(2, 32);

Pierwszy wiersz wyświetli 0, ponieważ przesunięcie w lewo o 32 bity wypełni 32-bitową liczbę całkowitą bitami 0. Drugi wiersz użyje biblioteki math i wyświetli poprawną wartość 2 podniesioną do potęgi 32.

Wskazówka : Jeśli chcesz eksperymentować z operatorami binarnymi, funkcja base_convert() będzie bardzo przydatna. Na przykład, aby wyświetlić binarną reprezentację liczby dziesiętnej 50, można tak : echo base_convert (50, 10, 2). PHP_EOL ;.

Bitowe NOT

Nie musisz znać szczegółów matematycznych stojących za tym operatorem, więc nie marnuj zbyt wiele czasu na martwienie się o szczegóły. Jeśli rozumiesz wpływ, jaki ma to na bity, powinieneś być gotowy odpowiedzieć na pytania na ten temat. PHP używa symbolu ˜ (tylda) do bitowego NIE. Działanie tego operatora polega na zamianie bitów na wartość - jeśli bit jest ustawiony, staje się nieuzbrojony, a jeśli nie został ustawiony, zostaje ustawiony. Najlepiej to rozumie przykład:



Wartość (dziesiętnie) wyniku wynosi -51. Tylko w celu wzbogacenia widzy można przeczytać w Wikipedii o uzupełnieniu dwóch. Jest używany głównie do uzyskania binarnej reprezentacji liczby ujemnej.

Operatory przypisania

PHP używa symbolu = jako operatora przypisania. Kolejny wiersz ustawia wartość $ a na 123.

< ? php
$a = 123;

Operator przypisania można łączyć z niemal wszystkimi operatorami binarnymi i arytmetycznymi. Ta składnia służy jako skrót, który najlepiej pokazano, podając przykład równoważnych instrukcji:

< ?php
$a + = 345; // równowartość $a = $a + 345;
$a. = "foo"; // równowartość $a = $a. 'bla';

Wynikiem dowolnego wyrażenia przypisania jest wartość zmiennej następującej po przypisaniu. Dość częstym błędem podczas pisania jest omyłkowe zapomnienie drugiego symbolu = podczas kontroli równości. Rozważ następujący przykład, w którym używamy operatora przypisania w instrukcji if, w którym zamierzaliśmy użyć operatora równości.

< ?php
$foo = "hello";
if ($ foo = "world") {
echo "pasuje";
} else {
echo "nie pasuje";
}

Gdyby to był operator równości, instrukcja if byłaby fałszywa, a skrypt wypisałby "nie pasuje". Ponieważ jednak przypisujemy ciąg "world" do zmiennej $ foo, wynikiem jest wartość "world", która w przypadku rzutowania na wartość logiczną jest prawdziwa. Niektóre konwencje kodowania używają tak zwanego "warunku Yoda", aby pomóc z tym błędem. Wykorzystuje fakt, że PHP nie pozwoli ci zmienić wartości stałej. Jeśli zawsze umieszczasz stałą po lewej stronie porównania równości, zostaniesz ostrzeżony, jeśli popełnisz błąd operatora. To, czy warto koszt czytelności kodu, zależy od osobistego stylu.

Operator referencji

Domyślnie PHP przypisuje wszystkie zmienne skalarne według wartości. PHP ma optymalizacje, dzięki którym przypisywanie według wartości jest szybsze niż przypisywanie przez referencję, ale jeśli chcesz przypisać referencję, możesz użyć operatora & w następujący sposób:

< ?php
$a = 1;
$b = &$a; // przypisanie przez odniesienie
$b + = 5;
echo $a; // 6

PHP zawsze przypisuje obiekty przez odniesienie; jeśli spróbujesz utworzyć go jawnie przez odwołanie, PHP wygeneruje błąd analizy.
class MyClass {}
// Błąd analizy: błąd składni, nieoczekiwany "nowy"
$a = &new MyClass;

Operatory porównania

PHP korzysta z następujących operatorów porównania:
Operatora : Opis

> : Większy niż
>= : Większy lub równy
< : Mniejszy niż
<= : Mniejszy lub równy
< > : Nie równe
== : Równoważność; wartości są równoważne, jeśli rzutuje się na ten sam typ zmiennej
=== : Tożsamość; wartości muszą być tego samego typu danych i mieć tę samą wartość
!= : Nie równe
!== : Nie identyczne

Ważne jest, aby zrozumieć różnicę między porównaniem równoważnośi a porównaniem tożsamości:

•  Operandy są równoważne, jeśli można je rzutować na wspólny typ danych i mają tę samą wartość.
•  Operandy są identyczne, jeśli mają ten sam typ danych i mają tę samą wartość.

Tablice są równoważne, jeśli mają takie same pary klucz i wartość. Są identyczne, jeśli mają te same pary klucz i wartość, w tej samej kolejności, a klucz-wartość są tego samego typu. Podczas korzystania z operatorów porównania na tablicach liczba ich kluczy służy do określania, która wartość jest większa lub mniejsza. W porównaniu ze zmienną skalarną zarówno obiekt, jak i tablica będą uważane za większe niż skalar.

< ?php
$a = [1];
$b = 100;
echo $a ⇔$ b; // 1

Zachowaj ostrożność podczas używania operatorów porównania na ciągach znaków lub podczas korzystania z nich w przypadku niedopasowania typów zmiennych

Dwa kolejne operatory

PHP udostępnia operator do tłumienia komunikatów o błędach. Działa to tylko wtedy, gdy biblioteka, na której opiera się funkcja, korzysta ze standardowego raportowania błędów PHP.

< ?php
// Komunikaty o błędach zostaną pominięte
$ dbConnection = @mysqli_connect (…);

Złą praktyką jest tłumienie błędów PHP za pomocą operatora @. Lepiej jest używać ustawień PHP, aby ukryć błędy w środowisku produkcyjnym i umożliwić środowisku programistycznemu wyświetlanie błędów. Posiadanie kodu, który nie działa cicho bez spowodowania błędu, sprawia, że debugowanie jest znacznie trudniejsze niż to konieczne. Ostatnim operatorem, który omówimy, jest operator backtick. To nie jest powszechnie używane i jest równoważne z wywołaniem polecenia shell_exec(). W poniższym przykładzie zmienna $a będzie zawierać nazwę użytkownika uruchamiającego interpreter PHP.

< ?php
// Jest to odpowiednik echa shell_exec ('whoami');
echo `whoami`;
W środowisku internetowym prawdopodobnie będą to www-data. Jest to ustawienie domyślne dla Nginx i Apache, ale z wiersza poleceń będzie nazwa zalogowanego użytkownika.


Struktury sterujące

Struktury sterujące pozwalają analizować zmienne, a następnie wybierać kierunek napływu programu. W tej sekcji przyjrzymy się kilku różnym rodzajom struktur kontrolnych i sposobom ich implementacji w PHP

Struktury warunkowe

PHP obsługuje if, else, elseif, switch i trójskładnikowe struktury warunkowe. Jeśli struktury wyglądają tak:

< ?php
if (warunek) {
// instrukcje do wykonania
} elseif (drugi warunek) {
// instrukcje do wykonania
} else {
// instrukcje do wykonania
}

Zauważ, że odstęp między else i if w elseif jest opcjonalny. Jeśli instrukcje mogą być zagnieżdżone. Instrukcja switch wygląda następująco:

< ?php
switch ($value) {
case '10' :
// instrukcje do wykonania
break;
case '20' :
// instrukcje do wykonania
break;
case '30' :
// instrukcje do wykonania
break;
default:
// instrukcje do wykonania
break;
}

Gdy wielkość liter pasuje do wartości, instrukcje w bloku kodu będą wykonywane, dopóki nie osiągnie polecenia przerwania. Pominięcie polecenia przerwania spowoduje, że wszystkie poniższe instrukcje w przełączniku będą wykonywane, dopóki przerwa nie zostanie trafiona, nawet jeśli wielkość liter nie jest zgodna z wartością. Może to być przydatne w niektórych okolicznościach, ale może również przynieść niezamierzone wyniki, jeśli zapomnisz użyć instrukcji break. Aby to zilustrować, rozważ ten przykład:

< ?php
$value = 10;
switch ($value) {
case '10' :
echo "Value is 10";
// brak instrukcji break
case '20' :
echo "Value is 20";
break;
case '30' :
echo "Value is 30";
break;
default:
echo "Value is not 10,20, or 30";
break;
}
// Wartość wynosi 10 Wartość wynosi 20

Uwaga : Jeśli wstawisz instrukcję case po domyślnym case , nie zostaną one sprawdzone.

Pętle

Najbardziej podstawową pętlą PHP jest pętla while. Ma dwie formy, jak pokazano:

< ?php
while (wyrażenie) {
// instrukcje do wykonania
}

do {
// instrukcje do wykonania
} while (wyrażenie)
Różnica między nimi polega na tym, że w pierwszej formie wyrażenie jest oceniane na początku pętli, a w drugiej formie na końcu. Oznacza to, że jeśli wyrażenie jest fałszywe, pętla while w ogóle nie będzie działać w pierwszym przypadku, ale będzie działać co najmniej raz w drugim przypadku. Składnia pętli for pokazuje korzenie C PHP i wygląda następująco:

< ?php
dla ($i = 0; $ i < 10; $ i ++) {
// Zrób coś
}

Podobnie jak w przypadku C, pierwsza instrukcja jest wykonywana w celu zainicjowania pętli. Drugi warunek jest oceniany na początku każdej pętli, a ostatnia instrukcja jest wykonywana na końcu każdej pętli. Pętla będzie działać, dopóki warunek nie zostanie oceniony jako fałszywy. Aby wykonać iterację po tablicy, możesz użyć foreach w następujący sposób:

< ?php
$arr = [
'a' => 'one',
'b' => 'two',
'c' => 'three'
];
foreach ($arr as $value) {
echo $value; // one, two, three
}
foreach ($arr as $key => $value) {
echo $key; // a, b, c
echo $value; // one, two, three
}

Wyjście z pętli

Istnieją dwa sposoby zatrzymania iteracji pętli w PHP - break i continue. Użycie continue powoduje zatrzymanie bieżącej iteracji i pozwala pętli przetworzyć kolejny warunek oceny. Pozwala to na wykonanie kolejnych iteracji.
Użycie break powoduje zatrzymanie całej pętli i dalsze iteracje nie wystąpią. Instrukcja break przyjmuje opcjonalną liczbę całkowitą, której można użyć do zerwania z wielu poziomów zagnieżdżonej pętli. Jeśli nie określono żadnej wartości, domyślnie jest to 1

Przestrzenie nazw

Przestrzenie nazw pomagają unikać kolizji nazw między bibliotekami lub innym wspólnym kodem. Przestrzeń nazw będzie otaczać zawarte w niej elementy, aby nie kolidowały z elementami zadeklarowanymi w innym miejscu. Można ich użyć, aby uniknąć zbyt opisowych nazw klas, podzielić bibliotekę na sekcje lub ograniczyć zastosowanie stałych do jednej sekcji kodu. Klasy enkapsulują kod w natychmiastowe jednostki. Przestrzenie nazw grupują funkcje, klasy i stałe w przestrzenie, w których ich nazwa jest unikalna. Deklaracja przestrzeni nazw musi wystąpić bezpośrednio po otwierającym znaczniku < ? php i żadne inne instrukcje nie mogą go poprzedzać. Przestrzenie nazw wpływają na stałe, ale należy je zadeklarować za pomocą słowa kluczowego const, a nie za pomocą define(). Możliwe jest posiadanie dwóch przestrzeni nazw w pliku, ale większość standardów kodowania zdecydowanie to odradza. Aby to zrobić, umieść kod przestrzeni nazw w nawiasach klamrowych, jak w tym przykładzie:

< ?php
namespace A {
// to jest w przestrzeni nazw A
}
namespace B {
// to jest w przestrzeni nazw A B
}
namespace {
// to jest w globalnej przestrzeni nazw
}

Uwaga : To użycie nie jest standardową praktyką; w większości przypadków deklaracja przestrzeni nazw nie zawiera nawiasów klamrowych, a wszystkie instrukcje w pliku istnieją tylko w jednej przestrzeni nazw

W pełni kwalifikowane nazwy przestrzeni nazw

Jeśli pracujesz w przestrzeni nazw, wówczas interpreter przyjmie, że nazwy są względne w stosunku do bieżącej przestrzeni nazw. Rozważ tę klasę jako podstawę dla następujących przykładów:

< ?php
namespace MyApp\Helpers;
class Formatters
{
public static function asCurrency($val) {
// statement
}
}

Jeśli chcemy użyć tej klasy z innej przestrzeni nazw, musimy podać w pełni kwalifikowaną przestrzeń nazw, jak w tym przykładzie:

< ?php
// ten plik ma inną przestrzeń nazw
namespace MyApp\Lib;
// musimy podać pełną ścieżkę do przestrzeni nazw, w której znajduje się klasa
echo MyApp\Helpers\Formatters::asCurrency(10);

Alternatywnie możesz użyć instrukcji use, aby zaimportować przestrzeń nazw, abyś nie musiał cały czas używać długiego formatu:

< ?php
// ten plik ma inną przestrzeń nazw
namespace MyApp\Lib;
// słowo kluczowe "use" importuje przestrzeń nazw
use MyApp\Helpers\Formatters;
// nie musimy już podawać pełnego odniesienia
echo Formatters::asCurrency(10);

Możesz poprzedzić nazwę odwrotnym ukośnikiem, aby wskazać, że zamierzasz używać globalnej przestrzeni nazw, jak w tym przykładzie:

< ?php
namespace MyApp;
throw new \Exception('Global namespace');

W tym przykładzie, gdybyśmy nie wskazali zasięgu globalnego odwrotnym ukośnikiem, interpreter szukałby klasy o nazwie Wyjątek w przestrzeni nazw MyApp.

Konfiguracja

Gorąco polecam wykonanie praktycznych prac związanych z konfiguracją PHP. Możesz skonfigurować maszynę wirtualną na swoim komputerze i zainstalować na niej Linux, co zapewni ci praktyczne doświadczenie. Istnieje kilka pakietów Windows i Mac, które oferują konfigurację typu "wszystko w jednym" dla PHP, ale powinieneś upewnić się, że znajdziesz pliki konfiguracyjne i przejrzysz je.

Gdzie Ustawienia mogą zostać ustawione lub zmienione

PHP oferuje elastyczną strategię konfiguracji, w której podstawowe ustawienia konfiguracji mogą zostać zastąpione przez pliki konfiguracyjne użytkownika, a nawet w czasie wykonywania przez same PHP. W tym celu najlepiej zapoznać się z instrukcją. Powielenie jej tutaj spowoduje tylko nieaktualne informacje. Zobacz link w Internecie

Php.ini

Plik PHP.ini określa konfigurację dla każdego środowiska PHP. Środowisko tutaj odnosi się do tego, jak PHP jest uruchamiane na przykład przez powłokę poleceń, jako proces FPM lub w Apache2 jako moduł. Każde środowisko będzie miało katalog znajdujący się poza głównym katalogiem konfiguracji, którym jest domyślnie /etc/php/7.0/ w Ubuntu. Komputery z systemem Windows używają rejestru do przechowywania lokalizacji pliku php.ini. Rzeczywista nazwa klucza różni się w zależności od wersji PHP, ale będzie podobna do następującej: HKEY_LOCAL_MACHINE \ SOFTWARE \ PHP. Jeśli komputer z systemem Windows nie może go znaleźć w lokalizacji określonej przez Rejestr, wróci do szukania pliku w wielu domyślnych lokalizacjach, w tym w katalogu systemowym Windows. Oprócz pliku php.ini można określić katalog, który PHP będzie skanować w poszukiwaniu dodatkowych plików konfiguracyjnych. Możesz użyć funkcji php_ini_scanned_files(), aby uzyskać listę dołączonych plików, a także kolejność dołączania. Plik konfiguracyjny jest odczytywany przy każdym uruchomieniu serwera (apache) lub procesu (fpm / cli). Oznacza to, że jeśli zmienisz konfigurację PHP, będziesz musiał ponownie załadować serwer Apache2 lub ponownie uruchomić usługę fpm. W przeciwieństwie do tego zmiany w konfiguracji CLI nie będą działać przy następnym uruchomieniu PHP z powłoki. Możliwe jest użycie zmiennych środowiskowych systemu operacyjnego w pliku PHP.ini przy użyciu następującej składni:

; PHP_MEMORY_LIMIT jest pobierany ze środowiska
memory_limit = $ {PHP_MEMORY_LIMIT}

Pliki INI użytkownika

PHP sprawdza te pliki, gdy działa w trybie FastCGI (PHP 5.3+). Dzieje się tak, gdy używasz modułu fpm, ale nie w CLI ani Apache2. PHP najpierw sprawdzi te pliki w katalogu, w którym działa skrypt, i zacznie pracę wstecz aż do katalogu głównego dokumentu. Katalog główny jest skonfigurowany w pliku hosta i znajduje odzwierciedlenie w zmiennej $ _SERVER ['DOCUMENT_ROOT']. Te pliki INI zastąpią ustawienia w php.ini, ale wpłyną tylko na ustawienia oznaczone jako PHP_INI_PERDIR lub PHP_INI_USER. Odwołaj się do poprzedniego łącza, aby uzyskać listę ustawień i miejsca, w których można je zmienić. Główny plik konfiguracyjny ma dwie dyrektywy dotyczące plików INI użytkownika. Pierwszy, user_ini_filename, określa nazwę pliku, którego szuka PHP. Drugi, user_cache_ttl, określa, jak często plik użytkownika jest odczytywany z dysku.

Wersja plików INI w Apache

Jeśli używasz Apache, możesz użyć .htaccess do zarządzania ustawieniami INI użytkownika. Przeszukano je w ten sam sposób, co pliki fastcgi. Musisz ustawić wartość AllowOverride w konfiguracji vhost na true w każdym katalogu, w którym chcesz odczytać plik .htaccess.

Wydajność

Wiele problemów z wydajnością PHP dotyczy środowiska wdrażania, które wykracza poza zakres tego odniesienia. Jednym z potencjalnych problemów z wdrażaniem, o których warto wspomnieć w kontekście badania Zend, jest użycie rozszerzenia xdebug w produkcji. Jak sama nazwa wskazuje, to rozszerzenie służy do debugowania i nie powinno być instalowane w środowisku produkcyjnym. Innym problemem związanym z wdrażaniem jest aktualizowanie wersji PHP. PHP stale poprawia swoją wydajność i dobrym pomysłem jest migracja kodu, aby nadążać za nowymi wersjami PHP.

Wskazówka: Korzystanie z najnowszej wersji PHP to dobry sposób na poprawę wydajności. PHP 7 jest około 30% (w moich testach) szybszy niż PHP 5, a niektórzy twierdzą, że jest jeszcze szybszy. PHP 7.2 jest szybszy niż PHP 7.1.

Rozważając wydajność egzaminu Zend, skupiamy się na zarządzaniu pamięcią i pamięci podręcznej opcode.

Zarządzanie pamięcią

Optymalizacja wydajności pamięci w PHP wymaga pewnego zrozumienia, w jaki sposób działa wewnętrzna reprezentacja danych w języku. PHP używa kontenera o nazwie zval do przechowywania zmiennych. Pojemnik Zval zawiera cztery informacje:

Value : Wartość, na którą ustawiona jest zmienna
Type : Typ danych zmiennej
Is_ref : Wartość logiczna wskazująca, czy ta zmienna jest częścią zestawu referencyjnego. Pamiętaj, że zmienne mogą być przypisywane przez odniesienie. Ta wartość logiczna pomaga PHP zdecydować, czy dana zmienna jest zmienną normalną, czy też jest odwołaniem do innej zmiennej.
Refcount : Jest to licznik, który śledzi, ile nazw zmiennych wskazuje na ten konkretny kontener zval. To przeliczanie jest zwiększane, gdy deklarujemy nową zmienną, która będzie się do niej odwoływała.

Nazwy zmiennych są nazywane symbolami i są przechowywane w tablicy symboli, która jest unikalna dla zakresu, w którym występują zmienne.

Symbole są skierowane na pojemniki zval

W sekcji dotyczącej operatora referencyjnego wspomniałem, że PHP ma optymalizacje do przypisywania według wartości. PHP osiąga to poprzez kopiowanie wartości do nowego zval tylko wtedy, gdy się zmienia, i początkowo kierowanie nowego symbolu do tego samego kontenera zval. Ten mechanizm nazywa się "kopiuj przy zapisie". Oto przykład ilustrujący

< ?php
$a = "new string";
$b =& $a;
// zmienna b wskazuje na zmienną a xdebug_debug_zval( 'a' ); xdebug_debug_zval( 'b' ); // zmień ciąg i sprawdź, czy refcount został zresetowany $b = 'changed string'; xdebug_debug_zval( 'a' ); xdebug_debug_zval( 'b' ); Dane wyjściowe tego skryptu są następujące:: a: (refcount=2, is_ref=0)='new string' b: (refcount=2, is_ref=0)='new string' a: (refcount=1, is_ref=0)='new string' b: (refcount=1, is_ref=0)='changed string' Widzimy, że dopóki nie zmienimy wartości $b, odnosi się to do tego samego kontenera zval, co $a

Tablice i obiekty

Tablice i obiekty używają własnej tabeli symboli, oddzielnej od zmiennych skalarnych. Używają również kontenerów zval, ale utworzenie tablicy lub obiektu spowoduje utworzenie kilku kontenerów. Rozważ ten przykład:

< ?php
$arr = ['name' => 'Bob', 'age' => 23 ];
xdebug_debug_zval( 'arr' );

Dane wyjściowe tego skryptu wyglądają następująco:

arr: (refcount=1, is_ref=0)=array (
'name' => (refcount=1, is_ref=0)='Bob',
'age' => (refcount=1, is_ref=0)=23)

Widzimy, że tworzone są trzy kontenery zval, jeden dla samej zmiennej tablicowej i jeden dla każdej z jej dwóch wartości. Podobnie jak w przypadku zmiennych skalarnych, jeśli mielibyśmy trzeci element tablicy o tej samej wartości co inny element, to zamiast tworzenia nowego kontenera zval PHP zwiększy refcount i wskaże zduplikowany symbol na tym samym zval.

Wycieki pamięci w tablicach i obiektach

Wycieki pamięci mogą wystąpić, gdy obiekt złożony zawiera odniesienie do siebie jako składowej. Jest to bardziej prawdopodobne w przypadkach użycia obiektów, ponieważ PHP zawsze przypisuje obiekty przez referencję. Możliwe, na przykład, w relacjach rodzic-dziecko, takich jak w modelu ORM. Podręcznik PHP zawiera szereg diagramów wyjaśniających to na stronie z podstawami refcountingu. Problem występuje, gdy rozłączysz obiekt złożony, który ma odniesienie do siebie. W tym przypadku tablica symboli jest usuwana z odwołania do struktury zval, która została użyta do przechowywania zmiennej. PHP nie wykonuje iteracji przez obiekt złożony, ponieważ spowodowałoby to rekurencję, ponieważ podąża za linkami do siebie. Oznacza to, że element zmiennej, która jest odwołaniem do siebie, nie jest rozbrojony, a kontener zval nie jest oznaczony jako wolny. Brak symbolu wskazującego na ten pojemnik zval, więc użytkownik nie może samodzielnie zwolnić pamięci. PHP usunie te odniesienia na końcu żądania. Pamiętaj, że PHP nie jest językiem długotrwałym i jest zaprojektowany jako procesor tekstowy zbudowany do obsługi określonych żądań w kontekście aplikacji internetowej.

Garbage Collection

Garbage collector czyści odniesienia cykliczne, które są tymi, w których złożony obiekt zawiera element, który odnosi się do siebie. PHP zainicjuje wyrzucanie elementów bezużytecznych po zapełnieniu bufora głównego lub wywołaniu funkcji gc_collect_cycles(). Garbage collector powoduje spowolnienie tylko wtedy, gdy faktycznie musi coś zrobić. W mniejszych skryptach, w których nie ma wycieków, nie spowoduje to spadku wydajności. Wyrzucanie elementów bezużytecznych może być przydatne w długo działających skryptach lub w tych, w których przeciek pamięci jest wielokrotnie tworzony, na przykład podczas przetwarzania bardzo dużej liczby rekordów bazy danych przy użyciu przeciekających modeli ORM.

Pamięć podręczna kodów operacyjnych

PHP jest kompilowany w sekwencję instrukcji pośrednich, które są wykonywane w kolejności przez silnik wykonawczy. Instrukcje te nazywane są opcoami lub kodami bajtowymi i proces ten zachodzi przy każdym uruchomieniu skryptu. Kod bajtowy jest interpretowany przez silnik środowiska wykonawczego; dlatego PHP jest wstępnie kompilowane i interpretowane. Pamięć podręczna opcode przechowuje przekonwertowane instrukcje dla skryptu. Kolejne wywołania skryptu nie wymagają interpretacji skryptu przed uruchomieniem. W 2013 roku Zend wniósł swój silnik optymalizacji do PHP. Znany jako opcache, jest wtapainy do dystrybucji PHP od wersji 5.5 i jest prawdopodobnie najczęściej używaną pamięcią podręczną opcache PHP.

Uwaga Opcache jest wbudowany w PHP 7.1 i jest domyślnie włączony w ustawieniach php.ini.

Zwróć uwagę na ustawienie opcache.revalidate_freq. Określa to interwał w sekundach, przez które PHP będzie skanować zmiany pliku źródłowego przed jego ponowną kompilacją. Możesz ustawić na 0, aby PHP zawsze skanował w poszukiwaniu zmian. PHP nie skanuje pliku więcej niż raz. Oprócz bufora wbudowanego w PHP, istnieje wiele zewnętrznych buforów opcode

Wskazówka : użycie pamięci podręcznej opcode powoduje znaczny wzrost wydajności

Rozszerzenia

Rozszerzenia PHP rozszerzają funkcjonalność oferowaną przez język podstawowy. Niektóre z nich są domyślnie włączone w standardowe dystrybucje repozytoriów PHP. Inne rozszerzenia należy pobrać i zainstalować ręcznie. PECL to repozytorium rozszerzeń PHP. Zapewnia łatwy sposób pobierania i instalowania rozszerzeń w systemie Linux. Komputery z systemem Windows muszą ręcznie kompilować i instalować rozszerzenia, ale zwykle są one dystrybuowane w skompilowanej formie i wystarczy je edytować, aby je włączyć. PHP zawiera kilka rozszerzeń, których nie można usunąć z PHP za pomocą flag kompilacji. Rozszerzenia te obejmują podstawowe funkcje, takie jak odbicie, tablice, data i godzina, SPL i matematyka. Powinieneś być w stanie polegać na ich instalacji.

Instalowanie rozszerzenia

Rozszerzenia są włączane przez plik php.ini przy użyciu ustawienia "rozszerzenie", aby określić nazwę pliku rozszerzenia, tak jak w przypadku mcrypt:

extension = mcrypt.so;

Możesz ustawić katalog rozszerzenia z ustawieniem w pliku php.ini, takim jak:

extension_dir = "/usr/lib/php5/20121212/mcrypt.so"

Różne systemy mogą zapewniać wygodne sposoby instalowania i włączania rozszerzeń. Rozszerzenia PECL można zainstalować za pomocą narzędzia wiersza polecenia pecl.

Sprawdzanie zainstalowanych rozszerzeń

Zainstalowane rozszerzenia będą wyświetlane, jeśli wywołasz phpinfo() lub użyjesz bardziej szczegółowej komendy get_loaded_extensions(). Uruchomienie php -m z powłoki wyświetli listę zainstalowanych rozszerzeń. Możesz sprawdzić, czy rozszerzenie jest załadowane, wywołując extension_loaded(). To jest zalecane, jeśli używasz funkcji w rozszerzeniu, które nie jest domyślnie ładowane. Oto przykład z podręcznika PHP:

< ?php
if (!extension_loaded('gd')) {
if (!dl('gd.so')) {
exit;
}
}



QUIZ



P1: Którego z poniższych tagów należy unikać, aby dołączyć PHP do HTML?

< ?
< ?=
Żadne z powyższych; wszystko w porządku

P2: Które z poniższych NIE uwzględniają wielkości liter w PHP? Wybierz wszystkie, które dotyczą?

Nazwy zmiennych
Nazwy klas
Przestrzenie nazw
Nazwy funkcji

P3: Co wygeneruje ten skrypt?

< ?php
$a = "Hello";
$B = " world";
ECHO $a . $b;

---------------

Nic; nie uruchomi się
Hello world
Hello
Komunikat o błędzie, ponieważ zmienna b nie jest zdefiniowana
Komunikat o błędzie i słowo "Hello"

P4: Co wygeneruje ten skrypt?

< ?php
function A() {
try {
b());
} catch (Exception $e) {
echo "Exception caught in " . __CLASS__;
}
}
function B() {
C(); }
try {
A();
} catch (Error $e) {
echo "Error caught in global scope: " . $e->getMessage();
}

-----------

Wyjątek wykryty w punkcie A.
Błąd wychwycony w zasięgu globalnym: wywołanie niezdefiniowanej funkcji C ()
Błąd wychwycony w zasięgu globalnym: Wywołanie niezdefiniowanej funkcji b ()
Żadne z powyższych

P5: Co wygeneruje ten skrypt?

< ?php
function A() {
try {
b();
} catch (Exception $e) {
echo "Exception caught in " . __CLASS__;
}
}
function B() {
echo 5 / "five";
}
try {
A();
} catch (Error $e) {
echo "Error caught in global scope: " . $e->getMessage();
}

--------

Wyjątek wykryty w punkcie A.
Błąd wychwycony w zasięgu globalnym: wywołanie niezdefiniowanej funkcji C()
1
Błąd wychwycony w zasięgu globalnym: Wywołanie niezdefiniowanej funkcji b()
Żadne z powyższych

P6: Co wygeneruje ten skrypt?

< ?php
class MyException extends Exception {}
class ChildException extends MyException {}
try {
throw new ChildException;
} catch (Exception $e) {
echo "Caught Exception: " . get_class($e);
} catch (MyException $e) {
echo "Caught MyException" . get_class($e);
}

--------

Caught Exception: ChildException
Caught MyException: ChildException
Caught MyException: MyException
Nic
Komunikat o błędzie związany z nieprzechwyconym wyjątkiem

P7: Które z poniższych ustawień można skonfigurować w czasie wykonywania za pomocą funkcji ini_set ()?

output_buffering
memory_limit
max_execution_time
extension

P8: Jakie są wyniki tego skryptu?

< ?php
$a = "apples" ⇔ "bananas";
$b = $a ?? $c ?? 10;
echo $b;

--------

-1
0
1
10
jabłka

P9: Jaka jest wynik tego skryptu?

echo 10 ⇔ 10 << 1;

---------

-1
0
1
10

P10: Jakie są wyniki tego skryptu?

< ?php
define('A', 1);
const B = 2;
define('C', [A * A, B * B]);
echo(C[1]);

-------

To wygeneruje błąd, ponieważ stałe mogą przechowywać tylko wartości skalarne.
Spowoduje to wygenerowanie błędu, ponieważ nie można użyć funkcji replace () do zadeklarowania stałej tablicy.
To wygeneruje błąd, ponieważ nie można używać wyrażeń ani funkcji podczas deklarowania stałej.
1
2
4


ODPOWIEDZI



• Żadne z powyższych; wszystko w porządku

• Nazwy klas - Nazwy funkcji

• Hello

•  Żadne z powyższych

• Caught Exception: ChildException

•  memory_limit - max_execution_time

•  -1

•  -1

•  4