Používanie šablón v PHP. Používanie zástupných znakov v PHP Znaky a indexy znakov v reťazcoch
IN v poslednej dobe diskusie o jazyku PHP na Habré sa viac zameriavajú na možnosti návrhu komplexné systémy, ktorý sa nemôže len tešiť. Po zhliadnutí desiatky najuznávanejších webových frameworkov (Zend Framework, Adept, CakePHP, CodeIgniter, LIMB, Symfony, MZZ a ďalšie) ma však úprimne prekvapilo, že v niektorých som našiel výrazné nedostatky z pohľadu elementárnej optimalizácie. .
Aby bola táto téma viac technicky zameraná, výsledky sú prezentované v prísnejšej forme, čo môže trochu skomplikovať vnímanie.
Takže poďme... Úloha je veľmi jednoduchá: vykonajte experimenty s rýchlosťou vytvárania reťazcov z podreťazcov v jednoduchých a dvojitých úvodzovkách. V zásade bude táto otázka stále aktuálna na dlhú dobu kvôli zvláštnostiam spracovania reťazcov v PHP.
Existuje veľa článkov o základnej optimalizácii skriptov v ruštine aj v iných jazykoch. Hovorí málo o reťazcoch, ale upozorňuje na skutočnosť, že reťazce v úvodzovkách sú „analyzované“ na premenné a riadiace znaky (rovnako ako v oficiálnej dokumentácii). Na základe toho je logické predpokladať, že používanie reťazcov v dvojitých úvodzovkách bude o niečo pomalšie ako rovnaké operácie s podreťazcami v jednoduchých úvodzovkách.
Okrem nahradenia premenných do reťazcov a zreťazenia premenných s podreťazcami PHP implementuje ešte aspoň jeden spôsob generovania reťazcov: prácu s funkciou sprintf. Je logické predpokladať, že túto metódu budú výrazne horšie ako „štandardné“ kvôli zbytočnému volaniu funkcií a analýze reťazcov vo vnútri.
Jediný dodatok, predtým, ako vám predstavím kód testovacieho skriptu: je potrebné zvážiť 2 veci možné možnosti práca s reťazcami v úvodzovkách: berúc do úvahy jednoduché a „pokročilé“ štýly kódovania. Pravdepodobne by ste nemali venovať pozornosť skutočnosti, že premenné sú na samom začiatku riadkov - sú to len príklady:
$string = "$_SERVER["HTTP_HOST"] nie je správou Uľanovskej oblasti. Milujeme ruský jazyk a nemáme radi tých, ktorí ním hovoria...“
A
$string = "($_SERVER["HTTP_HOST")]) nie je správou oblasti Uljanovsk. Milujeme ruský jazyk a nemáme radi tých, ktorí ním hovoria..."
Test číslo jedna.
Zdá sa, že všetky výhrady boli urobené - je čas ukázať výsledky práce. Zdrojový kód dá sa nájsť tester.
Screenshoty ukazujú, že moja hypotéza sa nepotvrdila. Jediný správny predpoklad sa ukázal byť o práci s reťazcami cez sprintf. Najrýchlejšie boli funkcie, ktoré pracujú špeciálne s dvojitými úvodzovkami.
Po krátkom zamyslení sa nad situáciou prišlo vysvetlenie samo: podstatou je, že referenčný reťazec, do ktorého boli vykonané substitúcie, je príliš krátky: prechod syntaktického analyzátora cez takýto reťazec je hračka. Avšak aj tu je jasné, že natívna substitúcia premennej do reťazca dáva výhodu oproti „pokročilému štýlu“.
Toto je tiež slabina prístupu zreťazenia: objem vložených údajov prevyšuje objem podreťazcov. Odkiaľ sa berú režijné náklady, sa dočítate v už spomínanom habratopiku.
Aj tieto myšlienky však bolo potrebné potvrdiť. To si vyžiadalo druhý test so zmenami možných spomínaných dôvodov takéhoto nepredvídateľného (pre mňa) správania. Zdá sa, že v piatej verzii sa toho veľa upravilo (priznám sa, v piatej verzii PHP som vykonal iba 1 test: prechádzať prvkami poľa).
Test číslo dva.
Druhá hypotéza: predĺženie referenčného reťazca bude mať v konečnom dôsledku za následok zvýšenie percenta prevádzkového času testovacích funkcií spojených s tvorbou reťazcov v dvojitých úvodzovkách v porovnaní s výsledkami testu číslo 1. Rovnaká situácia, teoreticky, by mala byť pozorovaná vo vzťahu k fungovaniu funkcie sprintf. Je to spôsobené predovšetkým potrebou analyzovať reťazce a predĺžením času stráveného na tomto procese. V situácii so zreťazením podreťazcov v jednoduchých úvodzovkách si myslím, že bude pozorovaný približne rovnaký výsledok ako v prvom teste, čo spôsobí mierne zníženie podielu času vykonania funkcie quotes_3() v porovnaní s časom vykonania celého scenára (ale nie zvýšenie výkonu).
Závery sú vlastne len pozitívne a potvrdzujú hypotézu. Pri miernom zvýšení referenčného reťazca sa objaví veľké zaťaženie, čo vedie k zníženiu výkonu funkcií pre prácu s dvojitými úvodzovkami a sprintf.
Predpoklad týkajúci sa reťazcov v jednoduchých úvodzovkách sa tiež ukázal ako správny: namiesto 36,75 % času v prvom teste zabrala funkcia quotes_3() v druhom 33,76 % času spustenia skriptu.
Praktická hodnota.
Jednoducho povedané, abstrahujúc od údajov, môžeme dospieť k záveru: čím dlhší je riadok, v ktorom je potrebné vykonať substitúciu, pravdepodobnejšie, že operácia zreťazenia sa vykoná rýchlejšie ako hľadanie premennej v úvodzovkách. Dobrovoľníci sa môžu pokúsiť vybrať potrebné parametre vkladania (počet premenných, dĺžka referenčného reťazca, dĺžky reťazcov v premenných) tak, aby vyhovovali rovnosti časov vykonávania.
To je vlastne všetko. Zostáva len dodať, že v programovaní nie sú žiadne maličkosti (myslím tým, ktorí radi hovoria „šetrenie na zápasy“ (c) Adelf). Poznaním takýchto jemností a ich zohľadnením môžete napísať kód, ktorý bude optimalizovaný na všetkých jeho úrovniach;)
PS:
Testy vykonané pomocou Zend Studio For Eclipse 6.0.0 (obsahuje Debugger + Profiler).
Verzia PHP 5.2.5
OS Debian Linux
PPS:
Bol by som rád, keby niekto zverejnil výsledky týchto testov. Myslím si, že to umožní objektívnejšie posúdiť potrebu použitia tej či onej metódy substitúcie do reťazcov. Ocenil by som aj zdravú kritiku štýlu prezentácie a dizajnu.
Hodnoty typu string sú textové reťazce (skrátene reťazce). Reťazec je sekvencia nula alebo viacerých znakov. Medzi znaky patria písmená, čísla, interpunkcia, špeciálne znaky a priestory.
Reťazec môže byť definovaný štyrmi rôznymi spôsobmi:
- dvojité úvodzovky
- jednoduché úvodzovky
- syntax heredoc
- syntax nowdoc
Reťazec v úvodzovkách
Reťazec v úvodzovkách:
V reťazcoch v dvojitých úvodzovkách môžete použiť sekvencie escape. Riadiaca sekvencia— sú to špeciálne znaky určené na formátovanie textového výstupu. V PHP sú k dispozícii nasledujúce sekvencie escape:
Hlavnou vlastnosťou reťazcov v dvojitých úvodzovkách je schopnosť spracovávať premenné v reťazcoch.
Znak dolára: \$";
Reťazce v úvodzovkách môžu obsahovať jednoduché úvodzovky:
Echo "Jedna citácia: "";
Reťazec v jednoduchých úvodzovkách (apostrofy)
Reťazec v jednoduchých úvodzovkách:
$str = "Reťazec"; echo "Jeden veľký riadok možno rozdeliť na niekoľko malých riadkov, aby sa dal ľahšie čítať.";
Na rozdiel od reťazcov v dvojitých úvodzovkách a syntaxe heredoc, premenné a riadiace sekvencie (s jednou výnimkou) uzavreté v jednoduché úvodzovky, nie sú spracované. To znamená, že budú interpretované ako normálne reťazcové znaky:
$num = 10; echo "Číslo: $num
Znak dolára: \$";
Aby ste mohli použiť jednoduché úvodzovky v reťazci uzavretom do jednoduchých úvodzoviek, musíte ich ukončiť pomocou spätnej lomky (\"). Ak potrebujete napísať samotnú spätnú lomku, musíte ju duplikovať (\\):
Echo "Vnútri použite \"jednoduché\" úvodzovky"; echo "Obrátená lomka: \\";
Reťazce v jednoduchých úvodzovkách môžu obsahovať znaky dvojitých úvodzoviek:
Echo "Dvojitá úvodzovka: "";
Syntax Heredoc
Syntax Heredoc je alternatívny spôsob písanie reťazcov.
Reťazec definovaný pomocou syntaxe Heredoc funguje rovnako ako reťazec v úvodzovkách. Rozdiel medzi Heredocom a reťazcom v dvojitých úvodzovkách je v tom, že v prípade Heredoc nie je potrebné unikať dvojitým úvodzovkám.
Syntax Heredoc začína tromi znakmi<<< , после которых должен быть указан произвольный идентификатор (назовём его открывающим). Идентификатор может быть указан как в двойных кавычках, так и без них. Hneď za identifikátorom musí nasledovať nový riadok, za identifikátorom by nemali byť žiadne iné znaky ako nový riadok, inak dôjde k chybe. Nasleduje samotný obsah reťazca. Po obsahu reťazca musí byť na samostatnom riadku uvedený koncový identifikátor (rovnaký ako po<<<). Перед ним и после него не должно быть никаких пробелов или других символов, за исключением точки с запятой. Если это правило нарушено, то считается, что закрывающий идентификатор отсутствует и будет вызвана ошибка:
<< Syntax Nowdoc, podobne ako Heredoc, je alternatívnym spôsobom zápisu reťazcov. Reťazec definovaný pomocou syntaxe Nowdoc funguje rovnako ako reťazec uzavretý v jednoduchých úvodzovkách. Rozdiel medzi Nowdoc a reťazcom v jednoduchých úvodzovkách je v tom, že v prípade Nowdoc nie je potrebné používať jednoduché úvodzovky. Syntax Nowdoc je podobná ako u Heredoc, len s tým rozdielom, že otvárací identifikátor musí byť uzavretý v jednoduchých úvodzovkách: $num = 10; ozvena<<<"some_id"
Число: $num
some_id;
Existujú dva typy syntaxe na spracovanie premenných v reťazcoch: jednoduché A ťažké. Jednoduchá syntax- vtedy je názov premennej uvedený v riadku tak, ako je. Keď tlmočník narazí na znak dolára, začne postupne kontrolovať, či sú všetky nasledujúce znaky platnými znakmi v názve premennej. Aby sa vytvoril platný názov premennej, zachytí čo najviac znakov: $str = "Svet!"; echo "Ahoj $str"; Zložitá syntax- vtedy je názov premennej uzavretý v zložených zátvorkách. Keďže na spracovanie premennej v riadku tlmočník zachytí čo najviac znakov, existujú situácie, keď tlmočník nie je schopný samostatne určiť, kde končí názov premennej: $sport1 = "vôľa"; $sport2 = "noha"; echo "Mám rád $sport1ball a $sport2ball"; V tomto prípade sa nedosiahne požadovaný výsledok, pretože interpret bude považovať $sport1 za súčasť premennej s názvom $sport1bol, ktorá neexistuje. Ak chcete interpretovi explicitne povedať, kde končí názov premennej, musíte názov premennej uzavrieť do zložených zátvoriek: $sport1 = "vôľa"; $sport2 = "noha"; echo "Mám rád ($sport1)bol a ($sport2)bol."; Znak dolára môže byť umiestnený pred alebo za zloženú zátvorku: $sport1 = "vôľa"; $sport2 = "noha"; echo "Páči sa mi $(sport1)bol a ($sport2)bol."; Reťazenie je spojenie dvoch alebo viacerých reťazcov do jedného väčšieho reťazca. K zreťazeniu dochádza pomocou operátora zreťazenia - . (bodka). Pri zreťazení sa každý nasledujúci riadok pridá na koniec predchádzajúceho:
Hodnota akéhokoľvek typu, ktorá je spojená s reťazcom, sa implicitne skonvertuje na reťazec a potom sa spojí:
"; echo "Číslo: " . 1; ?> Komentujte:
V PHP 7.0.0 na 64-bitových platformách neexistujú žiadne dosiahnuteľné limity na dĺžku linky na 32-bitových systémoch a v starších verziách PHP nemôžu byť riadky väčšie ako 2 GB (2147483647 bajtov). Reťazec možno definovať štyrmi rôznymi spôsobmi: Najjednoduchší spôsob, ako definovať reťazec, je uzavrieť ho do jednoduchých úvodzoviek (znak "
). Ak chcete v reťazci použiť jednu úvodzovku, uzavrite ju spätnou lomkou ( \
). Ak potrebujete napísať samotnú spätnú lomku, duplikujte ju ( \\
). Všetky ostatné použitia spätnej lomky budú interpretované ako normálne znaky: to znamená, že ak sa pokúsite použiť iné únikové sekvencie, ako napr. \r alebo \n, budú na výstupe tak, ako sú, namiesto akéhokoľvek špeciálneho správania. ozvena "toto je jednoduchý reťazec"; ozvena „Vkladať sa dá aj do riadkov // Výstupy: Arnold raz povedal: "Vrátim sa" Echo "Odstránili ste C:\\*.*?"; // Výstupy: Vymazali ste C:\*.*? // Výstupy: Toto sa nerozbalí: \n nový riadok // Výstupy: $expand a $either premenné nie sú expandované Ak je reťazec uzavretý v úvodzovkách ("), PHP rozpoznáva nasledujúce sekvencie escape špeciálnych znakov: Rovnako ako v prípade reťazca uzavretého v jednoduchých úvodzovkách, escapovanie ľubovoľného znaku tiež vypíše samotný únikový znak. Pred PHP 5.1.1 použite spätné lomítko \($var) nebola zverejnená. Tretím spôsobom, ako definovať reťazce, je použiť syntax heredoc: <<<
. Za týmto operátorom musíte zadať identifikátor a potom posun riadkov. Potom nasleduje samotný riadok a potom rovnaký identifikátor, ktorý uzatvára vkladanie. Linka by mal začínať koncovým identifikátorom, t.j. musí sa objaviť v prvom stĺpci riadku. Okrem toho musí identifikátor spĺňať rovnaké pravidlá pomenovania ako všetky ostatné značky v PHP: obsahovať iba alfanumerické znaky a podčiarkovník a nesmie začínať číslom (podčiarkovníky sú povolené). Pozornosť
Je veľmi dôležité poznamenať, že záverečný riadok identifikátora nesmie obsahovať žiadne iné znaky okrem bodkočiarky ( ;
). To znamená, že id by nemali byť odsadené a že pred ani za bodkočiarkou nemôžu byť žiadne medzery ani tabulátory. Je tiež dôležité pochopiť, že prvý znak pred koncovým identifikátorom musí byť znak nového riadku, ako ho definuje váš operačný systém. Napríklad v systémoch UNIX vrátane macOS je to tak \n. Za koncovým identifikátorom musí okamžite začať aj nový riadok. Ak je toto pravidlo porušené a koncový identifikátor nie je „čistý“, predpokladá sa, že koncový identifikátor chýba a PHP ho bude ďalej hľadať. Ak sa v tomto prípade nikdy nenájde správny koncový identifikátor, spôsobí to chybu analýzy s číslom riadku na konci skriptu. Príklad č. 1 Príklad nesprávnej syntaxe trieda foo( Príklad #2 Príklad správnej syntaxe trieda foo( Heredoc nemožno použiť na inicializáciu polí triedy. Počnúc PHP 5.3 sa toto obmedzenie vzťahuje len na heredocs obsahujúce premenné. Text Heredoc sa správa rovnako ako reťazec v dvojitých úvodzovkách bez toho, aby ich mal. To znamená, že v heredoc nemusíte uvádzať úvodzovky, ale stále môžete použiť sekvencie escape vyššie.<< v niekoľkých líniách, Trieda foo Function__construct() $this -><< Teraz dedukujem ( $foo -> bar [ 1 ]) Výsledkom by malo byť veľké písmeno "A": \x41 Moje meno je "Meno". píšem Foo. Teraz vypíšem Bar2. Výsledkom by malo byť veľké písmeno "A": A Je tiež možné použiť syntax heredoc na prenos údajov cez argumenty funkcie: statický $bar = const BAR =<< FOOBAR; Príklad použitia poľa Od PHP 5.3.0 môžete tiež umiestniť identifikátor Heredoc do dvojitých úvodzoviek: Nowdoc
vyhlásením bloku textu, ktorý nie je určený na spracovanie. Nowdoc je označený rovnakou sekvenciou <<<
, ktorý sa používa v heredoc, ale nasledujúci identifikátor je uzavretý v jednoduchých úvodzovkách, napr. <<<"EOT"
. Všetky podmienky, ktoré sa vzťahujú na identifikátory heredoc, sa vzťahujú aj na nowdoc, najmä tie, ktoré sa vzťahujú na koncový identifikátor. $this -><<<"EOD" EOD; Výsledok spustenia tohto príkladu: Príklad textu presahujúceho viacero riadkov pomocou syntaxe nowdoc. Spätné lomky sa vždy spracúvajú doslovne, ako napríklad \\ a \". Príklad #8 Nowdoc reťazec cituje príklad s premennými Trieda foo Function__construct() $this -><<<"EOT" EOD; Toto by nemalo vydávať veľké "A": \x41 Moje meno je "$name". Tlačím $foo->foo. Teraz tlačím ($foo->bar). Toto by nemalo vydávať veľké "A": \x41 trieda foo( Komentujte: Príklad #9 Príklad použitia statických údajov Manipulácia s premennými Ak je reťazec zadaný v úvodzovkách alebo pomocou heredoc, premenné v ňom sú spracované. Existujú dva typy syntaxe: jednoduchá a zložitá. Jednoduchá syntax je jednoduchšia a pohodlnejšia. Umožňuje spracovať premennú, hodnotu poľa ( pole) alebo vlastnosti objektu ( objekt Zložitú syntax možno identifikovať podľa zložených zátvoriek okolo výrazu. $
Jednoduchá syntax Ak tlmočník narazí na znak dolára ( ), zachytí čo najviac znakov, aby vytvoril platný názov premennej. Ak chcete zadať koniec názvu, uzatvorte názov premennej do zložených zátvoriek. $šťava = "jablko" ; // Nesprávne. "s" je platný znak pre názov premennej, ale premenná má názov $šťava. EOD; // Správne. Koniec názvu premennej je striktne uvedený v zátvorkách: echo "Vypil nejaký džús vyrobený z $( džúsu ) s." ; Existujú dva typy syntaxe: jednoduchá a zložitá. Vypil trochu jablkového džúsu. Vypil trochu šťavy z . Vypil trochu šťavy z jabĺk. pole Prvok poľa ( ]
) označuje koniec definície indexu. Pre vlastnosti objektu platia rovnaké pravidlá ako pre jednoduché premenné. Príklad #10 Jednoduchý príklad syntaxe definovať ("KOOLAID" , "koolaid1" ); echo "Vypil nejaké $džúsy [ 0 ] šťavy." . PHP_EOL ; triedni ľudia ( Verejné $kováč = "Kovář" ; $people = noví ľudia(); echo "$people -> John vypil $juices [ 0 ] džús." . PHP_EOL ; EOD; Vypil trochu jablkového džúsu. Vypil trochu pomarančového džúsu. Napil sa fialovej šťavy. John Smith vypil trochu jablkového džúsu. John Smith potom pozdravil Jane Smith. Manželka Johna Smitha pozdravila Roberta Paulsena. Pridaná podpora PHP 7.1.0 negatívnečíselné indexy. Príklad č. 11 Záporné číselné indexy $string = "retazec" ; EOD; Znak s indexom -2 sa rovná n. Zmenou znaku na pozícii -3 na "o" vznikne nasledujúci riadok: silný Pre čokoľvek zložitejšie použite komplexnú syntax. Nazýva sa komplexný nie preto, že je ťažko pochopiteľný, ale preto, že umožňuje použitie zložitých výrazov. Akákoľvek skalárna premenná, prvok poľa alebo vlastnosť objektu namapovaná na reťazec môže byť reprezentovaná v reťazci pomocou tejto syntaxe. Jednoducho napíšte výraz rovnakým spôsobom ako mimo riadku a potom ho zabaľte {
A }
. Pretože {
nemôže byť escapované, táto syntax bude rozpoznaná iba vtedy $
nasleduje priamo
{
. Použite {\$
vytlačiť {$
. Niekoľko názorných príkladov: error_reporting(E_ALL); $skvelý = "skvelý" ; echo "Toto je ( $skvelé )" ; echo "Toto je ($skvelé)" ; ( $square -> width ) 00 centimetrov." ; echo "Toto je ($skvelé)" ; // Toto je neplatné z rovnakého dôvodu ako $foo vonku // Funguje. Pri internom používaní viacrozmerných polí // Funguje. ozvena "Funguje aj toto:( $obj -> hodnoty [ 3 ]-> meno ) " ; ozvena „Toto je hodnota pomenovanej premennej$meno : ($( $meno)) "; ozvena "Toto je hodnota názvu premennej, ktorú getName() vracia:($( getName ())) "; ozvena "Toto je hodnota premennej podľa názvu, ktorú \$object->getName() vracia:($( $object -> getName ())) "; // Nefunguje, výstupy: GetName() vracia toto: (getName()) Pomocou tejto syntaxe je tiež možné pristupovať k vlastnostiam objektu v rámci reťazcov. trieda foo( Function__construct() EOD; ja som bar. ja som bar. Komentujte: Funkcie, volania metód, statické premenné tried a konštanty tried fungujú interne {$}
, počnúc PHP 5. Zadaná hodnota sa však bude považovať za názov premennej v rovnakom kontexte ako riadok, v ktorom je definovaná. Použitie jednoduchých zložených zátvoriek ( {}
) nebude fungovať pre prístup k hodnotám funkcií, metód, konštánt triedy alebo statických premenných triedy. Niekoľko názorných príkladov: triedne pivá ( $rootbeer = "A & W" ; // Funguje to, výstupy: Chcel by som A & W // Toto funguje tiež, výstupy: Chcel by som Alexandra Keitha Znaky v reťazcoch je možné používať a upravovať zadaním ich posunu od začiatku reťazca, počnúc nulou, v hranatých zátvorkách za reťazcom, napríklad $str . Predstavte si reťazec na tento účel ako pole znakov. A Ak potrebujete získať alebo nahradiť viac ako 1 znak, môžete použiť funkcie. Komentujte:
Od PHP 7.1.0 sú podporované záporné hodnoty offsetu. Určujú odsadenie od konca riadku. Predtým záporné odchýlky spôsobili chybu úrovne E_NOTICE pri čítaní (vrátenie prázdneho reťazca) resp E_UPOZORNENIE Komentujte:
pri písaní (ponechanie riadku nezmenené). Pozornosť
K znaku v reťazci možno pristupovať aj pomocou zložených zátvoriek, napríklad $str(42) . pri čítaní (vrátenie prázdneho reťazca) resp Pokus o zápis do posunu za hranicami riadku vyplní reťazec medzerami až do tohto posunu. Neceločíselné typy sa skonvertujú na celočíselné typy. Pozornosť
Nesprávny typ posunu spôsobí chybu úrovne Komentujte:
. Použije sa iba prvý znak priradeného reťazca. Od PHP 7.1.0 spôsobí priradenie prázdneho reťazca fatálnu chybu. Predtým bol v tomto prípade priradený nulový bajt (NULL). Príklad #12 Niekoľko príkladov reťazcov $str = "Toto je test." ; $tretina = $str [ 2 ];
?>
$posledny = $str [ strlen ($str ) - 1 ]; // Zmena posledného znaku riadku$str = "Pozrite sa na more" ; 0
. $str [ strlen ($str )- 1 ] = "e" ; Od PHP 5.4 musí byť offset v reťazci špecifikovaný ako celé číslo alebo reťazec obsahujúci číslice, inak sa zobrazí varovanie. Predtým offset daný reťazcom ako "foo" Príklad #13 Rozdiely medzi PHP 5.3 a PHP 5.4 Var_dump($str["1"]); Var_dump($str["1.0"]); Var_dump($str["x"]); var_dump (isset($str [ "x" ])); Var_dump($str["1x"]); var_dump (isset($str [ "1x" ])); Komentujte: Pokus o prístup k premenným iných typov (okrem polí alebo objektov, ktoré implementujú určité rozhrania) pomocou
alebo {}
sa potichu vráti NULL. Komentujte: PHP 5.5 pridalo podporu pre prístup k znakom v reťazcových literáloch pomocou syntaxe
alebo {}
. Existuje mnoho užitočných funkcií na úpravu reťazcov. Základné funkcie sú popísané v časti o funkciách reťazcov a pre pokročilé vyhľadávanie a nahradzovanie funkcií regulárnych výrazov kompatibilných s jazykom Perl. Hodnotu je možné previesť na reťazec pomocou pretypovania (reťazec) alebo funkcie strval(). ozvena alebo Vo výrazoch, kde sa vyžaduje reťazec, sa konverzia uskutoční automaticky. Stáva sa to pri používaní funkcií vytlačiť. , alebo keď sa hodnota premennej porovnáva s reťazcom. Keď si v príručke prečítate časti Typy a Manipulácia s typmi, budú nasledujúce informácie jasnejšie. Pozri tiež settype() Polia sa vždy skonvertujú na reťazec Existujú dva typy syntaxe: jednoduchá a zložitá."Pole" ozvena alebo Vo výrazoch, kde sa vyžaduje reťazec, sa konverzia uskutoční automaticky., takže nemôžete zobraziť obsah poľa ( ), pomocou aby ste videli, čo obsahuje. Ak chcete zobraziť jeden prvok, použite niečo ako echo $arr["foo"] . Nižšie nájdete tipy, ako zobraziť/zobraziť celý obsah. Na konverziu typovej premennej "objekt" v type reťazec NULL Používa sa magická metóda __toString. Význam sa vždy skonvertuje na prázdny reťazec. A Ako vidíte vyššie, priama konverzia polí, objektov alebo zdrojov na reťazec neposkytuje žiadne užitočné informácie o samotných hodnotách okrem ich typov.. Lepším spôsobom výstupu hodnôt na ladenie je použitie funkcií print_r(). Väčšinu hodnôt v PHP je možné previesť na reťazec pre trvalé ukladanie. Táto metóda sa nazýva serializácia a možno ju vykonať pomocou funkcie serializovať () Prevod reťazcov na čísla Ak je reťazec rozpoznaný ako číselná hodnota, výsledná hodnota a typ sa určia nasledovne. Ak reťazec neobsahuje žiadny zo znakov ".", "e" alebo "E" a hodnota čísla spadá do rozsahu celých čísel (definované PHP_INT_MAX ), reťazec bude rozpoznaný ako celé číslo (). Hodnota je určená začiatkom reťazca. Ak riadok začína platnou číselnou hodnotou, použije sa táto hodnota. V opačnom prípade bude hodnota 0 (nula). Platná číselná hodnota je jedna alebo viac číslic (ktoré môžu obsahovať desatinnú čiarku), pred ktorými môže byť znamienko, za ktorým nasleduje voliteľný exponent. Exponent je "e" alebo "E", za ktorým nasleduje jedna alebo viac číslic. $foo = 1 + "10,5" ; // $foo je plavák (11.5) Viac informácií o tejto konverzii nájdete v časti o strtod(3) v dokumentácii Unix. Ak chcete otestovať niektorý z príkladov v tejto časti, skopírujte ho a prilepte ho a nasledujúci riadok, aby ste videli, čo sa stane: echo "\$foo== $foo ; napíšte: " . gettype ($foo) . " Nečakajte, že kód znaku získate jeho konverziou na celé číslo (ako sa to robí napríklad v C). Ak chcete previesť znaky na ich kódy ASCII a späť, použite funkcie ord() A chr(). pred 7 rokmi Dokumentácia to nespomína, no bodkočiarka na konci heredocu sa v skutočnosti interpretuje ako skutočná bodkočiarka a ako taká niekedy vedie k syntaktickým chybám. $foo =<< foo (<< foo (<< pred 3 rokmi Môžete použiť reťazec ako pole znakov (napríklad C) $a = "Test poľa reťazcov"; var_dump($a); var_dump($a); // -- S odovzdaním poľa -- var_dump((pole) $a); Norihiori pred 15 rokmi Môžete použiť komplexnú syntax na vloženie hodnoty vlastností objektu A metód objektu do reťazca. Napríklad... Nemôžete to však urobiť pre všetky hodnoty vo vašom mennom priestore. Konštanty triedy a statické vlastnosti/metódy nebudú fungovať, pretože zložitá syntax hľadá „$“. pred 3 rokmi Pozor, v súlade s „Prevodom reťazcov na čísla“: If ("123abc" == 123 ) echo "(intstr == int) nesprávne testuje ako pravdivé."; // Pretože jedna strana je číslo, reťazec sa nesprávne skonvertuje z intstr na int, ktorý sa potom zhoduje s testovacím číslom. // Platí pre všetky podmienky, ako sú príkazy if a switch (pravdepodobne aj cykly while)! // Toto môže byť veľké bezpečnostné riziko pri testovaní/používaní/ukladaní používateľského vstupu, zatiaľ čo očakávate a testujete iba celé číslo. // Zdá sa, že jedinou opravou je, aby 123 bol reťazec ako "123", takže nedochádza k žiadnej konverzii.
?>
pred 6 rokmi Počiatočné nuly v reťazcoch sa (najmenšieho prekvapenia) nepovažujú za osmičkové. pred 10 rokmi Tu je jednoduchý hack, ktorý umožní reťazcom a heredocom v dvojitých úvodzovkách obsahovať ľubovoľné výrazy v syntaxi zložených zátvoriek vrátane konštánt a iných volaní funkcií: // Vyhlásenie o hackovaní // Naše ihrisko
$a=
3
; funkciu c($a,
$ b) (návrat$a+
$ b; }
//Použitie // Všeobecná syntax je ($_expr(...)) pred 2 rokmi Domnievam sa, že by bolo užitočné pridať tento komentár, aby sa informácia objavila aspoň na správnej stránke na webe PHP. Upozorňujeme, že ak máte v úmysle použiť reťazec v úvodzovkách s asociatívnym kľúčom, môžete naraziť na chybu T_ENCAPSED_AND_WHITESPACE. Niektorí to považujú za jednu z menej zjavných chybových správ. Výraz ako: $ovocie=array( Tlačiť "Toto je a$ovocie[
"a"]";
// T_ENCAPSED_AND_WHITESPACE Môžete to vyriešiť nasledovne: Vo výrazoch, kde sa vyžaduje reťazec, sa konverzia uskutoční automaticky."Toto je a$ovocie[
a]
"
;
// zrušte úvodzovku kľúča Nie je jasné (aspoň mne), prečo PHP nesprávne interpretuje jednu úvodzovku vo výraze, ale myslím si, že to má niečo spoločné s faktom, že úvodzovky nie sú súčasťou reťazca hodnôt - akonáhle sa reťazec už analyzuje, úvodzovky jednoducho prekážať...? pred 2 rokmi Oboje by malo fungovať :(
triedaTestovanie{ Verejná funkcia povedzHelloStatic() { Verejná funkcia povedz ahojConst() {
$obj= novýTestovanie(); pred 3 rokmi Niečo, čo som zažil, čo nepochybne niekomu pomôže. . . $html =<<<"EOD" Pomocou tohto zobrazíte všetky rovnaké farby: $html =<< značne uľahčuje prácu pred 11 rokmi Aby ste si ušetrili myseľ, nečítajte predchádzajúce komentáre o dátumoch ;) Keď je možné previesť oba reťazce na číselné hodnoty (v teste ("$a" > "$b")), potom sa použijú výsledné číselné údaje, inak sa porovnávajú celé reťazce po znakoch: var_dump("1.22"
>
"01.23"
);
//bool(false) (PHP 4, PHP 5, PHP 7) str_replace — Nahradí všetky výskyty hľadaného reťazca náhradným reťazcom Táto funkcia vráti reťazec alebo pole so všetkými výskytmi hľadania v predmete nahradenými výrazom nahradiť . Ak nie sú potrebné zložité pravidlá vyhľadávania/nahradenia (napríklad regulárne výrazy), je lepšie použiť túto funkciu preg_replace(). Ak vyhľadávanie a nahradenie sú polia, potom str_replace() používa každú hodnotu z príslušného poľa na vyhľadávanie a nahradenie v predmete . Ak má náhradné pole menej prvkov ako search , ako náhradný reťazec pre zostávajúce hodnoty sa použije prázdny reťazec. Ak je vyhľadávanie pole a nahradenie je reťazec, tento náhradný reťazec sa použije pre každý prvok poľa vyhľadávania. Opačný prípad nedáva zmysel. Ak sú pole hľadať alebo nahradiť, ich prvky budú spracované od prvého po posledný. Hodnota vyhľadávania, známa aj ako ihla (ihla). Pole môžete použiť pre viacero vyhľadávacích hodnôt. Nahradiť Nahradená hodnota sa použije na nahradenie hľadaných hodnôt. Pole môžete použiť pre viacero hodnôt. Predmet Reťazec alebo pole, na ktorom sa vyhľadáva a nahrádza, je tiež známy ako kopa sena (kopa sena). Ak je predmet pole, vyhľadávanie a nahradenie sa vykoná na každom prvku predmetu a výsledkom funkcie bude tiež pole. Táto funkcia vráti reťazec alebo pole s nahradenými hodnotami. Príklad č. 1 Príklady použitia str_replace()
// priradí // priradí: Hll Wrld f PHP // priradí: Každý deň by ste mali jesť pizzu, pivo a zmrzlinu $newphrase = str_replace($zdravé, $mňam, $fráza); // priraďuje: 2 Príklad č. 2 Príklady možných trikov s str_replace()
// Objednávka náhrady // Procesy \r\n ako prvé, aby sa predišlo ich opätovnému nahradeniu. // Vytlačí F, pretože A je nahradené B, potom B C a tak ďalej... // Výstupy: applerootrootnut (z vyššie uvedeného dôvodu) Komentujte: Táto funkcia je bezpečná na spracovanie údajov v binárnej forme. POZOR
Pretože str_replace() vykoná nahradenie zľava doprava, potom pri použití viacerých náhrad môže nahradiť predtým vloženú hodnotu inou. Komentujte: Pozrite si aj príklady na tejto stránke. Táto funkcia rozlišuje malé a veľké písmená. Použite str_ireplace() Tabuľky: 3 | OJSC Pyschpyshch | Soldatodachestroyskoe 404 3 | Veľká rekonštrukcia 3 | 3 | 2 | | %text% V skutočnosti je problém, že tretia tabuľka by sa mala zobraziť vo webovom formulári „výber objednávky“ a namiesto ID je potrebné nahradiť zodpovedajúce polia z iných stĺpcov. kód: INSERT INTO "table_name" ("zoznam") VALUES ("bla-bla") Syntax Nowdoc
Manipulácia s premennými v reťazcoch
Reťazenie
Syntax
Jednoduché úvodzovky
postava z nového riadku, ako je táto,
Toto je fajn";
ozvena "Jedného dňa Arnold povedal: "Vrátim sa.";
echo "Vymazali ste C:\*.*?" ;
ozvena "Toto sa nerozbalí: \n nový riadok";
ozvena "$expand a $either premenné nie sú rozšírené";
?>
Dvojité úvodzovky
Únikové sekvencie
Následná sekvencia
Význam
\n
nový riadok (LF alebo 0x0A (10) v ASCII)
\r
návrat vozíka (CR alebo 0x0D (13) v ASCII)
\t
horizontálna karta (HT alebo 0x09 (9) v ASCII)
\v
vertikálna karta (VT alebo 0x0B (11) v ASCII) (od PHP 5.2.5)
\e
escape znak (ESC alebo 0x1B (27) v ASCII) (od PHP 5.4.4)
\f
zoznam stránok (FF alebo 0x0C(12) v ASCII) (od PHP 5.2.5)
\\
spätné lomítko
\$
znak dolára
\"
dvojitý citát
\{1,3}
sekvencia znakov, ktoré sa zhodujú s regulárnym výrazom osmičkového znaku, ktorý ticho preteká, aby sa zmestil do bajtu (t. j. "\400" === "\000")
\x(1,2)
postupnosť znakov zodpovedajúca regulárnemu výrazu znaku v hexadecimálnom zápise
\u(+)
sekvencia znakov zodpovedajúcich regulárnemu výrazu znakov Unicode, ktorý sa mapuje na reťazec v reprezentácii UTF-8 (pridané v PHP 7.0.0)
Heredoc
verejný $bar =<<
EOT;
// odsadenie pred koncovým identifikátorom nie je povolené
}
?>
verejný $bar =<<
EOT;
}
?>
Príklad č. 3 Príklad definície reťazca Heredoc
$str =
Príklad riadku,
{
pomocou syntaxe heredoc.
EOD;
{
var $foo ;
var $bar ;
}
}
$this -> foo = "Foo" ;
$meno = "Meno" ; ozvena .
Moje meno je "$name". Píšem $foo -> foo
EOT;
?>
Od verzie 5.3.0 je možné inicializovať statické premenné a vlastnosti/konštanty triedy pomocou syntaxe heredoc:
{
Príklad #5 Použitie heredoc na inicializáciu statických premenných<<
Nič tu nie je...
{
ŠTÍTOK;<<
trieda foo
trieda foo
}
?>
Verejný $baz =
Príklad #7 Príklad použitia nowdoc
Ukážkový text,
zahŕňajúce niekoľko riadkov
pomocou syntaxe nowdoc. So spätnými lomkami sa vždy zaobchádza doslova,
napríklad \\ a \".
Nič tu nie je...
{
/* Zložitejší príklad s premennými. */
verejné $foo ;
{
var $foo ;
verejný $bar ;
}
}
$this -> foo = "Foo" ;
$this -> bar = array("Bar1" , "Bar2" , "Bar3" );
Moje meno je "$name". Tlačím $foo->foo.
Teraz tlačím ($foo->bar).
EOT;
?>
verejný $bar =<<<"EOT"
bar
EOT;
}
?>
Podpora nowdoc bola pridaná v PHP 5.3.0.
) s minimálnym úsilím.
echo "Vypil nejaký $džúsový džús." . PHP_EOL ;
echo "Vypil nejaký džús vyrobený z $džúsov." ;
?>
$juices = array("jablko" , "pomaranč" , "koolaid1" => "fialová" );
echo "Vypil nejaké $džúsy [ 1 ] šťavy." . PHP_EOL ;
echo "Vypil nejaké $džúsy [ koolaid1 ] džús." . PHP_EOL ;
public $john = "John Smith" ;
public $jane = "Jane Smith" ;
public $robert = "Robert Paulsen" ;
}
echo " $people -> john potom pozdravil $people -> jane ." . PHP_EOL ;
echo "$people -> manželka Johna pozdravila $people -> robert." . PHP_EOL;
echo " $people -> robert pozdravil dvoch $people -> smiths ." ; // Nefunguje
?>
ozvena „Znak na indexe -2 sa rovná$string [- 2 ] ." , PHP_EOL ;
$string [- 3 ] = "o" ;
ozvena "Zmena znaku na pozícii -3 na "o" vytvorí nasledujúci riadok:$string." , PHP_EOL;
?>
Komplexná (kučeravá) syntax
// Zobraziť všetky chyby
// Nefunguje, výstupy: Toto je (skvelé)
// Práce, výstupy: Toto je skvelé
ozvena // Funguje„Toto námestie je široké
echo "Funguje to: ( $arr [ "kľúč" ]) " ;
echo "Funguje to: ( $arr [ 4 ][ 3 ]) " ;
// riadky. Inými slovami, stále to bude fungovať,
// ale keďže PHP hľadá najprv konštantu foo, spôsobí to
// chyba úrovne E_NOTICE (nedefinovaná konštanta).
ozvena "Toto je nesprávne:( $arr [ foo ][ 3 ]) " ;
// riadky vždy používajú zložené zátvorky
echo "Funguje to: ( $arr [ "foo" ][ 3 ]) " ;
echo "Funguje to: ". $arr [ "foo" ][ 3 ];
ozvena "Toto vracia getName(): (getName())";
?>
var $bar = "Ja som bar." ;
}
$bar = "bar" ;
$baz = array("foo" , "bar" , "baz" , "quux" );
echo " ( $foo -> $bar ) \n" ;
echo " ( $foo ->( $baz [ 1 ])) \n" ;
?>
// Zobraziť všetky chyby
const softdrink = "koreňové pivo" ;
public static $ale = "ipa" ;
}
$ipa = "S Alexandrom Keithom" ;
echo "Chcel by som ($( piva :: nealkoholický nápoj )) \n" ;
echo "Chcel by som ($( piva :: $ale )) \n" ;
?>
Prístup a zmena znaku v reťazci
Reťazce v PHP sú interne polia bajtov. V dôsledku toho nie je prístup alebo úprava reťazca s posunom bezpečné pre viacbajtové kódovanie a malo by sa vykonávať iba s reťazcami v jednobajtových kódovaniach, ako je ISO-8859-1.
Od PHP 7.1.0 spôsobí použitie prázdneho indexu predtým fatálnu chybu, v tomto prípade bol reťazec konvertovaný na pole bez varovania.
// Získa prvý znak reťazca
$first = $str [ 0 ];
// Získame tretí znak reťazca
// Získanie posledného znaku reťazca
$str = "Toto je stále test." ;
, sa bez varovania premenil na
$str = "abc" ;
var_dump (isset($str [ "1" ]));
var_dump (isset($str [ "1.0" ]));
?>
Previesť na reťazec
var_dump()
$foo = 1 + "-1,3e3" ; // $foo je plavák (-1299)
$foo = 1 + "bob-1.3e3" ; // $foo je celé číslo (1)
$foo = 1 + "bob3" ; // $foo je celé číslo (1)
$foo = 1 + "10 malých prasiatok" ; // $foo je celé číslo (11)
$foo = 4 + "10,2 malých prasiatok" ; // $foo je plavák (14.2)
$foo = "10,0 ošípaných" + 1 ; // $foo is float (11)
$foo = "10,0 ošípaných" + 1,0 ; // $foo is float (11)
?>
\n" ;
?>
Podrobnosti implementácie typu reťazca
KONIEC;
?>
Toto neplatí:
KONIEC;
);
// chyba syntaxe, neočakávané ";"
?>
Bez bodkočiarky to funguje dobre:
KONIEC
);
?>
// Vráti reťazec(17) "Test poľa reťazcov"
// Vrátiť reťazec (1) "S"
var_dump((pole) $a);
// Vráti pole(1) ( => string(17) "Test poľa reťazcov")
// Vráti reťazec (17) "S"
triedny test(
verejné $jeden = 1 ;
verejná funkcia dva() (
návrat 2;
}
}
$test = new Test();
echo "foo ( $test -> jeden ) pruh ( $test -> dva ()) " ;
?>
Výstup "foo 1 bar 2".
triedny test(
const JEDEN = 1 ;
}
echo "foo (Test::ONE) bar" ;
?>
Výsledkom bude „foo (Test::one) bar“. Konštanty a statické vlastnosti vyžadujú, aby ste reťazec prerušili.
Zvážte:
$x = "0123" + 0;
$y = 0123 + 0;
echo "x je $x, y je $y"; //vytlačí "x je 123, y je 83"
inými slovami:
* úvodné nuly v číselných literáloch v zdrojovom kóde sa interpretujú ako "osmičkové", porov. strtol().
* úvodné nuly v reťazcoch (napr. údaje zadané používateľom), keď sa pretypujú (implicitne alebo explicitne) na celé číslo, sa ignorujú a považujú sa za desiatkové, c.f. strtod().
funkcia _expr ($v) (vráti $v; )
$_expr = "_expr" ;
define("qwe" ,
"asd");
definovať("zxc",
5
);
$ b=
4
;
ozvena"pre{
$_expr(1
+
2
)}
príspevok\n";
// výstupy "pre 3 post"
ozvena"pre{
$_expr(qwe)}
príspevok\n";
// výstupy "pre asd post"
ozvena"pre{
$_expr(c($a,
$ b)+
zxc*
2
)}
príspevok\n";
// výstupy "pre 17 post"
?>
"a"=>
"jablko",
"b"=>
"banán",
//atď
);
?>
určite sa rozpadne na kusy.
Vo výrazoch, kde sa vyžaduje reťazec, sa konverzia uskutoční automaticky."Toto je a${
ovocie[
"a"]}
"
;
// Komplexná syntax
Vo výrazoch, kde sa vyžaduje reťazec, sa konverzia uskutoční automaticky."Toto je a{
$ovocie[
"a"]}
"
;
// Komplexná variácia syntaxe
?>
Osobne preferujem poslednú variáciu, pretože je prirodzenejšia a bližšie k tomu, aký by bol výraz mimo sláčika.
verejná statika$ VAR=
"statický";
public const VAR ="const";
ozvena"ahoj:{
$this::
$ VAR}
"
;
}
ozvena"ahoj:{
$this::VAR)"
;
// Chyba analýzy: chyba syntaxe, neočakávané ")", očakáva sa "["
}
}
$obj->
povedzHelloStatic();
$obj->
povedz ahojConst();
V mojom editore to zvýrazní syntax HTML a komentár $:
$komentár
Príklad riadku,
Príklad riadku,
var_dump("1.22.00"
>
"01.23.00"
);
//bool(true)
var_dump("1-22-00"
>
"01-23-00"
);
//bool(true)
var_dump((plávajúci)"1.22.00"
> (plávajúci)"01.23.00"
);
//bool(false)
?>
Popis
Zoznam parametrov
Návratové hodnoty
Príklady
$bodytag = str_replace ("%body%" , "black" , "
$hlasky = array("a" , "e" , "i" , "o" , "u" , "A" , "E" , "I" , "O" , "U" );
$onlyconsonants = str_replace ($vowels , "" , "Ahoj svet PHP" );
$phrase = "Mali by ste jesť ovocie, zeleninu a vlákninu každý deň.";
$healthy = array("ovocie" , "zelenina" , "vláknina" );
$yummy = array("pizza" , "pivo" , "zmrzlina" );
$str = str_replace ("ll" , "" , "dobrá slečna Molly!" , $count );
echo $počet ;
?>
$str = "Riadok 1\nRiadok 2\rRiadok 3\r\nRiadok 4\n";
$poradie = pole("\r\n" , "\n" , "\r" );
$nahradiť = "
"
;
echo $newstr = str_nahradit ($poradie, $nahradit, $str);
// V dôsledku toho bude E nahradené F, pretože nahradenie prebieha zľava doprava.
$search = array("A" , "B" , "C" , "D" , "E" );
$nahradit = pole("B" , "C" , "D" , "E" , "F" );
$predmet = "A" ;
echo str_replace ($hľadať, $nahradiť, $predmet);
$písmená = pole("ja" , "asi" );
$ovocie = pole("jablko" , "orech" );
$text = "Chystám sa" ;
$output = str_replace ($písmená, $ovocie, $text);
echo $výstup ;
?>
Poznámky
Poznámka k postupu výmeny
pre výmenu bez ohľadu na veľkosť písmen.
C_id | Spoločnosť | Poloha
1 | LLC Hľadať | Kudykino ihrisko 15/3
2 | JSC Elita | Slunysvalinsk 133/7
Typ opravy (repair_types)
r_id | Typy opráv |
1 | Kladivo + klince
2 | Vedenie krásy
Zoznam objednávok (zoznam)
l_id | Kto | Čo treba | Čas | Komentár operátora
1 | 1 | 2 | %timestamp% | %operator_text%
2 | 2 | 1 | | %text%
Tabuľka č.1 obsahuje zoznam klientov.
Tabuľka č. 3 obsahuje zoznam aktuálnych zákaziek pre operačné tímy. Táto tabuľka je pravidelne aktualizovaná a na jej vyplnenie slúži webový formulár. Keďže prichádza pomerne veľa objednávok, do tabuľky sa zapisujú záznamy vo forme ID zákazníka a služby.
$dotaz = "VYBRAŤ * ZO zoznamu";
$vysledok = mysql_query($dotaz);
while($row=mysql_fetch_array($result. // prevziať výsledky z každého riadku
( echo "";// výstupné údaje
}
CREATE TABLE "table_name" ("id" int(255) NOT NULL AUTO_INCREMENT, text "list" (80) NOT NULL, PRIMARY KEY("id".
najlepšia odpoveď $dotaz =
"
vyberte firmy.Spoločnosť, typy_oprav.Druhy_opráv, zoznam.komentár_l
zo zoznamu
vnútorné spoločnosti
na zozname.Kto = spolocnosti.c_id
typy_opráv vnútorného spojenia
na zozname."Čo je potrebné" = repair_types.r_id
";