Ostatnie dyskusje język PHP Habré sprowadza się bardziej do umiejętności projektowania złożonych systemów, co jest dobrą wiadomością. Jednak po przejrzeniu kilkunastu najbardziej rozpoznawalnych frameworków internetowych (Zend Framework, Adept, CakePHP, CodeIgniter, LIMB, Symfony, MZZ i innych), byłem naprawdę zaskoczony, gdy znalazłem kilka znaczących niedociągnięć w zakresie elementarnej optymalizacji.

Aby uczynić ten temat bardziej zorientowanym technicznie, wyniki są prezentowane w bardziej ścisłej formie, co może nieco utrudniać zrozumienie.

A więc chodźmy... Zadanie jest niezwykle proste: przeprowadzić eksperymenty dotyczące szybkości tworzenia ciągów z podciągów w pojedynczych i podwójnych cudzysłowach. W zasadzie to pytanie będzie nadal aktualne przez długi czas ze względu na specyfikę przetwarzania ciągów w PHP.

Istnieje wiele artykułów na temat podstawowej optymalizacji skryptów zarówno w języku rosyjskim, jak iw innych językach. Niewiele mówi się o ciągach, ale odnotowany jest fakt „parsowania” ciągów w podwójnych cudzysłowach dla zmiennych i znaków sterujących (jednak jak w oficjalnej dokumentacji). Na tej podstawie logiczne jest założenie, że używanie w pracy ciągów w cudzysłowie będzie nieco wolniejsze niż te same operacje z podciągami w cudzysłowie.

Oprócz podstawiania zmiennych na łańcuchy i łączenia zmiennych z podłańcuchami, PHP implementuje co najmniej jeszcze jeden sposób tworzenia łańcuchów: za pomocą funkcji sprintf. Logiczne jest założenie, że Ta metoda będą znacznie gorsze od "standardowych" ze względu na dodatkowe wywołanie funkcji i parsowanie linii wewnątrz.

Jedyny dodatek, zanim przedstawię Wam kod skryptu testowego: należy rozważyć 2 możliwe opcje praca z łańcuchami w podwójnych cudzysłowach: biorąc pod uwagę prosty i "zaawansowany" styl kodowania. To, że zmienne znajdują się na samym początku wierszy, nie jest chyba warte uwagi – to tylko przykłady:
$string = "$_SERVER["HTTP_HOST"] nie jest administracją regionu Uljanowsk. Kochamy język rosyjski i nie lubimy tych, którzy nim mówią..."
oraz
$string = "($_SERVER["HTTP_HOST"]) nie jest administracją regionu Uljanowsk. Kochamy język rosyjski i nie lubimy tych, którzy nim mówią..."

Test numer jeden.
Otóż ​​wygląda na to, że wszystkie zastrzeżenia zostały poczynione - czas pokazać efekty pracy. Źródło tester można znaleźć.

Zrzuty ekranu pokazują, że moja hipoteza nie została potwierdzona. Założenie o pracy ze strunami poprzez sprintf okazało się jedynym słusznym. Najszybsze były funkcje, z którymi współpracują podwójne cudzysłowy.

Po krótkiej refleksji nad sytuacją, wyjaśnienie przyszło samo: chodzi o to, że ciąg referencji, w którym dokonano podstawień, jest za krótki: parser przechodzący przez taki ciąg to drobiazg. Jednak nawet tutaj jest jasne, że natywne podstawienie zmiennej do łańcucha daje przewagę nad „stylem zaawansowanym”.
Jest to również słabość podejścia konkatenacyjnego: objętość wstawianych danych przekracza objętość podciągów. Skąd pochodzą koszty ogólne można przeczytać we wspomnianym już habratopiku.

Jednak nawet te myśli wymagały potwierdzenia. W tym celu potrzebny był drugi test ze zmianami w możliwych przyczynach wspomnianych dla takiego nieprzewidywalnego (dla mnie) zachowania. Podobno wiele rzeczy zostało poprawionych w piątej wersji (przyznaję, że w piątej wersji php przeprowadziłem tylko 1 test: by ominąć elementy tablicy).

Test numer dwa.
Druga hipoteza jest taka, że ​​wydłużenie ciągu referencyjnego ostatecznie zwiększy odsetek funkcji testera związanych z tworzeniem ciągów w cudzysłowach w stosunku do wyników testu nr 1. Teoretycznie tę samą sytuację należy zaobserwować w odniesieniu do operacji funkcji sprintf. Wynika to przede wszystkim z konieczności parsowania ciągów i wydłużenia czasu na to poświęconego. W sytuacji konkatenacji podciągów w pojedyncze cudzysłowy myślę, że wynik będzie w przybliżeniu taki sam jak w pierwszym teście, co da nieznaczny spadek proporcji czasu wykonania funkcji quotes_3() o czas całego skryptu (ale nie wzrost wydajności).

Wnioski w rzeczywistości tylko pozytywne i potwierdzające hipotezę. Nieznaczne zwiększenie ciągu referencyjnego powoduje duże obciążenie, co prowadzi do spadku wydajności funkcji podwójnych cudzysłowów i funkcji sprintf.

Założenie o ciągach w pojedynczych cudzysłowach również okazało się poprawne: zamiast 36,75% czasu w pierwszym teście, w drugim funkcja quotes_3() zajęła 33,76% czasu wykonania skryptu

wartość praktyczna.
W uproszczeniu, abstrahując od danych, możemy stwierdzić: co dłuższy sznurek, w którym konieczne jest wykonanie podstawienia, tym większe prawdopodobieństwo, że operacja konkatenacji zakończy się szybciej niż wyszukiwanie zmiennej w cudzysłowie. Chętni mogą spróbować dobrać niezbędne parametry wstawiania (liczba zmiennych, długość ciągu referencyjnego, długości ciągów znaków w zmiennych) tak, aby spełniały równość czasów wykonania.

To w rzeczywistości wszystko. Pozostaje tylko dodać, że w programowaniu nie ma drobiazgów (to dla tych, którzy lubią mówić „oszczędzanie na meczach” (c) Adelf). Znając takie subtelności i uwzględniając je, możesz napisać kod, który będzie zoptymalizowany na wszystkich jego poziomach ;)

PS:
Testy wykonane przy użyciu Zend Studio For Eclipse 6.0.0 (w tym Debuger + Profiler).
Wersja PHP 5.2.5
System operacyjny Debian Linux

PPS:
Byłbym zadowolony, gdyby ktoś zamieścił swoje wyniki tych badań. Myślę, że pozwoli to na bardziej obiektywną ocenę konieczności zastosowania takiej czy innej metody podstawiania na struny. Byłbym też wdzięczny za zdrową krytykę stylu prezentacji i designu.

(PHP 4, PHP 5, PHP 7)

str_replace- Zastępuje wszystkie wystąpienia szukanego ciągu ciągiem zastępczym

Opis

Ta funkcja zwraca ciąg lub tablicę ze wszystkimi wystąpieniami wyszukiwania w temacie zastąpionymi przez replace .

Ta funkcja jest preferowana, jeśli nie potrzebujesz złożonych reguł znajdowania/zamieniania (takich jak wyrażenia regularne). preg_replace().

Lista parametrów

Jeśli wyszukiwanie i zamiana są tablicami, to str_replace() używa każdej wartości z odpowiedniej tablicy do wyszukiwania i zamiany w temacie . Jeśli w tablicy replace jest mniej elementów niż w search , pusty ciąg zostanie użyty jako ciąg zastępczy dla pozostałych wartości. Jeśli search jest tablicą, a replace jest ciągiem, to ten ciąg zastępczy zostanie użyty dla każdego elementu tablicy wyszukiwania. Odwrotny przypadek nie ma sensu.

Jeśli search lub replace są tablicami, ich elementy będą przetwarzane od pierwszego do ostatniego.

Wartość, której szukasz, znana również jako igła(igła). Możesz użyć tablicy dla wielu wartości wyszukiwania.

Zastępować

Wartość zastępcza zostanie użyta do zastąpienia wyszukiwanych wartości. Możesz użyć tablicy dla wielu wartości.

Temat

Ciąg lub tablica do przeszukania i zastąpienia, znany również jako stóg siana(stos siana).

Jeśli podmiot jest tablicą, to wyszukiwanie i zamiana zostanie wykonane na każdym elemencie podmiotu, a wynikiem funkcji będzie również tablica.

Jeśli przejdzie, zostanie ustawiony na liczbę wykonanych wymian.

Zwracane wartości

Ta funkcja zwraca ciąg lub tablicę z podmienionymi wartościami.

Przykłady

Przykład #1 Przykłady użycia str_replace()

// przypisuje
$bodytag = str_replace("%body%" , "czarny" , " " );

// przypisz: Hll Wrld f PHP
$vowels = array("a" , "e" , "i" , "o" , "u" , "A" , "E" , "I" , "O" , "U" );
$onlyconsonants = str_replace ($vowels , "" , "Hello World of PHP" );

// przypis: Powinnaś codziennie jeść pizzę, piwo i lody
$fraza = „Powinieneś codziennie jeść owoce, warzywa i błonnik”.;
$zdrowy = array("owoce" , "warzywa" , "błonnik" );
$yummy = array("pizza" , "piwo" , "lody" );

$nowafraza = str_replace ($zdrowy , $pyszny , $fraza );

// przypisz: 2
$str = str_replace ("ll" , "" , "dobra panienko Molly!" , $count );
echo $liczba ;
?>

Przykład #2 Przykłady potencjalnych sztuczek z str_replace()

// Zamówienie na wymianę
$str = "Linia 1\nLinia 2\rLinia 3\r\nLinia 4\n";
$order = array("\r\n" , "\n" , "\r" );
$zamień = "
" ;

// Najpierw obsługuje \r\n, aby uniknąć ich ponownego zastępowania.
echo $newstr = str_replace ($order , $replace , $str );

// Wyprowadza F, ponieważ A zostaje zastąpione przez B, następnie B przez C i tak dalej...
// W rezultacie E zostanie zastąpione przez F, ponieważ zastąpienie następuje od lewej do prawej.
$search = array("A" , "B" , "C" , "D" , "E" );
$replace = array("B" , "C" , "D" , "E" , "F" );
$temat = "A" ;
echo str_replace ($search , $replace , $subject );

// Wyjścia: jabłko, orzech, orzech (z powyższego powodu)
$litery = tablica("I" , "o" );
$owoc = tablica("jabłko" , "orzech" );
$text = "Jestem o" ;
$wyjście = str_replace ($litery , $owoce , $tekst );
echo $wyjście ;
?>

Uwagi

Komentarz: Ta funkcja jest bezpieczna do obsługi danych w postaci binarnej.

Ostrzeżenie

Uwaga dotycząca zamówienia wymiany

Dlatego str_replace() zastępuje od lewej do prawej, a następnie przy użyciu wielu zamienników może zastąpić poprzednio wstawioną wartość inną. Zobacz także przykłady na tej stronie.

Komentarz:

Ta funkcja rozróżnia wielkość liter. Posługiwać się str_place() do wymiany bez rozróżniania wielkości liter.

Komentarz: W PHP 7.0.0 na platformach 64-bitowych nie ma osiągalnego limitu długości ciągu, w systemach 32-bitowych i wcześniejszych wersjach PHP ciągi nie mogą być większe niż 2 GB (2147483647 bajtów).

Składnia

Ciąg można zdefiniować za pomocą czterech różne sposoby:

  • pojedyncze cytaty
  • podwójne cudzysłowy
  • Składnia nowdoc (od PHP 5.3.0)

Pojedyncze cytaty

