Jaký je rozdíl mezi jednoduchými a dvojitými uvozovkami v php. Jaký je rozdíl mezi jednoduchými a dvojitými uvozovkami v PHP? Podrobnosti implementace typu řetězce

Není žádným tajemstvím, že uvozovky v PHP mohou být jednoduché nebo dvojité. Pojďme zjistit, kdy jsou některá použití uvozovek vhodnější.

Jednoduché uvozovky

Nejjednodušší způsob, jak definovat řetězec, je uzavřít text do jednoduchých uvozovek.

Pokud potřebujeme v textu použít jednu uvozovku, musíme ji escapovat lomítkem (\).

Escape sekvence v jednoduchých uvozovkách nefungují.

Příklady použití jednoduchých uvozovek:

Dvojité uvozovky

Pokud text zvýrazníte dvojitými uvozovkami, bude řetězec definován stejným způsobem jako u jednoduchých uvozovek. Ale mezi uvozovkami jsou samozřejmě rozdíly.

Situace s uvozovkami je stejná jako u jednoduchých uvozovek.

Řetězec, který je uzavřen do dvojitých uvozovek, rozpozná většinu sekvencí escape pro speciální znaky.

Nejdůležitější rozdíl je ve skutečnosti, že dvojité uvozovky zpracovávají proměnné.

Příklady použití dvojitých uvozovek:

Zaměřme se na to, že řetězce s dvojitými uvozovkami zpracovávají proměnné.

Co se stane, když je řetězec zpracován? Tlumočník zkontrolujte každý řetězec pomocí dvojitých uvozovek pro proměnné, tj. dojde k nucené analýze, která zabere více času. Ano, často je to zlomek vteřiny, ale je třeba pochopit samotný fakt. To znamená, že pokud porovnáte zpracování jednoho řetězce s různými uvozovkami (samozřejmě bez proměnných), tak řetězec s jednoduchými uvozovkami bude určitě zpracován rychleji.

Výpočty

Na stránkách ProfiPHP jsem našel zajímavé výpočty pro toto téma. Autor napsal jednoduchý skript, pomocí kterého spočítal čas na zpracování řetězců.

Tento krátký článek ukazuje, jak a kde používat uvozovky v PHP.

Jednoduché uvozovky (apostrofy) v PHP

Řetězce uzavřené v jednoduchých uvozovkách PHP žádným způsobem nezpracovává. To znamená, že jednoduché uvozovky představují text uzavřený mezi nimi tak, jak je.

// Správné echo "Jak jde život?"; echo "Jak jde život? $jméno"; echo "Jak jde život?".$name; // Nesprávné echo "Jak se máš? $name";

Speciální znaky v jednoduchých a dvojitých uvozovkách

Chcete-li zajistit, že například znak tabulátoru (\t) bude interpretován jako znak tabulátoru a nikoli jako lomítko a písmeno t, musíte řádek textu obsahující znak tabulátoru uzavřít do dvojitých uvozovek. \' a \\ můžete použít pouze v jednoduchých uvozovkách. Všechny ostatní sekvence escape (\n, \r, \$ atd.) nejsou v jednoduchých uvozovkách povoleny.

// Nesprávné echo "Jak se máš?\n"; // Správné echo "Jak se máš?\n";

Chcete-li v řetězci ukončit dvojité uvozovky, umístěte je před zpětné lomítko \" .

// Nesprávná ozvěna "

Co se děje?

"; // Správná ozvěna"

Co se děje?

"; echo"

Co se děje?

";

Dvojité uvozovky v PHP

S textem uzavřeným v uvozovkách se zachází velmi odlišně. Například proměnné uzavřené v uvozovkách jsou nahrazeny svými hodnotami. To usnadňuje kompilaci SQL dotazy pomocí dvojitých uvozovek.

$dotaz = "INSERT INTO tabulky (příspěvek,autor,text,datum) VALUES ("$id","$author","$text","$datum"");

Nejsem odborník na programování v PHP, ale jsem trochu zmatený, proč v PHP vidím nějaký kód s řetězcem uzavřeným v jednoduchých a někdy i dvojitých uvozovkách.

Vím jen, že v jazyce .NET nebo C, pokud je to v jednoduchých uvozovkách, znamená to, že je to znak a ne řetězec.

Řešení

Co byste měli vědět

$a = "jméno"; $b = "moje $a"; == "moje jméno" $c = "moje $a"; != "moje jméno"

