luk Sat Mar 2 18:44:41 2002 EDT Added files: /phpdoc/cs/appendices migration4.xml reserved.xml Log:
Index: phpdoc/cs/appendices/migration4.xml +++ phpdoc/cs/appendices/migration4.xml <?xml version="1.0" encoding="iso-8859-2"?> <appendix id="migration4"> <title>Přechod z PHP 3 na PHP 4</title> <section id='migration4.changes'> <title>Co se změnilo v PHP 4</title> <para> PHP 4 a integrovaný Zend engine se vyznačuje podstatně vyšším výkonem a schopnostmi, přesto však byla věnována zvláštní péče tomu, dopady na stávající kód byly co nejmenší. Takže úpravy vašeho kódu z PHP 3 na PHP 4 by měly být podstatně snadnější než při přechodu z PHP/FI 2.0 na PHP 3. Mnoho existujícího kódu pro PHP 3 by mělo být připraveno běžet bez jakýchkoli změn, měli byste však vědět o několika podstatných odlišnostech a věnovat dobrou péči otestování kódu před změnou verze produkčního prostředí. Následující text by vám měl poradit, na co se zaměřit. </para> </section> <section id="migration4.php4.with.php3"> <title>Současný běh PHP 3 a PHP 4</title> <simpara> Nejnovější operační systémy poskytují možnost versioningu a scopingu. Tyto prostředky umožňují nechat běžet PHP 3 a PHP 4 současně na jediném serveru Apache. </simpara> <simpara> Funkce je ověřena na těchto platformách: </simpara> <itemizedlist> <listitem><simpara>Linux + nejnovější binutils (testována verze binutils 2.9.1.0.25) </simpara></listitem> <listitem><simpara>Solaris 2.5 a novější</simpara></listitem> <listitem><simpara>FreeBSD (testovány verze 3.2 a 4.0)</simpara></listitem> </itemizedlist> <para> K aktivaci této možnosti je třeba nakonfigurovat PHP 3 a PHP 4 k použití APXS (--with-apxs) a nezbytných rozšíření vazeb (--enable-versioning). Jinak postupujte zcela standardním způsobem (pro konfiguraci, kompilaci a instalaci). Například: <informalexample> <programlisting role="configure"> <![CDATA[ $ ./configure \ --with-apxs=/apache/bin/apxs \ --enable-versioning \ --with-mysql \ --enable-track-vars ]]> </programlisting> </informalexample> </para> </section> <section id="migration4.configuration"> <title>Převod konfiguračních souborů</title> <para> Název globálního konfiguračního souboru, <filename>php3.ini</filename>, se změnil na <filename>php.ini</filename>. </para> <para> V konfiguračním souboru serveru Apache je poněkud více změn. Změnily se především MIME datové typy rozpoznávané modulem PHP. <informalexample> <programlisting role="apache"> <![CDATA[ application/x-httpd-php3 --> application/x-httpd-php application/x-httpd-php3-source --> application/x-httpd-php-source ]]> </programlisting> </informalexample> </para> <para> Můžete upravit vaše konfigurační soubory tak, aby pracovaly s oběma verzemi PHP (v závislosti na tom, která je v příslušném okamžiku zkompilována pro server) použitím následující syntaxe: <informalexample> <programlisting> <![CDATA[ AddType application/x-httpd-php3 .php3 AddType application/x-httpd-php3-source .php3s AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps ]]> </programlisting> </informalexample> </para> <simpara> Změnily se také názvy direktiv pro server Apache. </simpara> <para> Od verze PHP 4.0 existují pouze čtyři direktivy pro Apache, které mají spojitost s PHP: <informalexample> <programlisting role="apache"> <![CDATA[ php_value [PHP directive name] [value] php_flag [PHP directive name] [On|Off] php_admin_value [PHP directive name] [value] php_admin_flag [PHP directive name] [On|Off] ]]> </programlisting> </informalexample> </para> <simpara> Jsou dva rozdíly mezi hodnotami "admin" a ostatními: </simpara> <itemizedlist> <listitem> <simpara>Hodnoty (nebo příznaky) "admin" se mohou objevit pouze v konfiguračních souborech pro celý server (např. httpd.conf). </simpara></listitem> <listitem> <simpara>Standardní hodnoty (nebo příznaky) nemohou ovládat jisté PHP direktivy, například bezpečný režim (pokud byste mohli změnit nastavení bezpečného režimu v souborech .htaccess, bezpečný režim ztrácí smysl). Naopak, "admin" hodnoty mohou zasahovat do jakýchkoli PHP direktiv. </simpara></listitem> </itemizedlist> <simpara> Aby byl přechod na novou verzi snazší, balík PHP 4 obsahuje skripty, které automaticky převedou váš konfigurační soubor pro Apache a soubory .htaccess tak, aby pracovaly jak s PHP 3, tak s PHP 4. Tyto skripty NEPŘEVÁDĚJÍ řádky s popisy MIME typů! Musíte je upravit ručně. </simpara> <para> K převedení konfiguračních souborů pro Apache, spusťte skript apconf-conv.sh (umístěný v adresáři scripts/apache/). Například: <informalexample> <programlisting role="shell"> <![CDATA[ ~/php4/scripts/apache:# ./apconf-conv.sh /usr/local/apache/conf/httpd.conf ]]> </programlisting> </informalexample> </para> <simpara> Váš originální konfigurační soubor bude uložen jako httpd.conf.orig. </simpara> <para> K převedení souborů .htaccess, spusťte skript aphtaccess-conv.sh (dostupný rovněž v adresáři scripts/apache/): <informalexample> <programlisting role="shell"> <![CDATA[ ~/php4/scripts/apache:# find / -name .htaccess -exec ./aphtaccess-conv.sh {} \; ]]> </programlisting> </informalexample> </para> <simpara> I v tomto případě budou originální soubory .htaccess uloženy s koncovkou .orig. </simpara> <simpara> Konverzní skripty vyžadují nainstalovaný nástroj awk. </simpara> </section> <section id='migration4.parser'> <title>Chování parseru</title> <para> Parsing a provádění kódu jsou nyní dva naprosto oddělené kroky, nic z kódu v souboru se neprovádí dříve, než je úspěšně provedena úplná syntaktická analýza celého souboru a všeho, co je třeba. </para> <para> Jeden z nových požadavků, které vyvstaly tímto rozdělením, je, že všechny soubory připojené prostřednictvím "require" a "include" nyní musí být syntakticky úplné. Již nelze rozložit různé části řídicích konstrukcí přes hranice souborů. Tj. nelze začít cyklus <literal>for</literal> nebo literal>while</literal>, větvení <literal>if</literal> nebo <literal>switch</literal> v jednom souboru a ukočit je (resp. pokračovat pomocí <literal>else</literal>, <literal>endif</literal>, <literal>case</literal> nebo <literal>break</literal>) v souboru jiném. </para> <para> Zůstává zcela legální vložit další kód do cyklů nebo jiných řídicích struktur, pouze řídicí klíčová slova a odpovídající složené závorky <literal>{...}</literal> musí být ve stejné kompilační jednotce (souboru nebo řetězci zpracovaném pomocí <function>eval</function>). </para> <para> Toto neškodí tolik jako výše uvedené rozkládání kódu, přesto to může být považováno za velmi špatný styl. </para> <para> Jinou věcí, která již není možná, je vzácně vídané vracení hodnot ze souborů připojených pomocí "require". Vracení hodnot ze souborů připojených "include" je možné i nadále. </para> </section> <section id='migration4.error-reporting'> <title>Hlášení chyb</title> <section id='migration4.error-reporting.config'> <title>Změny konfigurace</title> <para> Hlášení chyb v PHP 3 bylo založeno na úrovních, představovaných jednoduchou číselnou hodnotou. Hodnoty se sčítaly pro různé úrovně chyb. Obvyklé hodnoty byly 15 pro hlášení všech chyb a varování, 7 pro hlášení všeho kromě informativních zpráv, ohlašujících špatný styl a podobné věci. </para> <para> PHP 4 má větší množinu úrovní chyb a varování a přichází s konfiguračním parserem, který nyní umožňuje k nastavení potřebného chování používat symbolické konstanty. </para> <para> Úroveň hlášení chyb by měla být nyní nastavována explicitním odebíráním těch úrovní, u kterých které nechceme, aby byly hlášeny (pomocí logické operace XOR se symbolickou konstantou). <literal>E_ALL</literal>. Zní to komplikovaně? No, tak řekněme, že chcete hlásit všechny chyby s výjimkou jednoduchých "stylových" varování, která jsou zařazena do kategorie popsané symbolickou konstantou <literal>E_NOTICE</literal>. Potom do souboru <filename>php.ini</filename> vložíte: <literal>error_reporting = E_ALL & ~ ( E_NOTICE )</literal>. Pokud chcete potlačit také všechna varování, přidáte odpovídající konstantu do závorek s použitím binárního operátoru '|': <literal>error_reporting= E_ALL & ~ ( E_NOTICE | E_WARNING )</literal>. </para> <warning> <para> Používání starých hodnot 7 a 15 pro nastavení hlášení chyb je velmi špatný nápad, protože to potlačuje některé nově přidané třídy chyb včetně syntaktických. To může vést k velmi záhadnému chování, kdy skripty nepracují, aniž by vydaly jakoukoli zprávu o chybě. </para> <para> Toto v minulosti vedlo k množství nereprodukovatelných bug reportů (hlášení o chybách v PHP), když lidé hlásili problémy s enginem, které nebyli schopni vystopovat. Pravou příčinou byla obvykle chybějící uzavírací závorka '}' v souboru připojeném pomocí "require", a parser je nemohl ohlásit kvůli špatně nakonfigurovanému hlášení chyb. </para> <para> Takže kontrola nastavení hlášení chyb by měla být první věcí, pokud vaše skripty tiše havarují. Zend engine může být nyní považován za dost vyspělý na to, aby způsoboval takové podivné chování. </para> </warning> </section> <section id='migration4.error-reporting.additions'> <title>Přídavné varovné zprávy</title> <para> Mnoho existujících kódů v PHP 3 používá jazykové konstrukty, které by měly být považovány za velmi špatný styl psaní, neboť přestože nyní dělají zamýšlené věci, snadno mohou být narušeny změnami jinde. PHP 4 bude vydávat spousty informativních zpráv v takových situacích, kdy se v PHP 3 nic nedělo. Snadnou nápravou je vypnutí zpráv E_NOTICE, ale obvykle je lepší raději opravit kód. </para> <para> Nejčastějším případem, který bude produkovat takové zprávy, je použití řetězců bez uvozovek jako prvků pole. Jak PHP 3, tak PHP 4 je budou interpretovat jako řetězce, pokud pod tímto jménem není známo žádné klíčové slovo ani konstanta. Pokud by však nějaká taková konstanta (někde jinde v kódu) definována byla, skript může havarovat. Může to přerůst i v bezpečnostní riziko, pokud nějaký útočník předefinuje řetězcové konstanty způsobem, který mu dá přístupová práva, jež by mít neměl. Takže PHP 4 vás bude nyní varovat, pokud použijete řetězecovou konstantu neuzavřenou do uvozovek, jako například <literal>$HTTP_SERVER_VARS[REQUEST_METHOD]</literal>. Změníte-li to na <literal>$HTTP_SERVER_VARS['REQUEST_METHOD']</literal>, parser se uklidní a výrazně se zlepší styl a bezpečnost vašeho kódu. </para> <para> Další věcí v PHP 4 je hlášení použití neinicializovaných proměnných a prvků polí. </para> </section> </section> <section id='migration4.initializers'> <title>Inicializátory</title> <para> Statické proměnné a inicializátory položek tříd přijímají pouze skalární hodnoty, zatímco v PHP 3 přijímaly i jakékoli platné výrazy. Toto je, opět, kvůli rozdělení mezi parsing a provádění kódu - když parser zpracovává inicializátor, ještě není proveden žádný kód. </para> <para> K inicializaci položek ve třídách byste měli namísto toho používat konstruktory. Pro statické proměnné přesto vzácně dává smysl i něco jiného než obyčejná hodnota. </para> </section> <section id='migration4.empty'> <title><literal>empty("0")</literal></title> <para> Asi nejkontroverznější změnou v chování je změna ve funkci <function>empty</function>. Řetězec obsahující pouze znak '0' (nula) je nyní považován za prázdný, což v PHP 3 nebylo. </para> <para> Toto nové chování má smysl u aplikací pro web tam, kde všechna vstupní pole vrací řetězce, i když je požadován číselný vstup, a se schopností PHP provádět automatickou typovou konverzi. Na druhou stranu může v některých případech vést k chybnému chování, jehož příčiny se špatně zjištují, pokud nevíte, co máte hledat. </para> </section> <section id='migration4.missing'> <title>Chybějící funkce</title> <para> Současně s tím, že se v PHP 4 objevuje mnoho nových prostředků, funkcí a rozšíření, můžete najít i funkce, které oproti verzi 3 chybí. Malý počet jádrových funkcí zmizel, protože nefungují s novým schématem oddělení parsingu a provádění kódu v Zend enginu. Jiné funkce i celá kompletní rozšíření se staly zastaralými tím, že novější funkce a rozšíření poslouží ve stejné roli lépe nebo obecněji. Některé funkce jednoduše ještě nebyly portovány a konečně jsou také funkce a rozšíření chybějící kvůli licenčním konfliktům. </para> <section id='migration4.missing.concept'> <title>Funkce chybějící kvůli konceptuálním změnám</title> <para> Tím, že PHP 4 odděluje syntaktickou analýzu od interpretace, již není možné měnit chování parseru (nyní vloženého do Zend enginu) během provádění skriptu, který byl již syntakticky zpracován. Takže funkce <function>short_tags</function> již neexistuje. Měnit chování parseru stále můžete, a to nastavením hodnot v souboru <filename>php.ini</filename>. </para> <para> Jiným prostředkem PHP 3, který není součástí PHP 4, je zabudované rozhraní pro ladění. Existují externí doplňky pro Zend engine, které poskytují podobné funkce. </para> </section> <section id='migration4.deprecate'> <title>Zavržené funkce a rozšíření</title> <para> Databázová rozšíření Adabas a Solid již nejsou k dispozici. Namísto toho se používá rozšíření unifikované rozhraní ODBC. </para> </section> <section id='migration4.unset'> <title>Změněný status funkce <function>unset</function></title> <para> <function>unset</function>, přestože je stále k dispozici, je implementována jako jazykový konstrukt namísto funkce. </para> <para> To nemá žádné důsledky v chování <function>unset</function>, ale test "unset" pomocí <function>function_exists</function> vrátí &false;, stejně jako v případě jiných jazykových konstruktů, které vypadají jako funkce, např. <function>echo</function>. </para> <para> Jinou, praktičtější změnou je to, že již nelze volat <function>unset</function> nepřímo, tzn. <literal>$func="unset"; $func($somevar)</literal> už nebude fungovat. </para> </section> </section> <section id='migration4.extensions'> <title>Rozšíření PHP 3</title> <para> Rozšíření psaná pro PHP 3 nebudou s PHP 4 pracovat, ani na binární, ani na zdrojové úrovni. Není těžké portovat tato rozšíření na PHP 4, pokud máte přístup k originálnímu zdrojovému kódu. Detailní popis procesu portace není součástí tohoto textu. </para> </section> <section id='migration4.strings'> <title>Substituce za proměnné v řetězcích</title> <para> PHP 4 přidává nový mechanismus k substituci za proměnné v řetězcích. Nyní můžete konečně uvnitř řetězců přistupovat k položkám v objektech a k prvkům vícerozměrných polí. </para> <para> To se udělá pomocí uzavření proměnných do složených závorek se znakem dolaru ihned za otvírací závorkou: <literal>{$...}</literal> </para> <para> K vložení hodnoty položky objektu do řetězce jednoduše napíšete <literal>"text {$obj->member} text"</literal>, zatímco v PHP 3 jste museli napsat něco jako <literal>"text ".$obj->member." text"</literal>. </para> <para> Toto by mělo vést k čitelnějšímu kódu, ale může to způsobovat problémy s existujícími skripty pro PHP 3. Můžete ale provést test na kombinaci znaků <literal>{$</literal> ve vašem kódu a jejich nahrazení <literal>\{$</literal> pomocí vašeho oblíbeného nástroje pro hledání a náhradu. </para> </section> <section id='migration4.cookies'> <title>Cookies</title> <para> V PHP 3 se zavedl špatný zvyk nastavovat cookies opačným pořadím volání <function>setcookie</function> v kódu. PHP 4 toto napravuje a vytváří hlavičkové řádky pro cookies v přesně stejném pořadí, jak jdou za sebou v kódu. </para> <para> Opět se mohou vyskytnout problémy s existujícím kódem, ale staré chování bylo tak těžko pochopitelné, že si zasloužilo změnu, aby se zabránilo dalším problémům v budoucnosti. </para> </section> <section id='migration4.variables'> <title>Obsluha globálních proměnných</title> <para> Zatímco v PHP 3 a prvních verzích PHP 4 se při obsluze globálních proměnných dbalo především na jednoduchost, nyní se zaměření změnilo směrem k vyšší bezpečnosti. Takže jestliže následující případ dobře fungoval v PHP 3, v PHP 4 je třeba provést unset($GLOBALS["id"]);. Toto je jen jeden aspekt obsluhy globálních proměnných. Měli byste vždy používat $GLOBALS, v novějších verzích PHP 4 budete nuceni tak učinit ve většině případů. Více o této problematice najdete v <link linkend="references.global"> části <literal>global</literal> (globální) reference</link>. </para> <example> <title>Změny u globálních proměnných</title> <programlisting role="php"> <![CDATA[ <?php $id = 1; function test() { global $id; unset($id); } test(); echo($id); // This will print out 1 in PHP 4 ]]> </programlisting> </example> </section> </appendix> <!-- Keep this comment at the end of the file Local variables: mode: sgml sgml-omittag:t sgml-shorttag:t sgml-minimize-attributes:nil sgml-always-quote-attributes:t sgml-indent-step:1 sgml-indent-data:t indent-tabs-mode:nil sgml-parent-document:nil sgml-default-dtd-file:"../manual.ced" sgml-exposed-tags:nil sgml-local-catalogs:nil sgml-local-ecat-files:nil End: --> Index: phpdoc/cs/appendices/reserved.xml +++ phpdoc/cs/appendices/reserved.xml <?xml version="1.0" encoding="iso-8859-2"?> <appendix id="reserved"> <title>Seznam vyhrazených slov</title> <para> Toto je seznam vyhrazených slov PHP, obvykle <link linkend="language.constants">konstant</link> a <link linkend="language.variables.predefined">předdefinovaných proměnných</link>. Nenajdete zde žádné funkce, což však neplatí pro jazykové konstrukty. Uvedenými názvy byste se neměli pokoušet nazývat proměnné, funkce, konstanty nebo metody, vedlo by to spolehlivě ke zmatku. <simplelist columns="3"> <member> <link linkend="language.operators.logical">and</link> </member> <member> <link linkend="language.variables.predefined.php">$argv</link> </member> <member> <link linkend="control-structures.foreach">as</link> </member> <member> <link linkend="language.variables.predefined.php">$argc</link> </member> <member> <link linkend="control-structures.break">break</link> </member> <member> <link linkend="control-structures.switch">case</link> </member> <member> <link linkend="functions.old-syntax">cfunction</link> </member> <member> <link linkend="keyword.class">class</link> </member> <member> <link linkend="control-structures.continue">continue</link> </member> <member> <link linkend="control-structures.declare">declare</link> </member> <member> <link linkend="control-structures.switch">default</link> </member> <member> <link linkend="control-structures.do.while">do</link> </member> <member> <function>die</function> </member> <member> <function>echo</function> </member> <member> <link linkend="control-structures.else">else</link> </member> <member> <link linkend="control-structures.elseif">elseif</link> </member> <member> <function>empty</function> </member> <member> <link linkend="control-structures.declare">enddeclare</link> </member> <member> <link linkend="control-structures.alternative-syntax">endfor</link> </member> <member> <link linkend="control-structures.alternative-syntax">endforeach</link> </member> <member> <link linkend="control-structures.alternative-syntax">endif</link> </member> <member> <link linkend="control-structures.alternative-syntax">endswitch</link> </member> <member> <link linkend="control-structures.alternative-syntax">endwhile</link> </member> <member> <link linkend="language.constants">E_ALL</link> </member> <member> <link linkend="language.constants">E_PARSE</link> </member> <member> <link linkend="language.constants">E_ERROR</link> </member> <member> <link linkend="language.constants">E_WARNING</link> </member> <member> <link linkend="function.eval">eval</link> </member> <member> <function>exit</function> </member> <member> <link linkend="keyword.class">extends</link> </member> <member> <link linkend="language.constants">&false;</link> </member> <member> <link linkend="control-structures.for">for</link> </member> <member> <link linkend="control-structures.foreach">foreach</link> </member> <member> <link linkend="functions.user-defined">function</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_COOKIE_VARS</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_GET_VARS</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_POST_VARS</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_POST_FILES</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_ENV_VARS</link> </member> <member> <link linkend="language.variables.predefined.php">$HTTP_SERVER_VARS</link> </member> <member> <link linkend="control-structures.if">if</link> </member> <member> <function>include</function> </member> <member> <function>include_once</function> </member> <member> <link linkend="language.variables.scope">global</link> </member> <member> <function>list</function> </member> <member> <link linkend="keyword.class">new</link> </member> <member> <link linkend="language.operators.logical">not</link> </member> <member> <link linkend="language.constants.predefined">NULL</link> </member> <member> <link linkend="functions.old-syntax">old_function</link> </member> <member> <link linkend="language.operators.logical">or</link> </member> <member> <link linkend="keyword.parent">parent</link> </member> <member> <link linkend="language.constants">PHP_OS</link> </member> <member> <link linkend="language.variables.predefined.php">$PHP_SELF</link> </member> <member> <link linkend="language.constants">PHP_VERSION</link> </member> <member> <function>print</function> </member> <member> <function>require</function> </member> <member> <function>require_once</function> </member> <member> <function>return</function> </member> <member> <link linkend="language.variables.scope">static</link> </member> <member> <link linkend="control-structures.switch">switch</link> </member> <member> <link linkend="keyword.class">stdClass</link> </member> <member> <link linkend="keyword.class">$this</link> </member> <member> <link linkend="language.constants">&true;</link> </member> <member> <link linkend="keyword.class">var</link> </member> <member> <link linkend="language.operators.logical">xor</link> </member> <member> <function>virtual</function> </member> <member> <link linkend="control-structures.while">while</link> </member> <member> <link linkend="language.constants">__FILE__</link> </member> <member> <link linkend="language.constants">__LINE__</link> </member> <member> <link linkend="language.oop.magic-functions">__sleep</link> </member> <member> <link linkend="language.oop.magic-functions">__wakeup</link> </member> </simplelist> </para> </appendix> <!-- Keep this comment at the end of the file Local variables: mode: sgml sgml-omittag:t sgml-shorttag:t sgml-minimize-attributes:nil sgml-always-quote-attributes:t sgml-indent-step:1 sgml-indent-data:t indent-tabs-mode:nil sgml-parent-document:nil sgml-default-dtd-file:"../manual.ced" sgml-exposed-tags:nil sgml-local-catalogs:nil sgml-local-ecat-files:nil End: -->