Najprostszy sposób zdefiniowanie ciągu oznacza ujęcie go w pojedynczych cudzysłowach (symbol " ).

Aby użyć pojedynczego cudzysłowu w ciągu, skoryguj go odwrotnym ukośnikiem ( \ ). Jeśli chcesz napisać sam ukośnik odwrotny, zduplikuj go ( \\ ). Wszystkie inne odwrotne ukośniki będą interpretowane jako zwykłe znaki, co oznacza, że ​​jeśli spróbujesz użyć innych sekwencji specjalnych, takich jak \r lub \n, będą one wyprowadzane tak, jak są, zamiast specjalnego zachowania.

Echo „to jest prosty ciąg”;

Echo "Można też wstawiać do wierszy
znak nowej linii taki jak ten,
to normalne"
;

// Wyniki: Pewnego dnia Arnold powiedział: „Wrócę”
Echo "Pewnego dnia Arnold powiedział: "Wrócę"";

Echo "Czy usunąłeś C:\\*.*?";

// Dane wyjściowe: Czy usunąłeś C:\*.*?
echo "Czy usunąłeś C:\*.*?" ;

// Dane wyjściowe: To nie zostanie rozwinięte: \n nowa linia
Echo "To się nie rozwinie: \n nowa linia";

// Wyświetla: zmienne $expand również nie są rozwijane przez $either
Echo "Zmienne $rozwiń również $albo nie są rozwijane";
?>

Podwójne cytaty

Jeśli ciąg jest ujęty w cudzysłów ("), PHP rozpoznaje następujące sekwencje specjalne znaków specjalnych:

Sekwencje ewakuacyjne
Podciąg Oznaczający
\n znak nowej linii (LF lub 0x0A (10) w ASCII)
\r powrót karetki (CR lub 0x0D (13) w ASCII)
\t zakładka pozioma (HT lub 0x09 (9) w ASCII)
\v zakładka pionowa (VT lub 0x0B (11) w ASCII) (od PHP 5.2.5)
\mi znak ucieczki (ESC lub 0x1B(27) w ASCII) (od PHP 5.4.4)
\f kanał strony (FF lub 0x0C (12) w ASCII) (od PHP 5.2.5)
\\ ukośnik wsteczny
\$ znak dolara
\" cudzysłów
\{1,3} sekwencja znaków pasująca do wyrażenia regularnego znaku w postaci ósemkowej, która po cichu przepełnia się, aby zmieścić się w bajcie (np. "\400" === "\000")
\x(1,2) sekwencja znaków, która odpowiada wyrażeniu regularnemu znaku w systemie szesnastkowym
\u(+) sekwencja znaków pasująca do wyrażenia regularnego znaku Unicode, która odwzorowuje łańcuch w reprezentacji UTF-8 (dodana w PHP 7.0.0)

Podobnie jak w przypadku łańcucha ujętego w pojedyncze cudzysłowy, zmiana znaczenia dowolnego znaku spowoduje również wydrukowanie samego znaku zmiany znaczenia. Przed PHP 5.1.1 ukośnik odwrotny w \($zmienna) nie drukowane.

Heredoc

Trzecim sposobem definiowania łańcuchów jest użycie składni heredoc: <<< . Po tej instrukcji musisz podać identyfikator, a następnie znak nowej linii. Po tym następuje sama linia, a następnie ten sam identyfikator, który zamyka wstawkę.

Linia musi zacznij od identyfikatora zamykającego, tj. powinien znajdować się w pierwszej kolumnie wiersza. Ponadto identyfikator musi być zgodny z tą samą konwencją nazewnictwa, co wszystkie inne znaczniki PHP: zawierać tylko znaki alfanumeryczne i podkreślenia i nie może zaczynać się od cyfry (podkreślenia są dozwolone).

Uwaga

Bardzo ważne jest, aby pamiętać, że ciąg z identyfikatorem zamykającym nie może zawierać innych znaków poza średnikiem ( ; ). Oznacza to, że identyfikator nie może być wcięty i że nie może być żadnych spacji ani tabulatorów przed ani po średniku. Ważne jest również, aby zrozumieć, że pierwszy znak przed identyfikatorem zamykającym musi być znakiem nowej linii, zgodnie z definicją w systemie operacyjnym. Na przykład w systemach UNIX, w tym macOS, jest to \n. Bezpośrednio po identyfikatorze zamykającym musi znajdować się znak nowej linii.

Jeśli ta reguła jest naruszona, a identyfikator zamykający nie jest „czysty”, uważa się, że nie ma identyfikatora zamykającego i PHP będzie kontynuować jego wyszukiwanie. Jeśli w tym przypadku nigdy nie zostanie znaleziony prawidłowy identyfikator zamknięcia, spowoduje to błąd parsowania z numerem wiersza na końcu skryptu.

Beispiel #1 Przykład nieprawidłowej składni

klasa foo (
publiczny $bar =<<bar
EOT;
// dopełnienie przed identyfikatorem zamykającym jest niedozwolone
}
?>

Beispiel #2 Przykład poprawnej składni

klasa foo (
publiczny $bar =<<bar
EOT;
}
?>

Heredoc nie może być używany do inicjowania pól klas. Od PHP 5.3 to ograniczenie dotyczy tylko dokumentów heredoc, które zawierają w sobie zmienne.

Tekst Heredoc zachowuje się tak samo, jak łańcuch w cudzysłowie, bez ich posiadania. Oznacza to, że nie musisz uciekać się do cudzysłowów w dokumencie heredoc, ale nadal możesz używać powyższych sekwencji ucieczki. Obsługiwane są zmienne, ale musisz być tak samo ostrożny używając złożonych zmiennych wewnątrz heredoc jak podczas pracy z łańcuchami.

Beispiel #3 przykład definicji ciągu znaków heredoc

$str =<<Przykład linii,
obejmujących wiele linii
używając składni heredoc.
EOD;

Klasa
{
var $foo ;
var $bar ;

Funkcja __construct()
{
$this -> foo = "foo" ;
$to ->
}
}

$foo = newfoo();
$nazwa = "Nazwa" ;

Echo<<Nazywam się „ $imię ”. wpisuję $foo -> foo .
Teraz wynoszę
( $foo -> bar [1]) .
Powinno to spowodować wyświetlenie wielkiej litery „A”: \x41
EOT;
?>

Nazywam się "Imię". Piszę Foo. Teraz wyprowadzam Bar2. Powinno to spowodować wyświetlenie wielkiej litery „A”: A

Możliwe jest również użycie składni heredoc do przekazywania danych przez argumenty funkcji:

Od wersji 5.3.0 stało się możliwe inicjowanie zmiennych statycznych i właściwości/stałych klas przy użyciu składni heredoc:

Beispiel #5 Używanie heredoc do inicjalizacji zmiennych statycznych

// Zmienne statyczne
functionfoo()
{
statyczny $bar =<<Tu nic nie ma...
etykieta;
}

// Stałe/właściwości klas
klasa
{
const BAR =<<Przykład użycia stałej
FOOBAR;

Publiczna $podstawa =<<Przykład użycia w terenie
FOOBAR;
}
?>

Od PHP 5.3.0 możliwe jest również otoczenie identyfikatora Heredoc podwójnymi cudzysłowami:

Nowdoc

Nowdoc jest taki sam dla ciągów w pojedynczym cudzysłowie, jak heredoc dla ciągów w cudzysłowie podwójnym. Nowdoc jest podobny do heredoc, ale w środku nie dokonuje się żadnych zastępstw. Ta konstrukcja jest idealna do osadzania kodu PHP lub innych dużych bloków tekstu bez konieczności ucieczki. Pod tym względem jest trochę podobny do konstrukcji SGML. deklarując blok tekstu, który nie jest przeznaczony do przetwarzania.

Nowdoc jest oznaczony tą samą sekwencją <<< , który jest używany w dokumencie heredoc, ale następujący po nim identyfikator jest ujęty w pojedyncze cudzysłowy, na przykład <<<"EOT" . Wszystkie warunki, które mają zastosowanie do identyfikatorów heredoc dotyczą również nowdoc, zwłaszcza te, które dotyczą identyfikatora zamykającego.

Beispiel #7 przykład nowdoc

Echo<<<"EOD"
przykład tekstu,
obejmujących wiele linii
używając składni nowdoc. Odwrotne ukośniki są zawsze traktowane dosłownie,
na przykład \\ i \".
EOD;

Wynik uruchomienia tego przykładu:

Przykład tekstu obejmującego wiele wierszy przy użyciu składni nowdoc. Ukośniki odwrotne są zawsze traktowane dosłownie, jak \\ i \".

Przykład #8 Przykład cytowania łańcucha Nowdoc ze zmiennymi

/* Bardziej złożony przykład ze zmiennymi. */
klasa
{
publiczne $foo ;
publiczny $bar ;

Funkcja __construct()
{
$this -> foo = "foo" ;
$this -> bar = array("Bar1" , "Bar2" , "Bar3" );
}
}

$foo = newfoo();
$nazwa = "Nazwa" ;

Echo<<<"EOT"
Nazywam się „$nazwa”. Wpisuję $foo->foo.
Teraz piszę ($foo->bar).
To nie powinno generować dużej litery „A”: \x41
EOT;
?>

Wynik uruchomienia tego przykładu:

Nazywam się „$nazwa”. Wpisuję $foo->foo. Teraz piszę ($foo->bar). To nie powinno generować dużej litery „A”: \x41

Przykład #9 Przykład danych statycznych

klasa foo (
publiczny $bar =<<<"EOT"
bar
EOT;
}
?>

Komentarz:

wsparcie nowdoc zostało dodane w PHP 5.3.0.

Zmienne przetwarzania

Jeśli ciąg jest określony w cudzysłowie lub w heredoc, przetwarzane są zmienne w nim zawarte.

Istnieją dwa rodzaje składni: prosta i złożona. Prosta składnia jest łatwiejsza i wygodniejsza. Umożliwia przetwarzanie zmiennej, wartości tablicy ( szyk) lub właściwości obiektu ( obiekt) przy minimalnym wysiłku.

Złożoną składnię można rozpoznać po nawiasach klamrowych otaczających wyrażenie.

Prosta składnia

Jeśli tłumacz napotka znak dolara ( $ ), przechwytuje jak najwięcej znaków, aby utworzyć poprawną nazwę zmiennej. Jeśli chcesz określić koniec nazwy, umieść nazwę zmiennej w nawiasach klamrowych.

$sok = "jabłko" ;

echo "Wypił trochę soku z soku." . PHP_EOL ;

// Nieprawidłowo. "s" jest poprawnym znakiem nazwy zmiennej, ale nazwa zmiennej to $sok.
echo "Wypił sok z $soków ." ;

// Prawidłowy. Koniec nazwy zmiennej jest ściśle określony w nawiasach:
echo "Wypił trochę soku z $(soku) s." ;
?>

Wynik uruchomienia tego przykładu:

Wypił sok jabłkowy. Wypił trochę soku z niego. Napił się soku z jabłek.

Element tablicy ( szyk) lub właściwość obiektu ( obiekt). W indeksach tablicowych zamykający nawias kwadratowy ( ] ) oznacza koniec definicji indeksu. Te same zasady odnoszą się do właściwości obiektów, jak do prostych zmiennych.

Przykład #10 Prosty przykład składni

define("KOOLAID" , "koolaid1" );
$soki = array("jabłko" , "pomarańcza" , "koolaid1" => "fioletowy" );

echo "Wypił trochę soku $soki [ 0 ]." . PHP_EOL ;
echo "Wypił trochę soku $sok [ 1 ] sok." . PHP_EOL ;
echo "Wypił trochę soku $sok [ koolaid1 ]." . PHP_EOL ;

klasa ludzie (
publiczny $jan = "Jan Kowalski" ;
public $jane = "Jane Kowalski" ;
publiczny $robert = "Robert Paulsen" ;

Publiczny $kowalski = "Kowalski" ;
}

$ludzie = nowi ludzie();

echo " $ludzie -> John wypił trochę $soku [ 0 ] sok." . PHP_EOL ;
echo " $ludzie -> jan przywitał się z $ludźmi -> jane ." . PHP_EOL ;
echo " $ludzie -> żona Jana przywitała $ludzie -> robert." .PHP_EOL ;
echo " $ludzie -> Robert przywitał dwóch $ludzi -> kowale ." ; // Nie działa
?>

Wynik uruchomienia tego przykładu:

Wypił sok jabłkowy. Napił się soku pomarańczowego. Wypił trochę fioletowego soku. John Smith wypił trochę soku jabłkowego. Następnie John Smith przywitał się z Jane Smith. Żona Johna Smitha przywitała Roberta Paulsena, Robert Paulsen pozdrowił ich dwoje.

Dodano obsługę PHP 7.1.0 negatywny indeksy numeryczne.

Przykład #11 Ujemne indeksy liczbowe

$ciąg = "ciąg" ;
Echo „Znak w indeksie -2 to$string [- 2 ].", PHP_EOL;
$string [- 3 ] = "o" ;
Echo „Zmiana znaku w pozycji -3 na „o” daje następujący wiersz:$string.", PHP_EOL;
?>

Wynik uruchomienia tego przykładu:

Znak z indeksem -2 to n. Zmiana znaku na pozycji -3 na "o" daje następujący ciąg: strong

W przypadku czegoś bardziej złożonego użyj złożonej składni.

Składnia złożona (kręcona)

Nazywa się to złożonym nie dlatego, że jest trudny do zrozumienia, ale dlatego, że pozwala na użycie złożonych wyrażeń.

Każda zmienna skalarna, element tablicy lub właściwość obiektu, która jest mapowana na ciąg, może być reprezentowana w ciągu za pomocą tej składni. Po prostu napisz wyrażenie tak, jak byś pisał poza ciągiem, a następnie zamknij je w { oraz } . Ponieważ { nie można uciec, ta składnia zostanie rozpoznana tylko wtedy, gdy $ następuje bezpośrednio po { . Posługiwać się {\$ drukować {$ . Kilka ilustrujących przykładów:

// Pokaż wszystkie błędy
raportowanie_błędów(E_ALL);

$świetnie = "świetnie" ;

// Nie działa, wyjścia: To (świetnie)
echo "To jest ($świetnie)" ;

// Działa, wyniki: To jest świetne
echo "To jest ($świetnie)" ;

// Pracuje
Echo „Ten kwadrat jest szeroki($kwadrat -> szerokość) 00 centymetrów.";

// Działa, klucze w cudzysłowie działają tylko ze składnią nawiasów klamrowych
echo "To działa: ( $arr [ "klucz" ]) " ;

// Pracuje
echo "To działa: ( $arr [ 4 ][ 3 ]) " ;

// To jest złe z tego samego powodu, dla którego $foo jest na zewnątrz
// linie. Innymi słowy, nadal będzie działać
// ale ponieważ PHP najpierw szuka stałej foo, wywoła
// Błąd poziomu E_NOTICE (niezdefiniowana stała).
Echo "To nie jest właściwe:( $arr [ foo ][ 3 ] ) " ;

// Pracuje. Podczas korzystania z wielowymiarowych tablic wewnątrz
// napisy zawsze używają nawiasów klamrowych
echo "To działa: ( $arr [ "foo" ][ 3 ]) " ;

// Pracuje.
echo "To działa: " . $arr [ "foo" ][ 3 ];

Echo „Działa to również:($obj -> wartości [3]-> nazwa)";

Echo „To jest wartość zmiennej o nazwie$nazwa : ($( $nazwa )) " ;

Echo „To jest wartość zmiennej według nazwy, która jest zwracana przez funkcję getName():($( pobierzNazwę ())) ";

Echo "To jest wartość zmiennej według nazwy zwrócona przez \$object->getName():($( $obiekt -> pobierzNazwę ())) " ;

// Nie działa, dane wyjściowe: To właśnie zwraca getName(): (getName())
Echo "Oto co zwraca getName(): (getName())";
?>

Za pomocą tej składni można również uzyskać dostęp do właściwości obiektu w ciągach znaków.

klasa foo (
var $bar = "Jestem barem." ;
}

$foo = newfoo();
$bar = "bar" ;
$baz = array("foo" , "bar" , "baz" , "quux" );
echo " ( $foo -> $bar ) \n" ;
echo "( $foo ->( $baz [1])) \n" ;
?>

Wynik uruchomienia tego przykładu:

Jestem barem. Jestem barem.

Komentarz:

Funkcje, wywołania metod, statyczne zmienne klas i stałe klas działają wewnętrznie {$} , zaczynając od PHP 5. Jednak podana wartość będzie traktowana jako nazwa zmiennej w tym samym kontekście, co łańcuch, w którym jest zdefiniowany. Używanie pojedynczych nawiasów klamrowych ( {} ) nie będzie działać w przypadku dostępu do wartości funkcji, metod, stałych klas lub statycznych zmiennych klas.

// Pokaż wszystkie błędy
raportowanie_błędów(E_ALL);

piwa klasowe (
const napój bezalkoholowy = "piwo korzenne" ;
public static $ale = "ipa" ;
}

$rootbeer = "A & W" ;
$ipa = "Aleksander Keith\"s" ;

// To działa, wyjścia: chciałbym A & W
echo "Chciałbym ($( piwo :: napój bezalkoholowy )) \n" ;

// To też działa, wyjścia: chciałbym Aleksandra Keitha
echo "Chciałbym ($(piwa ​​:: $ale )) \n" ;
?>

Dostęp do znaku w ciągu i zmiana go

Znaków w łańcuchach można używać i modyfikować, określając ich przesunięcie od początku ciągu, zaczynając od zera, w nawiasach kwadratowych po ciągu, na przykład $str . Pomyśl o łańcuchu w tym celu jako o tablicy znaków. Jeśli potrzebujesz uzyskać lub zastąpić więcej niż 1 znak, możesz użyć funkcji substr() oraz substr_replace().

Komentarz: od PHP 7.1.0 obsługiwane są ujemne wartości przesunięcia. Ustawiają przesunięcie od końca ciągu. Wcześniej ujemne przesunięcia powodowały błąd poziomu E_NOTICE podczas czytania (zwracając pusty ciąg) lub E_OSTRZEŻENIE przy zapisie (pozostawiając ciąg bez zmian).

Komentarz: Dostęp do znaku w ciągu można również uzyskać za pomocą nawiasów klamrowych, takich jak $str(42) .

Uwaga

Próba zapisu do przesunięcia poza ciągiem spowoduje wypełnienie ciągu spacjami aż do tego przesunięcia. Typy niecałkowite zostaną przekonwertowane na liczby całkowite. Nieprawidłowy typ przesunięcia spowoduje błąd poziomu E_OSTRZEŻENIE. Używany jest tylko pierwszy znak przypisanego ciągu. Od PHP 7.1.0 przypisanie pustego ciągu spowoduje błąd krytyczny. Wcześniej w tym przypadku przypisywano bajt null (NULL).

Uwaga

Łańcuchy w PHP są wewnętrznie tablicami bajtów. W rezultacie dostęp lub modyfikowanie ciągu przez przesunięcie nie jest bezpieczne dla wielu bajtów i powinno być wykonywane tylko za pomocą ciągów w kodowaniu jednobajtowym, takim jak ISO-8859-1.

Komentarz: Od PHP 7.1.0 użycie pustego indeksu powoduje błąd krytyczny, wcześniej w takim przypadku ciąg był konwertowany na tablicę bez ostrzeżenia.

Przykład #12 Kilka przykładowych ciągów

// Pobierz pierwszy znak ciągu
$str = "To jest test." ;
$pierwszy = $str [ 0 ];

// Pobierz trzeci znak ciągu
$trzecia = $str [ 2 ];

// Pobierz ostatni znak ciągu
$str = "To wciąż jest test." ;
$ostatni = $str [ strlen($str )- 1 ];

// Zmień ostatni znak ciągu
$str = "Spójrz na morze" ;
$str [ strlen ($str )- 1 ] = "e" ;

?>

Od PHP 5.4 przesunięcie w łańcuchu musi być liczbą całkowitą lub łańcuchem zawierającym liczby, w przeciwnym razie zostanie wyświetlone ostrzeżenie. Wcześniej offset podany przez ciąg znaków, taki jak "bla", bez ostrzeżenia został przekonwertowany na 0 .

Przykład #13 Różnice między PHP 5.3 a PHP 5.4

$str = "abc" ;

Var_dump($str["1"]);
var_dump (isset($str [ "1" ]));

Var_dump($str[ "1.0" ]);
var_dump (isset($str [ "1.0" ]));

Var_dump($str["x"]);
var_dump (isset($str [ "x" ]));

Var_dump($str[ "1x" ]);
var_dump (isset($str [ "1x" ]));
?>

Wynikiem uruchomienia tego przykładu w PHP 5.3 jest:

string(1) "b" bool(true) string(1) "b" bool(true) string(1) "a" bool(true) string(1) "b" bool(true)

Wynikiem uruchomienia tego przykładu w PHP 5.4 jest:

string(1) "b" bool(true) Ostrzeżenie: Niedozwolone przesunięcie "1.0" w /tmp/t.php w wierszu 7 string(1) "b" bool(false) Ostrzeżenie: Niedozwolone przesunięcie "x" w / tmp/t.php w wierszu 9 string(1) "a" bool(false) string(1) "b" bool(false)

Komentarz:

Próba uzyskania dostępu do zmiennych innych typów (z wyłączeniem tablic lub obiektów implementujących określone interfejsy) za pomocą lub {} po cichu wróć ZERO.

Komentarz:

PHP 5.5 dodało obsługę dostępu do znaków w literałach łańcuchowych za pomocą składni lub {} .

Istnieje wiele przydatnych funkcji do modyfikowania ciągów.

Główne funkcje są opisane w sekcji dotyczącej funkcji ciągów, a dla zaawansowanych funkcji wyszukiwania i zamiany funkcje wyrażeń regularnych zgodne z Perlem.

Konwertuj na ciąg

Wartość można przekonwertować na ciąg znaków za pomocą rzutowania (strunowy) lub funkcje strval(). W wyrażeniach, w których potrzebny jest ciąg, konwersja następuje automatycznie. Dzieje się tak, gdy używasz funkcji Echo lub wydrukować lub gdy wartość zmiennej jest porównywana z ciągiem. Zapoznanie się z rozdziałami podręcznika Typy i Manipulacja Typami sprawi, że poniższe informacje będą bardziej zrozumiałe. Zobacz też typ zestawu().

Tablice są zawsze konwertowane na ciąg "szyk", więc nie można wyświetlić zawartości tablicy ( szyk) za pomocą Echo lub wydrukować aby zobaczyć, co zawiera. Aby wyświetlić pojedynczy element, użyj czegoś takiego: echo $arr["foo"]. Poniżej znajdziesz wskazówki dotyczące wyświetlania/wyświetlania całej zawartości.

Aby przekonwertować zmienną typu "Obiekt" według typu strunowy używana jest magiczna metoda __toString.

Oznaczający ZERO zawsze konwertowane na pusty ciąg.

Jak widać powyżej, bezpośrednie łańcuchowanie tablic, obiektów lub zasobów nie dostarcza żadnych użytecznych informacji o samych wartościach, poza ich typami. Bardziej odpowiednim sposobem na wyprowadzenie wartości do debugowania jest użycie funkcji print_r() oraz var_dump().

Większość wartości w PHP można przekonwertować na ciąg do trwałego przechowywania. Ta metoda nazywa się serializacją i można ją wykonać za pomocą funkcji serializuj().

Zamiana ciągów na liczby

Jeśli ciąg zostanie rozpoznany jako wartość liczbowa, wynikowa wartość i typ są określane w następujący sposób.

Jeśli ciąg nie zawiera żadnego ze znaków „.”, „e” lub „E”, a wartość liczby mieści się w zakresie liczb całkowitych (zdefiniowanych PHP_INT_MAX), ciąg zostanie rozpoznany jako liczba całkowita ( liczba całkowita). We wszystkich innych przypadkach jest uważana za liczbę zmiennoprzecinkową ( platforma).

Wartość jest określana przez początkową część ciągu. Jeśli ciąg zaczyna się od prawidłowej wartości liczbowej, ta wartość zostanie użyta. W przeciwnym razie wartość będzie wynosić 0 (zero). Prawidłowa wartość liczbowa to jedna lub więcej cyfr (które mogą zawierać kropkę dziesiętną), opcjonalnie poprzedzone znakiem, po którym następuje opcjonalny wykładnik. Wykładnik to „e” lub „E”, po którym następuje jedna lub więcej cyfr.

$foo = 1 + "10,5" ; // $foo to liczba zmiennoprzecinkowa (11.5)
$foo = 1 + "-1.3e3" ; // $foo to liczba zmiennoprzecinkowa (-1299)
$foo = 1 + "bob-1.3e3" ; // $foo jest liczbą całkowitą (1)
$foo = 1 + "bob3" ; // $foo jest liczbą całkowitą (1)
$foo = 1 + "10 małych świń" ; // $foo jest liczbą całkowitą (11)
$foo = 4 + "10.2 Małe świnki" ; // $foo to liczba zmiennoprzecinkowa (14.2)
$foo = "10.0 świń" + 1 ; // $foo to liczba zmiennoprzecinkowa (11)
$foo = "10.0 świń" + 1.0 ; // $foo to liczba zmiennoprzecinkowa (11)
?>

Zobacz sekcję strtod(3) dokumentacji Uniksa, aby uzyskać więcej informacji na temat tej konwersji.

Jeśli chcesz przetestować którykolwiek z przykładów w tej sekcji, skopiuj i wklej go oraz następujący wiersz, aby zobaczyć, co się stanie:

echo "\$foo== $foo ; wpisz: " . gettype ($foo ) . "
\n" ;
?>

Nie oczekuj, że uzyskasz kod znaku przez konwersję go na liczbę całkowitą (jak to się robi na przykład w C). Aby przekonwertować znaki na ich kody ASCII i odwrotnie, użyj funkcji ord() oraz chr().

Szczegóły implementacji typu string

7 lat temu

Dokumentacja nie wspomina, ale zamykający średnik na końcu dokumentu jest w rzeczywistości interpretowany jako prawdziwy średnik i jako taki czasami prowadzi do błędów składniowych.

$foo =<<abcd
KONIEC;
?>

Nie oznacza to:

bla(<<abcd
KONIEC;
);
// błąd składni, nieoczekiwany ";"
?>

Bez średnika działa dobrze:

bla(<<abcd
KONIEC
);
?>

3 lata temu

Możesz użyć string jak tablica char (jak C)

$a = "Test tablicy ciągów";

var_dump($a);
// Zwróć string(17) "Test tablicy ciągów"

var_dump($a);
// Zwróć łańcuch(1) "S"

// -- Z rzutowaniem tablicy --
var_dump((tablica)$a);
// Zwróć tablicę(1) ( => string(17) "Test tablicy ciągów")

var_dump((tablica)$a);
// Zwróć ciąg(17) "S"

Norihiori

15 lat temu

Możesz użyć złożonej składni, aby umieścić wartość zarówno właściwości obiektu, jak i metod obiektu wewnątrz ciągu. Na przykład...
klasa Test(
publiczny jeden $ = 1 ;
funkcja publiczna druga()(
powrót 2 ;
}
}
$test = nowy Test();
echo "foo($test -> jeden) bar ($test -> dwa ())";
?>
Wygeneruje "foo 1 bar 2".

Nie możesz jednak tego zrobić dla wszystkich wartości w Twojej przestrzeni nazw. Stałe klas i statyczne właściwości/metody nie będą działać, ponieważ złożona składnia szuka znaku „$”.
klasa Test(
const JEDEN = 1 ;
}
echo "foo (Test::ONE) bar" ;
?>
Spowoduje to wyświetlenie „foo (Test::jeden) bar”. Stałe i właściwości statyczne wymagają rozbicia łańcucha.

3 lata temu

Uważaj, że zgodnie z „konwersją ciągu na liczby”:

Jeśli ("123abc" == 123 ) echo "(intstr == int) niepoprawnie testuje jako prawda.";

// Ponieważ jedna strona jest liczbą, łańcuch jest niepoprawnie konwertowany z intstr na int, który następnie pasuje do numeru testu.

// Prawda dla wszystkich instrukcji warunkowych, takich jak if i switch (prawdopodobnie także dla pętli while)!

// Może to stanowić ogromne zagrożenie bezpieczeństwa podczas testowania/używania/zapisywania danych wejściowych użytkownika podczas oczekiwania i testowania tylko liczby całkowitej.

// Wydaje się, że jedyną poprawką jest to, że 123 jest ciągiem jako „123”, więc konwersja nie zachodzi.

?>

6 lat temu

Zera wiodące w ciągach nie są (co najmniej niespodzianka) traktowane jako ósemkowe.
Rozważać:
$x = "0123" + 0;
$y = 0123 + 0;
echo "x to $x, y to $y"; //wypisuje "x to 123, y to 83"
innymi słowy:
* wiodące zera w literałach numerycznych w kodzie źródłowym są interpretowane jako „ósemkowe”, por. strtol().
* wiodące zera w łańcuchach (np. dane przesłane przez użytkownika), gdy rzutowane (niejawnie lub jawnie) na liczbę całkowitą są ignorowane i traktowane jako dziesiętne, por. strtod().

10 lat temu

Oto prosty sposób, aby umożliwić ciągom w podwójnych cudzysłowach i dokumentom heredoc zawieranie dowolnych wyrażeń w składni nawiasów klamrowych, w tym stałych i innych wywołań funkcji:

// Deklaracja hakowania
function_expr ($v ) ( zwraca $v ; )
$_expr = "_expr" ;

// Nasz plac zabaw
zdefiniuj("qwe" , „asd”);
definiować("zxc", 5 );

$a= 3 ;
$b= 4 ;

funkcjonować c($a, $b) (zwrócić$a+ $b; }

// Stosowanie
Echo"przed{ $_expr(1 + 2 )} post\n"; // wypisuje "przed 3 postem"
Echo"przed{ $_expr(qwe)} post\n"; // wypisuje "przed ogłoszeniem"
Echo"przed{ $_expr(c($a, $b)+ zxc* 2 )} post\n"; // wypisuje "przed 17 postem"

// Ogólna składnia to ($_expr(...))
?>

2 lata temu

Pomyślałem, że warto dodać ten komentarz, aby informacja przynajmniej pojawiła się na właściwej stronie na stronie PHP.

Pamiętaj, że jeśli zamierzasz użyć łańcucha w cudzysłowie z kluczem asocjacyjnym, możesz napotkać błąd T_ENCAPSED_AND_WHITESPACE. Niektórzy uważają to za jeden z mniej oczywistych komunikatów o błędach.

Wyrażenie takie jak:

$owoc=tablica(
"a"=> "jabłko",
"b"=> banan,
//itp
);

wydrukować "To jest$owoc[ "a"]"; // T_ENCAPSED_AND_WHITESPACE
?>

na pewno rozpadnie się na kawałki.

Możesz go rozwiązać w następujący sposób:

wydrukować"To jest$owoc[ a] " ; // usuń cudzysłów z klawisza
wydrukować"To jest${ owoce[ "a"]} " ; // Składnia złożona
wydrukować"To jest{ $owoc[ "a"]} " ; // Złożona odmiana składni
?>

Osobiście preferuję ostatnią wariację, ponieważ jest ona bardziej naturalna i bliższa temu, jak wyglądałoby wyrażenie poza struną.

Nie jest jasne (przynajmniej dla mnie), dlaczego PHP błędnie interpretuje pojedynczy cudzysłów w wyrażeniu, ale wyobrażam sobie, że ma to coś wspólnego z faktem, że cudzysłowy nie są częścią ciągu wartości - gdy ciąg jest już analizowany, cytaty po prostu stanąć na przeszkodzie … ?

2 lata temu

Oba powinny działać:(

klasatestowanie{
publiczne statyczne
$var= "statyczny";
public const VAR =
"stały";

funkcja publiczna powiedzHelloStatic() {
Echo
Witam:{ $to:: $var} " ;
}

funkcja publiczna powiedzHelloConst() {
Echo
Witam:{ $to::WARIANCJA)" ; //Błąd analizy: błąd składni, nieoczekiwany „)”, oczekiwano „[”
}
}

$obj= nowytestowanie();
$obj-> powiedzHelloStatic();
$obj-> powiedzHelloConst();

3 lata temu

Coś, czego doświadczyłem, co bez wątpienia komuś pomoże. . .
W moim edytorze to podświetli składnię HTML i $comment:

$html =<<<"EOD"
$komentarz
EOD;

Używając tego pokazuje wszystkie te same kolory:

$html =<<$komentarz
EOD;

co znacznie ułatwia pracę

11 lat temu

Aby oszczędzić sobie głowy nie czytaj poprzednich komentarzy na temat terminów ;)

Gdy oba łańcuchy można przekonwertować na wartości liczbowe (w teście ("$a" > "$b")), używane są wynikowe wartości liczbowe, w przeciwnym razie PEŁNE łańcuchy są porównywane znak po znaku:

var_dump("1.22" > "01.23" ); // bool(false)
var_dump("1.22.00" > "01.23.00" ); // bool(prawda)
var_dump("1-22-00" > "01-23-00" ); // bool(prawda)
var_dump((platforma)"1.22.00" > (pływak)"01.23.00" ); // bool(false)
?>



Stoły:

C_id | firma | Lokalizacja
1 | OOO Szukaj | Pole Kudykino 15/3
2 | CJSC Elita | Słunysławinsk 133/7
3 | OJSC Pyshpyshch | Soldatodachestroyskoe 404

Typ naprawy (repair_types)
r_id | typy_napraw |
1 | Młotek + gwoździe
2 | Wskazówki dotyczące urody
3 | Wyremontować

Lista zamówień (lista)
l_id | Kto | Jaka potrzeba | czas | komentarz operatora
1 | 1 | 2 | %znacznik czasu% | %operator_text%
2 | 2 | 1 | | %tekst%
3 | 3 | 2 | | %tekst%

Tabela #1 zawiera listę klientów.
Tabela #2 zawiera listę usług.
Tabela nr 3 zawiera zestawienie aktualnych zleceń dla zespołów operacyjnych. Ta tabela jest regularnie aktualizowana, a do jej wypełnienia służy formularz internetowy. Ponieważ zamówień przychodzi dość dużo, rekordy są wprowadzane do tabeli w postaci identyfikatora klienta i usługi.

Właściwie problem polega na tym, że trzecia tabela powinna być wyświetlana w formularzu internetowym „wybór zamówienia”, a zamiast identyfikatora należy podstawić odpowiednie pola z innych kolumn.

Kod:
$query = "WYBIERZ * Z listy";
$wynik = mysql_query($zapytanie);
while($row=mysql_fetch_array($result. // pobierz wyniki z każdego wiersza
( echo "";// wyświetl dane
}




CREATE TABLE "nazwa_tabeli" ("id" int(255) NOT NULL AUTO_INCREMENT, "lista" tekst (80) NOT NULL, PRIMARY KEY("id".

INSERT INTO „nazwa_tabeli” („lista”) WARTOŚCI („bla-bla”)



najlepsza odpowiedź $zapytanie =
"
wybierz firmy.Firma, typy_napraw.Rodzaje_napraw, lista.comment_l
z listy
wewnętrzne łączenie firm
na liście.Kto = firmy.c_id
rodzaje_napraw połączeń wewnętrznych
na liście."Jaka potrzeba" = repair_types.r_id
";

Oczywiście obrazy, pliki dźwiękowe, informacje wideo, dane animacji i aplety stanowią ważną część treści World Wide Web, ale zdecydowana większość danych w sieci nadal ma postać tekstu - ciągów znaków jak to zdanie. Podstawowym typem danych PHP do reprezentowania tekstu jest ciąg.

Opis ciągów w PHP

Ciągi znaków to sekwencje znaków, które mogą być traktowane jako pojedyncza jednostka - przypisywane do zmiennych, przekazywane jako dane wejściowe do funkcji, zwracane z funkcji lub wysyłane jako dane wyjściowe do wyświetlenia na stronie internetowej użytkownika. Najprostszym sposobem określenia ciągu znaków w kodzie PHP jest ujęcie sekwencji znaków w cudzysłowie, pojedynczy ("") lub podwójny ("), na przykład w następujący sposób:

$myString = "Prosty ciąg"; $anotherString = "Kolejny ciąg";

Różnica między cudzysłowami pojedynczymi a cudzysłowami podwójnymi wynika z tego, jak szeroko środowisko PHP interpretuje znaki cudzysłowów przed utworzeniem właściwego ciągu. Jeśli ciąg jest ujęty w pojedyncze cudzysłowy, to prawie żadna interpretacja nie jest wykonywana, a jeśli ciąg jest ujęty w podwójne cudzysłowy, środowisko PHP dokonuje podstawienia wartości wszystkich zmiennych określonych w ciągu, a także zastępuje niektóre sekwencje znaków specjalnych, które zaczynają się od znaku odwrotnego ukośnika ().

Na przykład po przetworzeniu następującego kodu, który jest częścią strony internetowej:

$liczba = 13; $string1 = "Ciąg \"Hello, world!\" zawiera $count znaków.
"; $string2 = "Ciąg \"Hello, world!\" zawiera $count znaków.
"; echo $ciąg1; echo $ciąg2;

możesz spodziewać się następujących danych wyjściowych w oknie przeglądarki:

Podstawianie wartości za pomocą nawiasów klamrowych

W większości sytuacji możesz po prostu ująć zmienną w łańcuchu w podwójnych cudzysłowach, a wartość zmiennej zostanie podstawiona w łańcuchu, gdy interpreter przetworzy łańcuch. Jednak w dwóch opisanych poniżej sytuacjach może się okazać, że interpreter ciągów znaków nie jest w stanie podjąć świadomej decyzji i potrzebuje dodatkowych wskazówek od dewelopera.

Pierwsza sytuacja polega na tym, że interpreter nie może określić, gdzie kończy się nazwa zmiennej, a druga sytuacja ma miejsce, gdy konieczne jest podstawienie wartości wyrażenia do ciągu, a nie wartości prostej zmiennej. W takich przypadkach deweloper może wyjaśnić, umieszczając nazwę lub wyrażenie do przetworzenia w nawiasach klamrowych (()).

Na przykład interpreter PHP nie ma problemu z przetwarzaniem następującego kodu:

$sport = "siatkówka"; $play = "Uwielbiam grać w $sport.";

W takich przypadkach interpreter napotyka znak $, a następnie rozpoczyna podciąg znaków w celu ujawnienia nazwy zmiennej i robi to, dopóki nie napotka spacji lub kropki następującej po nazwie zmiennej $sport. Spacje i kropki nie mogą być częścią nazwy zmiennej, więc staje się jasne, że dana zmienna ma nazwę $sport; interpreter PHP następnie z powodzeniem znajduje wartość dla danej zmiennej ("siatkówka") i zastępuje ją.

Czasami jednak nie jest możliwe oznaczenie końca nazwy zmiennej spacją lub kropką. Rozważmy następujący przykład:

$sport1 = "będzie"; $sport2 = "stopa"; $sport3 = "koszyk"; // Nieprawidłowe konstrukcje $play1 = "Uwielbiam grać w $sport1ball."; $play2 = "Uwielbiam grać w $sport2ball."; $play3 = "Uwielbiam grać w $sport3ball.";

W takim przypadku pożądany efekt nie zostanie osiągnięty, ponieważ interpreter PHP uzna ciąg $sport1 za część zmiennej o nazwie $sport1ball, której najwyraźniej nie przypisano żadnej wartości. Zamiast tego musisz użyć następującej notacji:

// Poprawna konstrukcja $play1 = "Lubię grać w ($sport1)piłkę."; $play2 = "Uwielbiam grać w ($sport2)piłkę."; $play3 = "Uwielbiam grać w piłkę ($sport3).";

Ten zapis mówi interpreterowi PHP, że tylko wartość wyrażenia z nazwą zmiennej ujętą w nawiasy klamrowe musi zostać oceniona przed podstawieniem wartości.

Z podobnych powodów interpreter PHP, jeśli nie używa się nawiasów klamrowych, ma trudności z podstawianiem wartości wyrażeń złożonych nazwami zmiennych, takich jak dostęp do elementów tablic wielowymiarowych i zmiennych obiektowych. Ogólna zasada jest taka, że ​​jeśli po otwierającym nawiasie klamrowym (() natychmiast następuje znak $, to interpreter PHP ocenia wartość wyrażenia z nazwą zmiennej aż do zamykającego nawiasu klamrowego ()), a następnie podstawia otrzymaną wartość w ciąg. (Jeśli chcesz, aby w ciągu pojawiła się wartość literału ($), można to zrobić, poprzedzając każdy z tych znaków ukośnikiem odwrotnym, \).

Znaki i indeksy znaków w ciągach

W przeciwieństwie do niektórych innych języków programowania, PHP nie ma oddzielnego typu znaków, który nie jest taki sam jak typ string. Ogólnie rzecz biorąc, funkcje wymagające rzeczywistych parametrów znaków w innych językach są zaprojektowane tak, aby przyjmowały ciągi o długości 1 w PHP.

Wybór poszczególnych znaków z ciągu można wykonać, określając numer sekwencji znaków liczony od zera, który musi być określony w nawiasach klamrowych bezpośrednio po nazwie zmiennej ciągu. Takie znaki są w rzeczywistości ciągami jednoznakowymi. Na przykład uruchomienie następującego kodu:

$myString = "Podwojony"; for ($indeks = 0; $indeks< strlen($myString); $index++) { $char = $myString{$index}; print("$char$char"); }

skutkuje następującymi danymi wyjściowymi w oknie przeglądarki:

Oczywiście każdy znak ciągu jest wypisywany dwukrotnie przy każdym przejściu przez pętlę. Funkcja strlen() zwraca długość ciągu.

Operacje na ciągach

PHP udostępnia dwie operacje na łańcuchach: operator kropki (.) lub operator konkatenacji oraz operator kropki i znaku równości (.=) lub operator konkatenacji i przypisania. Rozważmy następujący przykład:

$string1 = "To jest część"; $string2 = "string"; // Łączenie ciągów echo $string1." simple ".$string2."
"; // "To jest część prostego ciągu" // Połącz i przypisz $ciąg1 .= " simple "; // Odpowiednik $ciąg1 = $ciąg1." simple "; $ciąg1 .= $ciąg2; echo $ciąg1; // "To jest część prostego ciągu"

Należy zauważyć, że w powyższym przykładzie pierwsza instrukcja echo nie jest przekazywana w wielu rzeczywistych parametrach ciągu; przekazywany jest tylko jeden rzeczywisty parametr ciągu, wynikający z połączenia czterech ciągów. Pierwszy i trzeci wiersz są ustawiane za pomocą zmiennych, a drugi i czwarty wiersz to dosłowny ciąg ujęty w podwójne cudzysłowy.

Struktura składni dokumentu podrzędnego (Heredoc)

Oprócz struktur składniowych łańcuchów w pojedynczych i podwójnych cudzysłowach, PHP zapewnia inny sposób określania łańcucha, zwany składniową strukturę dokumentu zagnieżdżonego (Heredoc). Jak się okazało, taka struktura składniowa jest bardzo wygodnym sposobem określania dużych fragmentów tekstu podstawianego za pomocą zmiennych, ponieważ eliminuje potrzebę oznaczania przez użytkownika wewnętrznych cudzysłowów za pomocą znaków specjalnych. Ta metoda jest szczególnie przydatna podczas tworzenia stron zawierających formularze HTML.

Znak operatora używany w strukturze składniowej poddokumentu to (<<<). За этим знаком должна непосредственно следовать метка (не заключенная в кавычки), которая обозначает начало многострочного текста. Интерпретатор PHP продолжает включать в состав значения переменной следующие строки до тех пор, пока снова не появится эта же метка в начале строки. За заключительной меткой может следовать необязательная точка с запятой, а какие-либо другие символы после метки не допускаются.

Rozważmy następujący przykład:

$ciąg =<<

EOT; echo $ciąg;

Zwróć uwagę, że ostatnie słowo EOT pokazane powyżej nie powinno być w ogóle wcięte, w przeciwnym razie będzie traktowane jako należące do dodatkowego zawartego tekstu. Nie jest konieczne używanie słowa "EOT" jako etykiety, etykieta może mieć dowolną nazwę, zgodnie ze zwykłymi konwencjami nazewnictwa zmiennych PHP.

Podstawianie zmiennych odbywa się za pomocą dokładnie tej samej metody, co w przypadku łańcuchów ujętych w podwójne cudzysłowy. Wygodną cechą dokumentu zagnieżdżonego jest to, że w tak oznaczonym tekście można wpisywać cudzysłowy bez użycia jakichkolwiek znaków kontrolnych, co nie prowadzi do przedwczesnego zakończenia tworzenia linii. Powyższy przykład wyświetla prosty formularz HTML:

Funkcje ciągów

Język PHP udostępnia szeroką gamę funkcji do przetwarzania i konwertowania ciągów. Jeśli kiedykolwiek będziesz musiał stworzyć własną funkcję, która odczytuje i przetwarza ciągi znak po znaku, aby utworzyć nowy ciąg, najpierw zastanów się, czy ktoś inny nie miał wcześniej do czynienia z podobnym zadaniem. A jeśli intuicja podpowiada, że ​​taka możliwość istnieje, to być może istnieje wbudowana funkcja, która rozwiązuje problem. Aby uzyskać więcej informacji na temat funkcji ciągów, odwiedź https://php.net/manual/en/ref.strings.php .

Ta sekcja przedstawia podstawowe funkcje sprawdzania, porównywania, modyfikowania i drukowania ciągów. Aby naprawdę opanować możliwości manipulowania ciągami znaków w PHP, wydaje się, że należy przynajmniej pobieżnie zapoznać się ze wszystkim, co omówiono w tej sekcji. Opis funkcji przeznaczonych do pracy z wyrażeniami regularnymi można znaleźć w poniższym artykule.

Walidacja ciągu

Jakie są najczęstsze pytania dotyczące ciągów znaków, na które należy odpowiedzieć? Pierwsze na liście pytań jest pytanie o długość sznurka; do odpowiedzi służy funkcja strlen(), której nazwa jest skrótem od string length - długość stringu. Przykład użycia takiej funkcji pokazano poniżej:

$enStr = "Witaj świecie!"; $rusStr = "Prosty ciąg"; echo $enStr." - ".strlen($enStr)." znaków
"; echo $rusStr." - ".strlen($rusStr)." postacie";

Uruchomienie tego kodu daje następujące niejednoznaczne dane wyjściowe:

Jak widać, dla ciągu „Hello world!” wynik jest poprawny, ale dla ciągu „Simple string” wynik 27 znaków jest niepoprawny. O co tu chodzi? Faktem jest, że funkcja strlen() liczy bajty, a nie znaki. W pierwszym przypadku wszystkie znaki w ciągu są w języku angielskim, tj. są reprezentowane przez kodowanie ASCII i zakodowane jako 1 bajt. W drugim przypadku ciąg zawiera znaki rosyjskie, które są zakodowane w 2 bajtach (UTF-8). Aby uniknąć późniejszych problemów podczas pracy z funkcjami łańcuchowymi, PHP powinno używać funkcji do kodowania wielobajtowego, które zaczynają się od prefiksu mb_. Oznacza to, że w poprzednim przykładzie musisz zastąpić funkcję strlen() funkcją mb_strlen() i wyraźnie określić kodowanie:

Echo $rus_str." - ".mb_strlen($rus_str, "UTF8")." znaki";

Znajdowanie znaków i podciągów

Kolejne pytanie dotyczące łańcuchów dotyczy ich zawartości. Na przykład funkcja strpos() pozwala znaleźć numer pozycji określonego znaku w ciągu, jeśli taki istnieje:

$enStr = "Witaj świecie!"; echo "Symbol "l": ".strpos($enStr, "l"); // 2

Sytuacje wymagające użycia funkcji strpos() to przypadki, w których niewrażliwość PHP na typ może być problemem. Jeśli dopasowanie nie zostanie znalezione, funkcja zwraca fałsz, a jeśli wyszukiwany znak pasuje do pierwszego znaku w ciągu, funkcja zwraca 0 (ponieważ pozycje znaków w ciągu zaczynają się od 0, a nie od 1). Obie te wartości odpowiadają fałszowi, gdy są używane do testowania warunku logicznego. Jednym ze sposobów rozróżnienia tych wartości jest użycie operatora porównywania tożsamości (operatora ===, wprowadzonego od PHP4), który zwraca prawdę tylko wtedy, gdy jego operandy są takie same i są tego samego typu. Operator porównywania tożsamości może służyć do testowania, czy zwracana wartość wynosi 0 (lub fałsz) bez ryzyka pomylenia zwracanej wartości z innymi wartościami, które mogą stać się takie same po rzutowaniu.

Funkcji strpos() można również użyć do wyszukiwania podciągu zamiast pojedynczego znaku. Aby to zrobić, wystarczy podać jako pożądany ciąg wieloznakowy, a nie jednoznakowy. Ponadto w wywołaniu tej funkcji można określić dodatkowy parametr typu integer, który określa pozycję początku wyszukiwania.

Możliwe jest również wyszukiwanie w przeciwnym kierunku, od końca ciągu do początku. Służy do tego funkcja strrpos(). (Zauważ, że ta funkcja ma w nazwie dodatkowe r, co jest skrótem od reverse.) Ta funkcja przyjmuje jako parametry ciąg do wyszukania i ciąg jednoznakowy do wyszukania, a następnie zwraca ostatnie wystąpienia pozycji drugiego parametru w pierwszym parametrze. (W przeciwieństwie do funkcji strpos(), w funkcji strrpos() poszukiwany ciąg musi składać się tylko z jednego znaku.) Po zastosowaniu tej funkcji z tymi samymi parametrami, co w poprzednim przykładzie, zostanie znaleziona inna pozycja:

$enStr = "Witaj świecie!"; echo "Symbol "l": ".strrpos($enStr, "l"); // 9 ponieważ wyszukiwanie rozpoczyna się od końca ciągu

Porównanie

Czy ta linia pasuje do tej linii? Najwyraźniej kod często musi również odpowiedzieć na to pytanie, zwłaszcza jeśli chodzi o obsługę danych wejściowych od użytkownika końcowego.

Najprostszą metodą znalezienia odpowiedzi na pytanie, czy łańcuchy są takie same, jest użycie prostego operatora porównania równości (==), który sprawdza równość nie tylko łańcuchów, ale także liczb. W przypadku korzystania z operatora == dwa ciągi są uważane za takie same, jeśli zawierają dokładnie te same sekwencje znaków. Nie jest to sprawdzane pod kątem bardziej rygorystycznej definicji identycznych ciągów, na przykład warunku, że te ciągi są przechowywane pod tym samym adresem w pamięci, ale uwzględnia wielkość liter (innymi słowy, czy porównywane litery są wielkimi czy małymi literami).

Wyniki porównania dwóch ciągów za pomocą operatora == (lub odpowiednich operatorów< и >) można ufać tylko wtedy, gdy oba operandy są łańcuchami i wiadomo, że nie nastąpiła konwersja typu. A wynikom sprawdzenia za pomocą funkcji strcmp(), opisanej poniżej, zawsze można ufać.

Najważniejszą funkcją porównywania ciągów, która wykonuje większość pracy, jest strcmp(). Ta funkcja pobiera dwa łańcuchy jako parametry i porównuje bajt po bajcie, aż znajdzie różnicę. Funkcja zwraca następnie liczbę ujemną, jeśli pierwszy ciąg jest mniejszy od drugiego, i dodatnią, jeśli drugi ciąg jest mniejszy od pierwszego. Jeśli ciągi są identyczne, funkcja strcmp() zwraca zero.

Funkcja strcasecmp() działa w ten sam sposób, z wyjątkiem tego, że porównanie równości nie uwzględnia wielkości liter. Na przykład wywołanie strcasecmp("hej!", "HEJ!") powinno zwrócić zero.

Szukaj

Opisane właśnie funkcje porównujące informują o tym, czy jeden ciąg jest równy innemu ciągowi. Aby określić, czy jeden ciąg jest zawarty w innym, użyj funkcji strpos() opisanej powyżej lub funkcji strstr() i podobnych funkcji.

Funkcja strstr() przyjmuje jako parametry ciąg do przeszukania i ciąg do przeszukania (w tej kolejności). Jeśli się powiedzie, ta funkcja zwraca część ciągu, która zaczyna się od pierwszego wystąpienia szukanego ciągu (i zawiera szukany ciąg). Jeśli nie zostanie znaleziony taki ciąg, funkcja zwróci false. Poniższy fragment kodu zawiera przykłady użycia tej funkcji:

$str = "Witaj świecie!"; $findStr = "świat"; echo "Podciąg" $findStr" w oryginalnym ciągu: ".strstr($str, $findStr);

Podobnie jak funkcja strcmp(), funkcja strstr() ma wersję niewrażliwą na wielkość liter o nazwie stristr() (i w tej nazwie jest skrótem od niewrażliwego). Funkcja stristr() jest pod każdym względem identyczna z funkcją strstr(), z wyjątkiem tego, że porównanie traktuje małe litery jako ich odpowiedniki.

Próbkowanie podciągów

Wiele funkcji napisów PHP wykonuje operacje wycinania i wklejania na napisach. Cięcie to zaznaczenie fragmentu struny, a wstawienie to selektywna modyfikacja struny. Należy pamiętać, że nawet funkcje wstawiania (najczęściej) nie modyfikują ciągu podanego jako parametr wejściowy. Zazwyczaj takie funkcje zwracają zmodyfikowaną kopię i pozostawiają oryginalny parametr bez zmian.

Najprostszym sposobem na spróbkowanie części ciągu jest użycie funkcji substr(), która zwraca nowy ciąg zawierający część podciągu znaków ze starego ciągu. Funkcja substr() przyjmuje jako parametry ciąg (z którego ma być próbkowany podciąg), liczbę całkowitą (pozycja, w której rozpoczyna się żądany podciąg) oraz opcjonalny trzeci parametr w postaci liczby całkowitej, który określa długość żądanego podciągu. Jeśli trzeci parametr nie zostanie określony, zakłada się, że podciąg będzie kontynuowany do końca ciągu. (Należy pamiętać, że przy korzystaniu z tej funkcji numeracja pozycji w linii zaczyna się od zera, a nie od jedynki, jak we wszystkich parametrach funkcji PHP, które oznaczają pozycje liczbowe w ciągach.) Na przykład:

$str = "Witaj świecie!"; echo mb_substr($str, 7, 3, "UTF8"); // "świat"

Zarówno parametr pozycji początkowej, jak i parametr długości mogą być ujemne, ale w obu przypadkach wartość ujemna ma inne znaczenie. Jeśli pozycja początkowa jest ujemna, pozycja początkowego znaku podciągu jest określana przez odliczanie wstecz od końca ciągu, a nie odliczanie do przodu od początku ciągu. (Pozycja początkowa -1 oznacza, że ​​licznik zaczyna się od ostatniego znaku, wartość -2 oznacza przedostatni znak itd.)

Na tej podstawie można założyć, że ujemna wartość długości oznacza również, że podciąg powinien być określany przez odliczanie wstecz od znaku początkowego, a nie odliczanie do przodu, ale tak nie jest. Twierdzenie, że znak na pozycji początkowej jest pierwszym znakiem w zwracanym ciągu (a nie ostatnim) jest zawsze prawdziwe. Zamiast tego ujemny parametr długości oznacza, że ​​znak końcowy jest określany przez odliczanie wstecz od końca, a nie odliczanie do przodu od pozycji początkowej.

Poniżej kilka przykładów z parametrami dodatnimi i ujemnymi:

$str = "Witaj świecie!"; echo mb_substr($str, 7, 3, "UTF8")."
"; // "świat" echo mb_substr($str, -4, 3, "UTF8")."
"; // "świat" echo mb_substr($str, 0, -5, "UTF8")."
"; // "Cześć"

Usuwanie spacji i tabulatorów z napisów

Z technicznego punktu widzenia funkcje chop(), ltrim() i trim() są funkcjami do pracy z podciągami (które są bardzo podobne do innych funkcji), ale w rzeczywistości funkcje te są przeznaczone do usuwania niechcianych znaków z łańcuchów. Funkcje chop(), ltrim() i trim(), odpowiednio, usuwają końcowe, wiodące, wiodące i końcowe białe znaki z ciągu podanego jako jedyny parametr ciągu.

Oprócz spacji, funkcje te usuwają inne białe znaki, takie jak te wskazane przez sekwencje specjalne \n, \r, \t i \0 (znaki końca wiersza, tabulatory i znaki null używane do oznaczenia końca wiersza w programach C).

W PHP często używa się funkcji do usuwania białych znaków na końcu łańcucha, nazywanej chop(), ale można również wywołać identyczną funkcję, bardziej opisowo nazwaną rtrim(). Na koniec należy zauważyć, że funkcja chop(), pomimo tego, że jej nazwa, co oznacza „odciąć”, brzmi bardzo groźnie, nie uszkadza oryginalnego parametru $original, który zachowuje poprzednią wartość.

Wymiana sznurka

Wszystkie omówione powyżej funkcje ciągów służą do pobierania części parametru wejściowego, zamiast tworzenia zupełnie nowego ciągu. W tej sekcji omówiono funkcje str_replace() i substr_replace() przeznaczone do tego celu.

Funkcja str_replace() umożliwia zastąpienie wszystkich wystąpień danego podciągu innym ciągiem. Ta funkcja przyjmuje trzy parametry: ciąg do przeszukania, podciąg, który ma zostać zastąpiony po znalezieniu, oraz ciąg, który ma zostać użyty do zamiany. Rozważmy następujący przykład:

$str = "Witaj świecie!"; echo str_replace("świat", "planeta", $str); // „Witaj planeto!”

Zastąpienie jest wykonywane na wszystkich wystąpieniach podciągu znalezionego w wyszukiwanym ciągu. Gdyby powyższy przykład posłużył do zamiany nazwy miasta w przestarzałej encyklopedii, to po skonwertowaniu całego tekstu encyklopedii do pojedynczej linii PHP, taką zamianę w całym tekście można by wykonać w jednym przejściu.

Jak pokazano powyżej, funkcja str_replace() wybiera część ciągu źródłowego do zastąpienia, szukając wystąpień żądanego podciągu w ciągu źródłowym; w przeciwieństwie do tego, substr_replace() wybiera część do zastąpienia przez jej pozycję bezwzględną. Ta funkcja przyjmuje do czterech parametrów: ciąg, który ma zostać zastąpiony, ciąg, który ma zostać zastąpiony, początkową pozycję zastąpienia i (jako parametr opcjonalny) długość części ciągu, która ma zostać zastąpiona. Rozważmy następujący przykład:

echo substr_replace("ABCDEFG", "-", 2, 3); // "AB-FG"

Część CDE ciągu została zastąpiona pojedynczym znakiem. Zauważ, że w tym przypadku dozwolone było zastąpienie podciągu łańcuchem o innej długości. Jeżeli parametr length zostanie pominięty, to zakłada się, że cała część ciągu po pozycji początkowej zostanie zastąpiona.

Funkcja substr_replace() akceptuje również parametry ujemne jako pozycję początkową i długość, które są traktowane dokładnie tak, jak w funkcji substr() powyżej. Należy pamiętać, że w wyniku operacji wykonywanych za pomocą funkcji str_replace i substr_replace, oryginalny ciąg pozostaje niezmieniony.

Wreszcie istnieje szereg rzadziej używanych funkcji, które tworzą nowe ciągi ze starych. Funkcja strrev() po prostu zwraca nowy ciąg z odwróconymi znakami w ciągu wejściowym. Funkcja str_repeat() pobiera jeden ciąg znaków i jeden parametr typu integer i zwraca ciąg znaków zawierający określoną liczbę kopii parametru ciągu:

echo str_repeat("ABC", 3); // ABCABCABC

Funkcje konwersji wielkości liter

Te funkcje umożliwiają konwersję małych liter na wielkie i odwrotnie. Funkcja strtolower() zwraca ciąg ze wszystkimi literami zamienionymi na małe. Nie ma znaczenia, czy oryginalny ciąg zawierał tylko wielkie litery, czy wielkie i małe litery. Na przykład:

$str = "Witaj świecie!"; echo mb_strtolower($str, "UTF8"); // "Witaj świecie!"

Jeśli doświadczyłeś już potrzeby wykonywania wielu walidacji formularzy, być może zauważyłeś, że funkcja strtolower() jest niezwykle przydatnym narzędziem do obsługi adresów e-mail otrzymanych od użytkowników, którzy nadal nie wiedzą, że adresy e-mail są prawdziwe -niewrażliwy. Nie mniej przydatne są inne funkcje związane z tą kategorią.

Funkcja strtoupper() zwraca ciąg ze wszystkimi literami zamienionymi na wielkie. Przykładem jest następujący fragment kodu:

$str = "Witaj świecie!"; echo mb_strtoupper($str, "UTF8"); // "WITAJ ŚWIECIE!"

Funkcja ucfirst() zmienia na wielką literę tylko pierwszą literę ciągu, funkcja ucwords() zmienia na wielką pierwszą literę każdego słowa w ciągu. Ani funkcja ucwords(), ani ucfirst() nie mają podobnej funkcji do kodowania wielobajtowego, więc nie są kompatybilne z ciągami cyrylicy.

Funkcje wprowadzania znaków sterujących

Jedną z zalet języka PHP jest to, że może być używany do wymiany danych z prawie każdym systemem. Środki tego rodzaju są zwykle uważane za rodzaj "kleju programowego". W tej roli język PHP jest używany do interakcji z serwerami baz danych, serwerami LDAP, do wymiany danych przez gniazda oraz do samego połączenia HTTP. Często ta interakcja odbywa się poprzez utworzenie najpierw ciągu komunikatu (takiego jak zapytanie do bazy danych), a następnie przekazanie go do programu odbierającego. Ale programy często nadają specjalne znaczenie niektórym znakom i dlatego muszą być przekonwertowane na znaki kontrolne. Oznacza to, że program odbierający jest instruowany, aby traktować takie znaki jako dosłowną część ciągu, zamiast stosować wobec nich specjalne traktowanie.

Wielu użytkowników, aby poradzić sobie z tym problemem, umożliwia korzystanie z tak zwanego „trybu magicznych cudzysłowów”, który zapewnia, że ​​cudzysłowy są konwertowane na znaki kontrolne przed wstawieniem ciągów do bazy danych. Ale jeśli taki tryb przetwarzania nie jest możliwy lub pożądany, to trzeba użyć starego dobrego sposobu wstawiania znaków odwrotnego ukośnika, a następnie usuwania tych znaków.

Funkcja addslashes() konwertuje pojedyncze i podwójne cudzysłowy, ukośniki odwrotne i znaki null na sekwencje specjalne przy użyciu ukośników odwrotnych, ponieważ są to znaki, które zazwyczaj muszą zostać przekonwertowane na sekwencje specjalne podczas przygotowywania zapytań do baz danych:

$escapedstring = addslashes("Ciąg z "cytatami"."); $query = "WSTAW wartości testowe (cytat) ("$escapedstring""); $wynik = mysqli_query($link, $zapytanie) lub die(mysql_error());

Uruchomienie tego kodu zapobiega błędnej interpretacji instrukcji SQL, tak jakby ciąg kończył się tuż przed literą „k”. A po pobraniu tych danych musisz użyć funkcji stripslashes(), aby usunąć ukośniki odwrotne.

Funkcja quotemeta() konwertuje szerszy zestaw znaków na sekwencje specjalne. Wszystkie te znaki mają zwykle specjalne znaczenie w wierszu poleceń systemu Unix: " .", " " ", "+", "*", " ? „, „[”, „]”, „^”, „(”, „$” i „)”. Na przykład uruchomienie następującego kodu:

$str = "Te znaki ($, *, ^) muszą zostać przekonwertowane."; echo cytatmeta($str);

wyprowadza tę linię:

Funkcje wyjściowe do urządzenia zewnętrznego i do linii

Głównymi konstrukcjami używanymi do wyświetlania danych wyjściowych są print i echo, które zostały szczegółowo omówione wcześniej. Standardowym sposobem wyprowadzania wartości zmiennych do urządzenia zewnętrznego jest uwzględnienie nazw tych zmiennych w łańcuchu w cudzysłowie (który jest przetwarzany przez interpreter w celu podstawienia wartości zmiennych), a następnie przekazanie ten ciąg do konstrukcji print lub echo.

Jeśli potrzebujesz jeszcze dokładniej sformatowanego wyjścia, możesz użyć funkcji printf() i sprintf() PHP. Te dwie funkcje przyjmują te same parametry: specjalny ciąg formatujący, po którym następuje dowolna liczba innych parametrów, które są podstawiane we właściwych miejscach w ciągu formatującym w celu uzyskania wyniku. Jedyna różnica między printf() i sprintf() polega na tym, że printf() wysyła łańcuch wynikowy bezpośrednio do urządzenia zewnętrznego używanego do wyjścia, podczas gdy sprintf() zwraca łańcuch wynikowy jako wynik swojego wykonania.

Kilka słów dla doświadczonych programistów C. Ta wersja sprintf() różni się nieco od wersji C tym, że sprintf() nie musi dostarczać zaalokowanego ciągu do zapisu, ponieważ interpreter PHP alokuje pamięć na wynikowy ciąg w imieniu użytkownik.

Główną trudnością związaną z korzystaniem z tych funkcji jest prawidłowa definicja ciągu formatującego. Każdy znak w ciągu formatu pojawia się bezpośrednio w wartości wynikowej, z wyjątkiem znaków % i znaków, które występują bezpośrednio po tych znakach. Symbol % oznacza początek specyfikacji konwersji, która określa sposób wyprowadzania do urządzenia zewnętrznego jednego z parametrów następujących po ciągu formatu.

Po znaku % znajduje się pięć elementów składających się na specyfikację konwersji, które opisano poniżej, a niektóre z nich są opcjonalne: dopełnienie, wyrównanie, minimalna szerokość, precyzja i typ:

  • Opcjonalny znak minus (-) służy do wskazania, czy liczba jest ujemna.
  • Pojedynczy (opcjonalny) znak wypełnienia to 0 lub spacja (). Ten symbol jest używany do wypełnienia wszelkich miejsc, które w innym przypadku byłyby puste, ale które użytkownik nalegał na wybranie (poprzez ustawienie zbyt wysokiego parametru minimalnej szerokości). Jeśli ten znak dopełniający nie jest określony, domyślnie dopełnia się spacjami.
  • Opcjonalny znak justowania (-) określa, czy wartość wyjściowa powinna być justowana do lewej czy do prawej. Jeśli ten znak zostanie określony, wartość zostanie wyrównana do lewej, a jeśli nie będzie, zostanie zastosowana wyrównanie do prawej.
  • Opcjonalna wartość liczbowa minimalnej szerokości, która określa minimalną liczbę pozycji, jakie powinna zajmować wartość wyjściowa. (Jeśli wartości wyjściowe wymagają większej liczby pozycji znaków niż określono, wartość wyjściowa jest poza zakresem.)
  • Opcjonalny specyfikator dokładności, sformatowany jako kropka (.), po której następuje liczba. Specyfikator wskazuje, z jaką dokładnością, mierzoną liczbą miejsc dziesiętnych po kropce, powinna być wyprowadzana liczba zmiennoprzecinkowa podwójnej precyzji. (Zastosowanie tej specyfikacji nie ma wpływu na wyprowadzanie danych innych niż liczby zmiennoprzecinkowe o podwójnej precyzji).
  • Pojedynczy znak wskazujący, jak należy interpretować typ wartości. Znak f oznacza, że ​​wartość ma być wydrukowana jako liczba zmiennoprzecinkowa podwójnej precyzji, znak s wskazuje, że wartość ma być wydrukowana jako łańcuch, a pozostałe możliwe znaki (b, c, d, o, x, X ) wskazują, że wartość powinna być interpretowana jako liczba całkowita i wyprowadzana w różnych formatach. Te formaty to b dla wyjścia w formacie binarnym, c dla wyjścia znaku z odpowiednią wartością kodu ASCII, o dla wyjścia w formacie ósemkowym, x dla wyjścia w formacie szesnastkowym (z małymi literami cyfr) i X dla wyświetlania liczby szesnastkowe, które używają wielkich liter jako symboli dosłownych dla cyfr.

Poniżej znajduje się przykład wyprowadzania tej samej liczby zmiennoprzecinkowej o podwójnej precyzji na kilka różnych sposobów:

%10f 
%-10f
%2.2f", $wartość, $wartość, $wartość, $wartość); ?>

Daje następujące wyniki:

Konstrukcja użyta w tym przykładzie

...
to deskryptor HTML, który informuje przeglądarkę, że blok zawarty w tym deskryptorze powinien być sformatowany dosłownie, bez kompresji wielu spacji w jedną itd.

Funkcje do pracy z kodem HTML

PHP udostępnia szereg funkcji do manipulowania ciągami zawierającymi dane specyficzne dla sieci. Przegląd tych funkcji znajduje się w poniższej tabeli:

Funkcje ciągów zaprojektowane do pracy z kodem HTML

Funkcjonować Opis
htmlznaki specjalne() Pobiera ciąg jako parametr i zwraca ciąg, w którym cztery znaki, które mają specjalne znaczenie w języku HTML, zostały zastąpione specjalnymi ciągami. Każdy z tych znaków jest zastępowany przez odpowiedni składnik HTML, który jest ponownie zastępowany oryginalnym znakiem, gdy tekst strony jest rozwijany w przeglądarce. Znak & jest zastępowany przez znak & " (znak podwójnego cudzysłowu) - przez znak "< - < а символ > - >
htmlentities() Wykonuje bardziej kompletne przetwarzanie niż htmlspecialchars(), tj. zastępuje komponentem HTML nie tylko znaki specjalne, ale także wszystkie znaki, dla których przewidziano zastąpienie komponentem HTML
get_html_translation_table() Pobiera jedną z dwóch stałych specjalnych (HTML_SPECIAL_CHARS lub HTML_ENTITIES) i zwraca tabelę konwersji używaną odpowiednio przez funkcje htmlspecialchars() lub htmlentities(). Tabela przeglądowa to tablica, której klucze są ciągami znaków, a odpowiadające im wartości są ciągami, które je zastępują.
nl2br() Przyjmuje łańcuch jako parametr i zwraca ten sam łańcuch, ale z deskryptorami
, wstawiony przed wszystkimi znakami końca wiersza (\n, \r lub \r\n). Konieczność skorzystania z tej funkcji pojawia się np. gdy chcemy zapewnić takie same paragrafy tekstu wyświetlanego w przeglądarce jak w tekście źródłowym
strip_tags() Pobiera ciąg znaków jako parametr i stara się utworzyćłańcuch pozbawiony wszystkich deskryptorów HTML i wszystkich deskryptorów PHP

Haszowanie danych za pomocą algorytmu MD5

Algorytm MD5 to algorytm przetwarzania ciągów znaków, który służy do generowania tak zwanego skrótu lub podpisu cyfrowego dla dowolnego ciągu przekazywanego jako parametr. Algorytm generuje ciąg o stałej długości na podstawie ciągu wejściowego, składającego się z 32 cyfr szesnastkowych (0-9, a-f). Wyniki generowane przez algorytm MD5 mają bardzo przydatne właściwości, które opisano poniżej:

  • Algorytm MD5 zawsze zapewnia, że ​​ciąg wyjściowy jest taki sam, gdy podano ten sam ciąg wejściowy, więc szyfrowanie MD5 nie może być używane do przechowywania haseł.
  • Wyniki zastosowania algorytmu MD5 mają stałą długość i są bardzo równomiernie rozłożone w całym zakresie możliwych wartości.
  • Można wygenerować ciąg wejściowy odpowiadający danemu ciągowi wyjściowemu algorytmu MD5 lub można utworzyć dwa ciągi wejściowe, których przetwarzanie prowadziłoby do tego samego ciągu wyjściowego, ale tylko pod pewnymi warunkami.

Implementacja algorytmu MD5 w PHP jest dostępna jako funkcja md5(), która pobiera ciąg znaków jako dane wejściowe i generuje wyniki w postaci 32-znakowego skrótu. Na przykład uruchomienie następującego kodu:

$str = "Witaj świecie!"; echo "Kod skrótu łańcucha "$str": ".md5($str)."
"; $str = "Witaj, świecie!"; echo "Kod skrótu łańcucha "$str": ".md5($str)."
"; $str = "Witaj świecie"; echo "Kod skrótu łańcucha "$str": ".md5($str)."
";

skutkuje następującymi wynikami w oknie przeglądarki:

Oczywiście w tym przypadku wszystkie ciągi wejściowe są do siebie bardzo podobne, ale ciągi wyjściowe nie mają żadnego widocznego podobieństwa. Ponadto zakres możliwych wartości wyjściowych jest niezwykle duży (1632), więc szanse na przetworzenie dwóch różnych ciągów (które dałyby tę samą wartość MD5) są bardzo mało prawdopodobne.

Ze względu na powyższą charakterystykę algorytmu MD5, wartości uzyskane za jego pomocą mogą być wykorzystane do rozwiązania szerokiej gamy problemów, w tym opisanych poniżej:
Obliczanie sumy kontrolnej wiadomości lub pliku
Aby sprawdzić, czy wiadomość została uszkodzona podczas transmisji, możesz wraz z wiadomością wysłać skrót MD5 i ponownie wygenerować skrót MD5 po odebraniu wiadomości. Jeśli dwie wersje skrótu nie pasują, oznacza to, że podczas transmisji doszło do uszkodzenia.
Kontrola nad tym, czy zawartość pliku pozostaje niezmieniona
To zadanie jest podobne do zadania obliczania sumy kontrolnej. Algorytm MD5 jest często używany do wykonania tej operacji w wyszukiwarkach, jeśli wymagane jest okresowe sprawdzanie, czy strona internetowa się zmieniła i ponowne indeksowanie w razie potrzeby. Faktem jest, że dla dalszej weryfikacji znacznie łatwiej jest zorganizować przechowywanie skrótu MD5 niż całego pliku źródłowego.
Dzielenie wielu ciągów lub plików na podzbiory
Aby rozwiązać problem dzielenia zbioru łańcuchów na N losowo wybranych podzbiorów, możesz obliczyć skrót MD5 każdego łańcucha, wziąć kilka pierwszych znaków szesnastkowych, przekonwertować je na liczbę, uzyskać modulo modulo tej liczby i użyć tego reszta jako numer podzbioru, w którym należy wpisać ten wiersz.

Oprócz funkcji md5() PHP udostępnia funkcję md5_file(), która jako parametr przyjmuje nazwę pliku i zwraca zaszyfrowaną wartość MD5 odpowiadającą zawartości pliku.

Funkcje zaprojektowane do oceny podobieństwa ciągów

W praktyce często konieczne staje się określenie, na ile podobne są dwie struny. Oczywiście wyniki estymacji podobieństwa strun zależą od tego, co rozumiemy pod pojęciem podobieństwa strun.

Jeśli podobieństwo w pisowni jest uważane za kryterium oceny podobieństwa, można zastosować Wskaźnik Levenshteina. Funkcja levenshtein() przyjmuje dwa ciągi jako parametry i zwraca minimalną liczbę operacji dodawania, usuwania i zastępowania znaków wymaganych do konwersji jednego ciągu na inny. Rozważ przykład:

echo levenshtein("Tim", "Czas"); // 1 echo levenshtein("chłopiec", "chefboyee"); // 9 echo levenshtein("nigdy", "sprytny"); // 2

Jeśli podobieństwo fonetyczne jest traktowane jako kryterium podobieństwa, to do oceny podobieństwa można użyć funkcji soundex() i metaphone(). Obie te funkcje przyjmują dany ciąg jako dane wejściowe i zwracają kluczowy ciąg wskazujący kategorię wymowy danego słowa (które jest traktowane jako słowo angielskie). Jeśli dwa słowa użyte jako zawartość ciągu wejściowego odpowiadają dokładnie tej samej wartości wyjściowej, prawdopodobnie będą wymawiane tak samo.

Funkcje parsowania i tokenizacji

Czasami konieczne jest, aby program podzielił ciągi na komponenty, kierując się własną definicją tego, co powinno być uważane za komponent. Proces dzielenia długiego łańcucha na części nazywa się tokenizacją. W szczególności taki proces jest częścią ogólnej procedury interpretacji lub kompilacji dowolnego programu komputerowego, w tym programu napisanego w PHP. Język PHP udostępnia do tego celu specjalną funkcję - strtok().

Funkcja strtok() przyjmuje dwa parametry: ciąg znaków do tokenizacji oraz ciąg znaków zawierający wszystkie ograniczniki (znaki, które są traktowane jako granice między tokenami). Przy pierwszym wywołaniu używane są oba parametry, a funkcja zwraca wartość ciągu reprezentującą pierwszy token. Aby wybrać kolejne tokeny, wykonywane jest to samo wywołanie, ale parametr ciągu źródłowego jest pomijany. Funkcja zapamiętuje adres ciągu podanego w pierwszym parametrze i używa go jako bieżącego ciągu. Ponadto funkcja ta zapamiętuje, gdzie przetwarzanie zostało zakończone w poprzednim wywołaniu. Rozważmy następujący przykład:

$token = strtok("open-source HTML-osadzone skrypty WWW po stronie serwera", " "); while($token) ( echo $token."
"; $token = strtok(" "); )

co skutkuje następującym wynikiem w oknie przeglądarki:

Oryginalny ciąg jest dzielony w miejscu, w którym znajduje się każda spacja.

Funkcja strtok() buduje tokeny jeden po drugim. Możesz również użyć funkcji explode(), która wykonuje mniej więcej to samo, z wyjątkiem tego, że przechowuje wszystkie tokeny jednocześnie w jednej tablicy. Po przedstawieniu tokenów w postaci tablicy można na nich wykonywać dowolne operacje, w tym sortowanie.

Funkcja explode() przyjmuje dwa parametry: ciąg znaków ogranicznika i ciąg znaków, który ma zostać podzielony na tokeny. Ta funkcja zwraca tablicę, której każdy element jest podciągiem między wystąpieniami ogranicznika w ciągu do podziału. Rozważmy następujący przykład:

$explodeResult = explode("I", "jeden AND dwa AND trzy");

co daje w wyniku tablicę $explode_result zawierającą trzy elementy, z których każdy jest łańcuchem: "jeden", "dwa" i "trójka". W tym konkretnym przykładzie w żadnym z ciągów zawartych w tablicy nie występują duże litery, ponieważ w wyniku nie występuje separator AND.

Łańcuch znaków separatora używany w funkcji explode() jest zupełnie inny niż łańcuch znaków z separatorem używany w funkcji strtok(). Ogranicznik jest pełnym ciągiem, więc wszystkie znaki w tym ciągu muszą znajdować się w ciągu źródłowym w tej samej kolejności, co w ograniczniku, aby ogranicznik został uznany za znaleziony.

Z drugiej strony rozdzielony ciąg w funkcji strtok() określa wiele pojedynczych znaków, z których każdy jest traktowany jako ogranicznik. Oznacza to, że funkcja explode() jest bardziej selektywna, ale bardziej podatna na uszkodzenia. W szczególności, jeśli w długim łańcuchu przypadkowo pominie choćby pojedyncza spacja lub znak końca wiersza, który jest częścią ogranicznika, wtedy całe działanie tej funkcji może zostać przerwane.

Funkcja explode() ma funkcję odwrotną, implode(), która przyjmuje dwa parametry: ciąg łączący (podobny do ciągu oddzielającego w funkcji explode()) oraz tablicę ciągów, podobną do tej zwracanej przez funkcję explode( ). Funkcja implode() zwraca ciąg znaków utworzony przez wstawienie ciągu łączącego wszystkie kolejne elementy ciągu w tablicy.