V PHP lidé používají jednoduché uvozovky k definování konstantního řetězce jako "a" , "moje jméno" , "abc xyz", zatímco používají dvojité uvozovky k definování řetězce obsahujícího identifikátor jako "a $b $c $d" .

A další věc je

Echo "mé jméno";

rychlejší než

Echo "mé jméno";

Echo "můj". $a;

pomalejší než

Echo "můj $a";

To platí pro ostatní použité řetězce.

V PHP je text v jednoduchých uvozovkách považován za hodnotu řetězce, zatímco text ve dvojitých uvozovkách analyzuje proměnné nahrazením a zpracováním jejich hodnoty.

$test = "proměnná"; echo "Dobrý den pane $test"; // výstup by byl: Hello Mr variable echo "Hello Mr $test"; // výstup by byl: Dobrý den, pane $test

Zde dvojitá uvozovka analyzuje hodnotu a jednoduchá uvozovka je považována za řetězcovou hodnotu (bez analýzy proměnné $test.)

Oba druhy vnořených znaků jsou řetězce. Je vhodné použít jeden typ nabídky k uzavření jiného typu nabídky. """ a """ Největší rozdíl mezi typy uvozovek je ten, že odkazy na vnořené identifikátory jsou nahrazeny uvnitř dvojitých uvozovek, nikoli uvnitř jednoduchých uvozovek.

Nejjednodušší způsob, jak definovat řetězec, je uzavřít jej do jednoduchých uvozovek (symbol " ).

Chcete-li v řetězci použít jednu uvozovku, uzavřete ji zpětným lomítkem ( \ ). Pokud potřebujete napsat zpětné lomítko samotné, zkopírujte jej ( \\ ). Všechna ostatní použití zpětných lomítek budou interpretována jako normální znaky: to znamená, že pokud se pokusíte použít jiné únikové sekvence, jako např. \r nebo \n, budou vystupovat tak, jak jsou, namísto jakéhokoli zvláštního chování.

echo "toto je jednoduchý řetězec";

echo „Lze vkládat i do řádků
postava z nového řádku, jako je tato,
Tohle je fajn"
;

// Výstupy: Arnold jednou řekl: "Vrátím se"
echo "Jednoho dne Arnold řekl: 'Vrátím se''.";

Echo "Smazali jste C:\\*.*?";

// Výstupy: Smazali jste C:\*.*?
echo "Smazali jste C:\*.*?" ;

// Výstupy: Toto nebude rozbaleno: \n nový řádek
echo "Toto nebude rozbaleno: \n nový řádek";

// Výstupy: $expand a $either proměnné nejsou expandovány
echo "$expand a $either proměnné nejsou rozbaleny";
?>

Dvojité uvozovky

Pokud je řetězec uzavřen do dvojitých uvozovek ("), PHP rozpozná více escape sekvencí pro speciální znaky:

Únikové sekvence
Subsekvence Význam
\n nový řádek (LF nebo 0x0A (10) v ASCII)
\r návrat vozíku (CR nebo 0x0D (13) v ASCII)
\t horizontální karta (HT nebo 0x09 (9) v ASCII)
\proti vertikální karta (VT nebo 0x0B (11) v ASCII) (od PHP 5.2.5)
\E znak escape (ESC nebo 0x1B (27) v ASCII) (od PHP 5.4.4)
\F seznam stránek (FF nebo 0x0C (12) v ASCII) (od PHP 5.2.5)
\\ obrácené lomítko
\$ znak dolaru
\" dvojitá citace
\{1,3} posloupnost znaků odpovídající regulárnímu výrazu znaku v osmičkové číselné soustavě
\x(1,2) posloupnost znaků odpovídající regulárnímu výrazu znaku v hexadecimálním zápisu

Stejně jako u řetězce uzavřeného v jednoduchých uvozovkách, escapování jakéhokoli znaku také vypíše samotné zpětné lomítko. Před PHP 5.1.1 zpětné lomítko \($var) nebyl zveřejněn.

Heredoc

Třetí způsob, jak definovat řetězce, je použít syntaxi heredoc: <<< . Po tomto operátoru musíte zadat identifikátor a poté odřádkování. Poté následuje samotný řádek a poté stejný identifikátor, který uzavírá vkládání.

Čára musí začít uzavíracím identifikátorem, tzn. musí se objevit v prvním sloupci řádku. Identifikátor se navíc musí řídit stejnými pravidly pro pojmenování jako všechny ostatní značky v PHP: obsahovat pouze alfanumerické znaky a podtržítko a nesmí začínat číslem (podtržítka jsou povolena).

Pozornost

Je velmi důležité si uvědomit, že závěrečný řádek identifikátoru nesmí obsahovat žádné jiné znaky kromě středníku ( ; ). To znamená, že id by nemělo být odsazeno a že před ani za středníkem nemohou být žádné mezery ani tabulátory. Je také důležité pochopit, že první znak před koncovým identifikátorem musí být znak nového řádku, jak je definováno vaším operačním systémem. Například na systémech UNIX, včetně Mac OS X, toto \n. Bezprostředně za koncovým identifikátorem musí také začínat nový řádek.

Pokud je toto pravidlo porušeno a koncový identifikátor není „čistý“, považuje se koncový identifikátor za chybějící a PHP jej bude dále hledat. Pokud v tomto případě není nikdy nalezen správný uzavírací identifikátor, způsobí to chybu analýzy s číslem řádku na konci skriptu.

Heredoc nelze použít k inicializaci polí třídy. Počínaje PHP 5.3 se toto omezení vztahuje pouze na heredocs obsahující proměnné.

Příklad č. 1 Špatný příklad

třída foo(
veřejný $bar =<<bar
EOT;
}
?>

Text Heredoc se chová stejně jako řetězec ve dvojitých uvozovkách, aniž by je měl. To znamená, že v heredoc nemusíte uvozovky escapovat, ale stále můžete použít sekvence escape výše. Proměnné se zpracovávají, ale při používání složitých proměnných uvnitř heredocu musíte být stejně opatrní jako při práci s řetězci.

Příklad č. 2 Příklad definování řetězce heredoc

$str =<<Příklad řádku,
pokrývající několik řádků,
pomocí syntaxe heredoc.
EOD;

Třída foo
{
var $foo ;
var $bar ;

Funkce foo()
{
$this -> foo = "Foo" ;
$this ->
}
}

$foo = new foo();
$jméno = "MojeJméno" ;

echo<<Jmenuji se "$name". Píšu $foo -> foo .
Teď dedukuji
( $foo -> bar [ 1 ]) .
Výsledkem by mělo být velké písmeno "A": \x41
EOT;
?>

Jmenuji se "MyName". Píšu Foo. Nyní vypíšu Bar2. Výsledkem by mělo být velké písmeno "A": A

Je také možné použít syntaxi heredoc k předání dat prostřednictvím argumentů funkce:

Od verze 5.3.0 je možné inicializovat statické proměnné a vlastnosti/konstanty třídy pomocí syntaxe heredoc:

Příklad #4 Použití heredoc k inicializaci statických proměnných

// Statické proměnné
funkce foo()
{
statický $bar =<<Nic tu není...
OZNAČENÍ;
}

// Vlastnosti/konstanty třídy
třída foo
{
const BAR =<<Příklad použití konstanty
FOOBAR;

Veřejný $baz =<<Příklad použití pole
FOOBAR;
}
?>

Od PHP 5.3.0 můžete také umístit identifikátor Heredoc do dvojitých uvozovek:

Nowdoc

Nowdoc je stejný pro řetězce v jednoduchých uvozovkách jako heredoc pro řetězce s dvojitými uvozovkami. Nowdoc je podobný jako heredoc, ale uvnitř nejsou prováděny žádné náhrady. Tento design je ideální pro vkládání kódu PHP nebo jiných velkých bloků textu, aniž byste jej museli opustit. V tomto je trochu podobný konstruktu SGML prohlášením bloku textu, který není určen ke zpracování.

Nowdoc je označen stejnou sekvencí <<< , který se používá v heredoc, ale následující identifikátor je uzavřen v jednoduchých uvozovkách, např. <<<"EOT" . Všechny podmínky, které se vztahují na identifikátory heredoc, se vztahují také na nowdoc, zejména ty, které se vztahují na uzavírací identifikátor.

Příklad č. 6 Příklad Nowdoc

$str =<<<"EOD"
Ukázkový text,
zahrnující několik linií
pomocí syntaxe nowdoc.
EOD;

/* Složitější příklad s proměnnými. */
třída foo
{
veřejné $foo ;
veřejný $bar ;

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

$foo = new foo();
$jméno = "MojeJméno" ;

echo<<<"EOT"
Jmenuji se "$name". Tisknu $foo->foo.
Nyní tisknu ($foo->bar).
To by nemělo vypsat velké "A": \x41
EOT;
?>

Výsledek spuštění tohoto příkladu:

Jmenuji se "$name". Tisknu $foo->foo. Nyní tisknu ($foo->bar). To by nemělo vypsat velké "A": \x41

Komentář:

Na rozdíl od heredoc lze nowdoc použít v jakémkoli kontextu se statickými daty. Typický příklad inicializace polí třídy nebo konstant:

Příklad č. 7 Příklad použití statických dat

třída foo(
veřejný $bar =<<<"EOT"
bar
EOT;
}
?>

Komentář:

Podpora nowdoc byla přidána do PHP 5.3.0.

Manipulace s proměnnými

Pokud je řetězec zadán v uvozovkách nebo pomocí heredoc, jsou zpracovány proměnné v něm obsažené.

Existují dva typy syntaxe: jednoduchá a složitá. Jednoduchá syntaxe je jednodušší a pohodlnější. Umožňuje zpracovat proměnnou, hodnotu pole ( pole) nebo vlastnosti objektu ( objekt) s minimálním úsilím.

Složitou syntaxi lze identifikovat podle složených závorek obklopujících výraz.

Jednoduchá syntaxe

Pokud tlumočník narazí na znak dolaru ( $ ), zachytí co nejvíce znaků, aby vytvořil platný název proměnné. Pokud chcete zadat konec názvu, uzavřete název proměnné do složených závorek.

$džus = "jablko" ;

echo "Vypil nějaký $džusový džus." . PHP_EOL ;
// nefunguje, "s" je platný znak pro název proměnné,
// ale naše proměnná se jmenuje $džus.
echo "Vypil nějaký džus vyrobený z $džusů." ;
?>

Výsledek spuštění tohoto příkladu:

Vypil trochu jablečného džusu. Vypil trochu šťávy z .

Prvek pole ( pole) nebo vlastnost objektu ( objekt). V indexech pole je uzavírací hranatá závorka ( ] ) označuje konec definice indexu. Pro vlastnosti objektu platí stejná pravidla jako pro jednoduché proměnné.

Příklad #8 Jednoduchý příklad syntaxe

$juices = array("jablko" , "oranžová" , "koolaid1" => "fialová" );

echo "Vypil nějaké $džusy [ 0 ] džusu." . PHP_EOL ;
echo "Vypil nějaké $džusy [ 1 ] džus." . PHP_EOL ;
echo "Vypil nějaké $džusy [ koolaid1 ] džus." . PHP_EOL ;

třídní lidé (
public $john = "Jan Smith" ;
public $jane = "Jane Smith" ;
public $robert = "Robert Paulsen" ;

Veřejné $kovář = "Kovář" ;
}

$people = noví lidé();

echo "$people -> John vypil $džusy [ 0 ] džus." . PHP_EOL ;
echo " $people -> john pak pozdravil $people -> jane ." . PHP_EOL ;
echo "$people -> manželka Johna pozdravila $people -> robert." . PHP_EOL;
echo " $people -> robert pozdravil dva $people -> kováři." ; // Nefunguje
?>

Výsledek spuštění tohoto příkladu:

Vypil trochu jablečného džusu. Vypil trochu pomerančového džusu. Vypil trochu fialového džusu. John Smith vypil trochu jablečného džusu. John Smith pak řekl ahoj Jane Smith. Manželka Johna Smithe pozdravila Roberta Paulsena a Robert Paulsen ty dva pozdravil.

Pro cokoliv složitějšího použijte komplexní syntaxi.

Složitá (složená) syntaxe

Nazývá se složitým ne proto, že je obtížné mu porozumět, ale proto, že umožňuje použití složitých výrazů.

Jakákoli skalární proměnná, prvek pole nebo vlastnost objektu namapovaná na řetězec mohou být reprezentovány v řetězci pomocí této syntaxe. Stačí napsat výraz stejným způsobem jako mimo řádek a poté jej zabalit { A } . Protože { nelze escapovat, tato syntaxe bude rozpoznána pouze tehdy $ následuje přímo { . Použití {\$ vytisknout {$ . Několik názorných příkladů:

// Zobrazit všechny chyby
error_reporting(E_ALL);

$skvělý = "skvělý" ;

// Nefunguje, výstupy: To je (skvělé)
echo "To je ( $skvělý )" ;

// Práce, výstupy: To je skvělé
echo "To je ( $skvělý ) " ;
echo "Toto je $( skvělé )" ;

// Funguje
echo „Tohle náměstí je široké( $čtverec -> šířka ) 00 centimetrů." ;

// Funguje, klíčová slova v uvozovkách fungují pouze se syntaxí složených závorek
echo "Funguje to: ( $arr [ "klíč" ]) " ;

// Funguje
echo "Funguje to: ( $arr [ 4 ][ 3 ]) " ;

// Toto je neplatné ze stejného důvodu jako $foo venku
// řádky. Jinými slovy, bude to stále fungovat,
// ale protože PHP nejprve hledá konstantní foo, způsobí to
// chyba úrovně E_NOTICE (nedefinovaná konstanta).
echo "Není to správné:( $arr [ foo ][ 3 ]) " ;

// Funguje. Při použití vícerozměrných polí interně
// řádky vždy používají složené závorky
echo "Funguje to: ( $arr [ "foo" ][ 3 ]) " ;

// Funguje.
echo "Funguje to: ". $arr [ "foo" ][ 3 ];

echo "Tohle taky funguje:( $obj -> hodnoty ​​[ 3 ]-> jméno ) ";

echo "Toto je hodnota pojmenované proměnné$jméno : ($( $jméno)) ";

echo "Toto je hodnota názvu proměnné, kterou getName() vrací:($( getName ())) ";

echo "Toto je hodnota proměnné podle názvu, kterou \$object->getName() vrací:($( $object -> getName ())) ";

// Nefunguje, výstupy: GetName() vrací toto: (getName())
echo "Toto vrací getName(): (getName())";
?>

Pomocí této syntaxe je také možné přistupovat k vlastnostem objektů v řetězcích.

třída foo(
var $bar = "Jsem bar." ;
}

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

Výsledek spuštění tohoto příkladu:

Jsem bar. Jsem bar.

Komentář:

Funkce, volání metod, statické proměnné třídy a konstanty třídy fungují interně {$} , počínaje PHP 5. Zadaná hodnota však bude považována za název proměnné ve stejném kontextu jako řádek, ve kterém je definována. Použití jednoduchých složených závorek ( {} ) nebude fungovat pro přístup k hodnotám funkcí, metod, konstant třídy nebo statických proměnných třídy.

// Zobrazit všechny chyby
error_reporting(E_ALL);

třídní piva (
const softdrink = "kořenové pivo" ;
public static $ale = "ipa" ;
}

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

// Funguje to, výstupy: Chtěl bych A & W
echo "Rád bych ($( piva :: nealkoholický nápoj )) \n" ;

// Toto funguje také, výstupy: Chtěl bych Alexandra Keitha
echo "Chtěl bych ($( piva :: $ale )) \n" ;
?>

Přístup a změna znaku v řetězci

Znaky v řetězcích lze použít a upravit zadáním jejich posunutí od začátku řetězce, počínaje nulou, v hranatých závorkách za řetězcem, například $str . Představte si řetězec pro tento účel jako pole znaků. Pokud potřebujete získat nebo nahradit více než 1 znak, můžete použít funkce substr() A substr_replace().

Komentář: Ke znaku v řetězci lze také přistupovat pomocí složených závorek, například $str(42) .

Pozornost

Pokus o zápis do posunu za hranicemi řádku vyplní řetězec mezerami až do tohoto posunu. Neceločíselné typy budou převedeny na celočíselné typy. Nesprávný typ offsetu způsobí chybu úrovně E_NOTICE. Zápis do záporného offsetu způsobí chybu úrovně E_NOTICE a při čtení vrátí prázdný řetězec. Použije se pouze první znak přiřazeného řetězce. Přiřazení prázdnému řetězci přiřadí prázdný bajt (NULL).

Pozornost

Řetězce v PHP jsou interně pole bajtů. V důsledku toho není přístup nebo úprava řetězce s posunem bezpečné pro vícebajtové kódování a mělo by být prováděno pouze s řetězci v jednobajtových kódováních, jako je ISO-8859-1.

Příklad #9 Několik příkladů řetězců

// Získá první znak řetězce
$str = "Toto je test." ;
$first = $str [ 0 ];

// Získá třetí znak řetězce
$třetina = $str [ 2 ];

// Získání posledního znaku řetězce
$str = "Toto je stále test." ;
$poslední = $str [ strlen ($str ) - 1 ];

// Změna posledního znaku řádku
$str = "Podívejte se na moře" ;
$str [ strlen ($str )- 1 ] = "e" ;

?>

Od PHP 5.4 musí být offset v řetězci specifikován jako celé číslo nebo řetězec obsahující číslice, jinak bude vydáno varování. Dříve offset daný řetězcem jako "foo", bez varování byl přeměněn na 0 .

Příklad #10 Rozdíly mezi 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" ]));
?>

Výsledek spuštění tohoto příkladu v PHP 5.3:

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

Výsledek spuštění tohoto příkladu v PHP 5.4:

string(1) "b" bool(true) Varování: Neplatný posun řetězce "1.0" v /tmp/t.php na řádku 7 string(1) "b" bool(false) Varování: Neplatný posun řetězce "x" v / tmp/t.php na řádku 9 string(1) "a" bool(false) string(1) "b" bool(false)

Komentář:

Pokus o přístup k proměnným jiných typů (kromě polí nebo objektů, které implementují určitá rozhraní) pomocí nebo {} se tiše vrátí NULA.

Komentář:

PHP 5.5 přidalo podporu pro přístup ke znakům v řetězcových literálech pomocí syntaxe nebo {} .

Existuje mnoho užitečných funkcí pro úpravu řetězců.

Základní funkce jsou popsány v části o řetězcových funkcích a pro pokročilé vyhledávání a nahrazování regulárních výrazů nebo funkcí regulárních výrazů kompatibilních s Perl.

Převést na řetězec

Hodnotu lze převést na řetězec pomocí přetypování (tětiva), nebo funkce strval(). Ve výrazech, kde je vyžadován řetězec, proběhne převod automaticky. K tomu dochází, když používáte funkce echo nebo tisk, nebo když je hodnota proměnné porovnána s řetězcem. Přečtením sekcí Typy a Manipulace s typy v příručce bude následující jasnější. viz také settype().

Pole jsou vždy převedeny na řetězec "Pole", takže nemůžete zobrazit obsah pole ( pole), použitím echo nebo tisk abyste viděli, co obsahuje. Chcete-li zobrazit jeden prvek, použijte něco jako echo $arr["foo"]. Níže naleznete tipy, jak zobrazit/zobrazit veškerý obsah.

Objekty v PHP 4 byly vždy převedeny na řetězec "Objekt". Pokud chcete zobrazit hodnoty polí objektu ( objekt) pro účely ladění, čtěte dále. Pokud chcete získat název třídy požadovaného objektu, použijte get_class(). Od PHP 5 je také dostupná metoda __toString.

NULA se vždy převede na prázdný řetězec.

Jak můžete vidět výše, přímý převod polí, objektů nebo zdrojů na řetězec neposkytuje žádné užitečné informace o hodnotách samotných kromě jejich typů. Lepším způsobem výstupu hodnot pro ladění je použití funkcí print_r() A var_dump().

Většinu hodnot v PHP lze převést na řetězec pro trvalé úložiště. Tato metoda se nazývá serializace a lze ji provést pomocí funkce serializovat (). Pokud má vaše instalace PHP podporu WDDX, je navíc možná serializace do struktury XML.

Převod řetězců na čísla

Pokud je řetězec rozpoznán jako číselná hodnota, výsledná hodnota a typ se určí následovně.

Pokud řetězec neobsahuje žádný ze znaků ".", "e" nebo "E" a hodnota čísla spadá do limitů celých čísel (definováno PHP_INT_MAX), bude řetězec rozpoznán jako celé číslo ( celé číslo). Ve všech ostatních případech se považuje za číslo s pohyblivou řádovou čárkou ( plovák).

Hodnota je určena začátkem řetězce. Pokud řádek začíná platnou číselnou hodnotou, použije se tato hodnota. Jinak bude hodnota 0 (nula). Platná číselná hodnota je jedna nebo více číslic (které mohou obsahovat desetinnou čárku), před kterými může být znaménko, za kterým následuje volitelný exponent. Exponent je "e" nebo "E" následovaný jednou nebo více číslicemi.

$foo = 1 + "10,5" ; // $foo je plovoucí (11.5)
$foo = 1 + "-1,3e3" ; // $foo je plovoucí (-1299)
$foo = 1 + "bob-1.3e3" ; // $foo je celé číslo (1)
$foo = 1 + "bob3" ; // $foo je celé číslo (1)
$foo = 1 + "10 malých prasat" ; // $foo je celé číslo (11)
$foo = 4 + "10.2 Malá prasátka" ; // $foo je plovoucí (14.2)
$foo = "10,0 prasat" + 1 ; // $foo is float (11)
$foo = "10,0 prasat" + 1,0 ; // $foo is float (11)
?>

Více detailní informace Informace o této konverzi naleznete v části o strtod(3) v dokumentaci Unixu.

Pokud chcete otestovat některý z příkladů v této části, zkopírujte jej a vložte jej a následující řádek, abyste viděli, co se stane:

echo "\$foo== $foo ; napište: " . gettype ($foo) . "
\n" ;
?>

Nečekejte, že kód znaku získáte převodem na celé číslo (jak se to dělá například v C). Chcete-li převést znaky na jejich kódy ASCII a zpět, použijte funkce ord() A chr().

Podrobnosti implementace typu řetězce

Typ řetězce ( tětiva) v PHP je implementován jako pole bajtů a celé číslo obsahující délku vyrovnávací paměti. Neobsahuje žádné informace o tom, jak tyto bajty převést na znaky, takže tento úkol ponechává programátorovi. Neexistují žádná omezení obsahu řetězce, jako je bajt s hodnotou 0 ("NUL" bajt) může být umístěn kdekoliv (ale uvědomte si, že některé funkce, jak je uvedeno v této příručce, nejsou "binárně bezpečné", tj. mohou předávat řetězce do knihoven, které ignorují data po NUL -bajtu).

Tato povaha typu řetězce vysvětluje, proč PHP nemá samostatný typ „byte“ – tuto roli hrají řetězce. Funkce, které vracejí netextová data – například libovolný datový tok načtený ze síťového soketu – stále vracejí řetězce.

Vzhledem k tomu, že PHP nediktuje specifické kódování pro řetězce, lze se ptát, jak se potom kódují řetězcové literály. Například čára "á" ekvivalent "\xE1"(ISO-8859-1), "\xC3\xA1"(UTF-8, normalizační forma C), "\x61\xCC\x81"(UTF-8, normalizační forma D) nebo nějaké jiné možné znázornění? Odpověď je, že řetězec bude zakódován tak, jak je zapsán v souboru skriptu. Pokud je tedy skript napsán v kódování ISO-8859-1, bude řetězec zakódován v kódování ISO-8859-1 atd. Toto pravidlo však neplatí, pokud je povolen režim Zend Multibyte: v tomto případě lze skript zapsat v libovolném kódování (buď explicitně určeném nebo automaticky určeném) a poté jej převést na specifické interní kódování, které bude následně použito pro řetězcové literály. Vezměte prosím na vědomí, že kódování skriptu (nebo interní kódování, pokud je povoleno Zend Multibyte) má určitá omezení: kódování musí být téměř vždy nadmnožinou ASCII, jako je UTF-8 nebo ISO-8859-1. Všimněte si také, že kódování závislé na stavu, kde lze použít stejné hodnoty bajtů ve stavu počátečního a jiného než počátečního posunu, mohou způsobit problémy.

Aby byly řetězcové funkce užitečné, musí samozřejmě vycházet z určitých předpokladů o kódování řetězce. Bohužel mezi funkcemi PHP existuje poměrně široká škála přístupů k tomuto problému:

  • Některé funkce předpokládají, že řetězec je zakódován v nějakém jednobajtovém kódování, ale nepotřebují interpretovat bajty jako specifické znaky, aby fungovaly správně. Do této kategorie patří např. substr(), strpos(), strlen() A strcmp(). Jiný způsob uvažování o těchto funkcích je ten, že fungují na vyrovnávací paměti paměti, tzn. pracují přímo s byty a jejich offsety. ofsety.
  • Jiné funkce očekávají, že kódování bude předáno jako parametr, možná za předpokladu nějakého výchozího kódování, pokud nebyl zadán parametr kódování. Tato funkce je
  • Konečně existují funkce, které předpokládají, že řetězec používá specifické kódování, obvykle UTF-8. Většina funkcí z rozšíření intl a PCRE spadá sem (v druhém případě pouze při specifikaci modifikátoru u). I když se to děje záměrně, funkce utf8_decode() zahrnuje kódování UTF-8 a utf8_encode()- ISO-8859-1.

Nakonec, psaní správných programů, které pracují s Unicode, znamená pečlivě se vyhýbat funkcím, které nefungují s Unicode a pravděpodobně poškozují data, a místo toho používat platné funkce, obvykle z rozšíření intl a mbstring. Použití funkcí podporujících Unicode je však dobrý začátek. Bez ohledu na funkce, které jazyk poskytuje, je nutné znát samotnou specifikaci Unicode. Pokud například program předpokládá, že v jazyce existují pouze malá a velká písmena, pak dělá velkou chybu.

Jaký typ uvozovek mám použít k formátování řetězců – apostrofy nebo klasické dvojité uvozovky?

Podívejme se na rozdíl mezi dvojitými a jednoduchými uvozovkami v PHP a pomocí příkladů zjistíme, kdy které použít.

Proměnné a sekvence escape pro speciální znaky nalezené v řetězcích uzavřených v jednoduchých uvozovkách se nezpracovávají. Řetězce ohraničené apostrofy zpracovává PHP interpret mnohem rychleji než podobné řetězce ohraničené dvojitými uvozovkami.

Důvod je zde jednoduchý: PHP interpret navíc kontroluje řetězce v dvojitých uvozovkách na přítomnost proměnných, a pokud jsou nalezeny, tak místo názvu proměnné je do řetězce vložena její hodnota. Řádek uzavřený v apostrofech je ale interpretem vnímán jako běžný text a PHP v těchto řádcích neprovádí žádné transformace. Myslím, že je jasné, že zpracování řetězců v jednoduchých uvozovkách bude v každém případě rychlejší.

Nejprve si popíšeme, jak definovat řetězec, a poté zkontrolujeme, o kolik rychlejší bude zpracování řetězců v jednoduchých uvozovkách.

Nejjednodušší způsob, jak definovat řetězec, je uzavřít ho do jednoduchých uvozovek ("). Chcete-li použít jednoduché uvozovky v řetězci v jednoduchých uvozovkách, musí jim předcházet zpětné lomítko (\), to znamená, že musí být uvozeny. před jednoduchou uvozovkou nebo na konci řádku, musíte ji duplikovat. Pokud se pokusíte uniknout jinému znaku, vytiskne se také zpětné lomítko.

Zde je příklad použití jednoduchých uvozovek:
// Výstup: Jednoduchý řetězec
echo "Jednoduchý řetězec";
// Tisky: Jsem tady
echo "Jsem tady";
// Výstup: Toto nevloží: \n nový řádek
echo "Toto se nevloží:\nnový řádek";
// Výstupy: Nebude nahrazena ani proměnná $example
echo "Nebude nahrazena ani proměnná $example"; Pokud je řetězec uzavřen v uvozovkách ("), PHP rozpozná velké množstvířídicí sekvence pro speciální znaky a také dosadí svou hodnotu místo názvu proměnné v řetězci. Stejně jako u jednoduchých uvozovek, aby bylo možné použít dvojité uvozovky v řetězci s dvojitými uvozovkami, musí jim předcházet znak zpětného lomítka (\).

Zde je příklad použití dvojitých uvozovek:
// Výstup: Jednoduchý řetězec
echo "Jednoduchý řetězec";
// Výstupy: Společnost "Snowdrop"
echo "Společnost \"Sněženka\"";
// Výstup: Toto povede k novému řádku
echo "Toto se přeruší na nový řádek \n";
// Výstup: Proměnná bude nahrazena
$example = "bude nahrazen";
echo "Proměnná $příklad"; Je třeba si také pamatovat, že sekvence "\n" ( nový řádek), "\r" (carriage return) pro prostý text, nikoli HTML. Změny v prohlížeči tedy neuvidíte (pouze v zdrojový kód stránky).

Pojďme zjistit, o kolik rychlejší jsou jednoduché uvozovky než dvojité. Pro měření napíšeme krátký testovací skript a hned si všimneme, že pokud to otestujete sami, výsledky, které závisí na hardwaru vašeho PC nebo serveru, se budou lišit.
// Vrátí časové razítko na začátku cyklu
$start = microtime(true);
// Vytvořte smyčku pro 1 milion iterací
pro ($i = 0; $i< 1000000; $i++) {
$text = "Zde je řetězec znaků";
}
// Vypočítejte strávený čas
$time = (microtime(true) - $start); Výsledek: 0,09 sekundy.

Pokud nahradíme jednoduché uvozovky dvojitými uvozovkami:
$text = "Zde je řetězec znaků"; Výsledek bude 0,10 sekundy.

Jak vidíte, při použití textových řetězců je rozdíl v době provádění velmi malý, dalo by se dokonce říci, že vůbec neexistuje. Zábava začíná, když se pokusíme spojit řetězec a proměnnou.
$text = "Zde je řetězec znaků $i"; nebo
$text = $i."Zde je řetězec znaků"; Výsledek přibližně: 0,27 sekundy.

Rozdíl je docela patrný. Zřetězení a dvojité uvozovky jasně ovlivňují výkon, když jsou do řetězce přidány proměnné.

Když server zpracuje kód, zkontroluje veškerý obsah dvojitých uvozovek na proměnné, konstanty a další. Chce to čas. A server zpracovává to, co je mezi jednoduchými uvozovkami, jako hotový text a je mu jedno, co tam je. Rozdíl mezi výkonem jednoduchých a dvojitých uvozovek je velmi malý, ale pokud vyvíjíte vysoce nabitý projekt, pak už je pár ušetřených milisekund vítězstvím.