mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-17 01:18:55 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@166233 c90b9560-bf6c-de11-be94-00142212c4b1
511 lines
19 KiB
XML
511 lines
19 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!-- $Revision: 1.39 $ -->
|
|
<appendix id="migration4">
|
|
<title>Migrating from PHP 3 to PHP 4</title>
|
|
|
|
<section id='migration4.changes'>
|
|
<title>What has changed in PHP 4</title>
|
|
<para>
|
|
PHP 4 and the integrated Zend engine have greatly improved PHP's
|
|
performance and capabilities, but great care has been taken to
|
|
break as little existing code as possible. So migrating your code
|
|
from PHP 3 to 4 should be much easier than migrating from
|
|
PHP/FI 2 to PHP 3. A lot of existing PHP 3 code should be
|
|
ready to run without changes, but you should still know about the
|
|
few differences and take care to test your code before switching
|
|
versions in production environments. The following should give you
|
|
some hints about what to look for.
|
|
</para>
|
|
</section>
|
|
|
|
<section id="migration4.php4.with.php3">
|
|
<title>Running PHP 3 and PHP 4 concurrently</title>
|
|
<simpara>
|
|
Recent operating systems provide the ability to perform
|
|
versioning and scoping. This features make it possible to let
|
|
PHP 3 and PHP 4 run as concurrent modules in one Apache server.
|
|
</simpara>
|
|
<simpara>
|
|
This feature is known to work on the following platforms:
|
|
</simpara>
|
|
<itemizedlist>
|
|
<listitem><simpara>Linux with recent binutils (binutils 2.9.1.0.25 tested) </simpara></listitem>
|
|
<listitem><simpara>Solaris 2.5 or better</simpara></listitem>
|
|
<listitem><simpara>FreeBSD (3.2, 4.0 tested)</simpara></listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
To enable it, configure PHP 3 and PHP 4 to use APXS
|
|
(<option role="configure">--with-apxs</option>) and the necessary
|
|
link extensions (<option role="configure">--enable-versioning</option>).
|
|
Otherwise, all standard installations instructions apply. For example:
|
|
<informalexample>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
$ ./configure \
|
|
--with-apxs=/apache/bin/apxs \
|
|
--enable-versioning \
|
|
--with-mysql \
|
|
--enable-track-vars
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</section>
|
|
|
|
<section id="migration4.configuration">
|
|
<title>Migrating Configuration Files</title>
|
|
<para>
|
|
The global configuration file, <filename>php3.ini</filename>,
|
|
has changed its name to &php.ini;.
|
|
</para>
|
|
<para>
|
|
For the Apache configuration file, there are slightly more
|
|
changes. The MIME types recognized by the PHP module have
|
|
changed.
|
|
<informalexample>
|
|
<programlisting role="apache-conf">
|
|
<![CDATA[
|
|
application/x-httpd-php3 --> application/x-httpd-php
|
|
application/x-httpd-php3-source --> application/x-httpd-php-source
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
You can make your configuration files work with both versions
|
|
of PHP (depending on which one is currently compiled into the
|
|
server), using the following syntax:
|
|
<informalexample>
|
|
<programlisting role="apache-conf">
|
|
<![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>
|
|
In addition, the PHP directive names for Apache have changed.
|
|
</simpara>
|
|
<para>
|
|
Starting with PHP 4.0, there are only four Apache directives
|
|
that relate to PHP:
|
|
<informalexample>
|
|
<programlisting role="apache-conf">
|
|
<![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>
|
|
There are two differences between the Admin values and the non admin values:
|
|
</simpara>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Admin values (or flags) can only appear in the server-wide Apache configuration
|
|
files (e.g., &httpd.conf;).
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Standard values (or flags) cannot control certain PHP directives, for example:
|
|
&safemode; (if you could override safe mode settings in
|
|
&htaccess; files, it
|
|
would defeat &safemode;'s purpose). In contrast, Admin values can modify
|
|
the value of any PHP directive.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<simpara>
|
|
To make the transition process easier, PHP 4 is bundled with scripts
|
|
that automatically convert your Apache configuration and
|
|
&htaccess; files
|
|
to work with both PHP 3 and PHP 4. These scripts do NOT convert the mime
|
|
type lines! You have to convert these yourself.
|
|
</simpara>
|
|
<para>
|
|
To convert your Apache configuration files, run the apconf-conv.sh
|
|
script (available in the scripts/apache/ directory). For example:
|
|
<informalexample>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
~/php4/scripts/apache:# ./apconf-conv.sh /usr/local/apache/conf/httpd.conf
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Your original configuration file will be saved in httpd.conf.orig.
|
|
</simpara>
|
|
<para>
|
|
To convert your &htaccess; files, run the
|
|
<filename>aphtaccess-conv.sh</filename> script (available in
|
|
the <filename>scripts/apache/</filename> directory as well):
|
|
<informalexample>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
~/php4/scripts/apache:# find / -name .htaccess -exec ./aphtaccess-conv.sh {} \;
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Likewise, your old &htaccess; files will be saved with
|
|
an .orig prefix.
|
|
</simpara>
|
|
<simpara>
|
|
The conversion scripts require awk to be installed.
|
|
</simpara>
|
|
</section>
|
|
|
|
<section id='migration4.parser'>
|
|
<title>Parser behavior</title>
|
|
<para>
|
|
Parsing and execution are now two completely separated steps, no
|
|
execution of a files code will happen until the complete file and
|
|
everything it requires has completely and successfully been
|
|
parsed.
|
|
</para>
|
|
<para>
|
|
One of the new requirements introduced with this split is that
|
|
required and included files now have to be syntactically
|
|
complete. You can no longer spread the different controlling parts
|
|
of a control structure across file boundaries. That is you cannot
|
|
start a <literal>for</literal> or <literal>while</literal> loop,
|
|
an <literal>if</literal> statement or a <literal>switch</literal>
|
|
block in one file and have the end of loop,
|
|
<literal>else</literal>, <literal>endif</literal>,
|
|
<literal>case</literal> or <literal>break</literal> statements in
|
|
a different file.
|
|
</para>
|
|
<para>
|
|
It still perfectly legal to include additional code within loops
|
|
or other control structures, only the controlling keywords and
|
|
corresponding curly braces <literal>{...}</literal> have to be
|
|
within the same compile unit (file or <function>eval</function>ed
|
|
string).
|
|
</para>
|
|
<para>
|
|
This should not harm too much as spreading code like this should be
|
|
considered as very bad style anyway.
|
|
</para>
|
|
<para>
|
|
Another thing no longer possible, though rarely seen in PHP 3
|
|
code is returning values from a required file. Returning a value
|
|
from an included file is still possible.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.error-reporting'>
|
|
<title>Error reporting</title>
|
|
|
|
<section id='migration4.error-reporting.config'>
|
|
<title>Configuration changes</title>
|
|
<para>
|
|
With PHP 3 the error reporting level was set as a simple
|
|
numeric value formed by summing up the numbers related to
|
|
different error levels. Usual values were 15 for reporting all
|
|
errors and warnings or 7 for reporting everything but simple
|
|
notice messages reporting bad style and things like that.
|
|
</para>
|
|
<para>
|
|
PHP 4 has a larger set of error and warning levels and comes with a
|
|
configuration parser that now allows for symbolic constants to be used
|
|
for setting the intended behavior.
|
|
</para>
|
|
<para>
|
|
Error reporting level should now be configured by explicitly
|
|
taking away the warning levels you do not want to generate error
|
|
messages by x-oring them from the symbolic constant
|
|
<literal>E_ALL</literal>. Sounds complicated? Well, lets say you
|
|
want the error reporting system to report all but the simple
|
|
style warnings that are categorized by the symbolic constant
|
|
<literal>E_NOTICE</literal>. Then you'll put the following into
|
|
your &php.ini;: <literal>error_reporting =
|
|
E_ALL & ~ ( E_NOTICE )</literal>. If you want to suppress
|
|
warnings too you add up the appropriate constant within the
|
|
braces using the binary or operator '|':
|
|
<literal>error_reporting= E_ALL & ~ ( E_NOTICE | E_WARNING
|
|
)</literal>.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
When upgrading code or servers from PHP 3 to PHP 4 you should
|
|
check these settings and calls to
|
|
<function>error_reporting</function> or you might disable
|
|
reporting the new error types, especially E_COMPILE_ERROR. This
|
|
may lead to empty documents without any feedback of what happened
|
|
or where to look for the problem.
|
|
</para>
|
|
</warning>
|
|
<warning>
|
|
<para>
|
|
Using the old values 7 and 15 for setting up error reporting is
|
|
a very bad idea as this suppresses some of the newly added error
|
|
classes including parse errors. This may lead to very strange
|
|
behavior as scripts might no longer work without error messages
|
|
showing up anywhere.
|
|
</para>
|
|
<para>
|
|
This has lead to a lot of unreproducible bug reports in the
|
|
past where people reported script engine problems they were not
|
|
capable to track down while the &true; case was usually some
|
|
missing '}' in a required file that the parser was not able to
|
|
report due to a misconfigured error reporting system.
|
|
</para>
|
|
<para>
|
|
So checking your error reporting setup should be the first thing
|
|
to do whenever your scripts silently die. The Zend engine can
|
|
be considered mature enough nowadays to not cause this kind of
|
|
strange behavior.
|
|
</para>
|
|
</warning>
|
|
</section>
|
|
|
|
<section id='migration4.error-reporting.additions'>
|
|
<title>Additional warning messages</title>
|
|
<para>
|
|
A lot of existing PHP 3 code uses language constructs that
|
|
should be considered as very bad style as this code, while doing
|
|
the intended thing now, could easily be broken by changes in
|
|
other places. PHP 4 will output a lot of notice messages in
|
|
such situations where PHP 3 didn't. The easy fix is to just
|
|
turn off E_NOTICE messages, but it is usually a good idea to fix
|
|
the code instead.
|
|
</para>
|
|
<para>
|
|
The most common case that will now produce notice messages is the
|
|
use of unquoted string constants as array indices. Both PHP 3
|
|
and 4 will fall back to interpret these as strings if no
|
|
keyword or constant is known by that name, but whenever a
|
|
constant by that name had been defined anywhere else in the code
|
|
it might break your script. This can even become a security risk
|
|
if some intruder manages to redefine string constants in a way
|
|
that makes your script give him access rights he wasn't intended
|
|
to have. So PHP 4 will now warn you whenever you use unquoted
|
|
string constants as for example in
|
|
<literal>$_SERVER[REQUEST_METHOD]</literal>. Changing it
|
|
to <literal>$_SERVER['REQUEST_METHOD']</literal> will
|
|
make the parser happy and greatly improve the style and security
|
|
of your code.
|
|
</para>
|
|
<para>
|
|
Another thing PHP 4 will now tell you about is the use of
|
|
uninitialized variables or array elements.
|
|
</para>
|
|
</section>
|
|
|
|
</section>
|
|
|
|
<section id='migration4.initializers'>
|
|
<title>Initializers</title>
|
|
<para>
|
|
Static variable and class member initializers only accept scalar
|
|
values while in PHP 3 they accepted any valid expression. This
|
|
is, once again, due to the split between parsing and execution as
|
|
no code has yet been executed when the parser sees the
|
|
initializer.
|
|
</para>
|
|
<para>
|
|
For classes you should use constructors to initialize member
|
|
variables instead. For static variables anything but a simple
|
|
static value rarely makes sense anyway.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.empty'>
|
|
<title><literal>empty("0")</literal></title>
|
|
<para>
|
|
The perhaps most controversial change in behavior has happened to the
|
|
behavior of the <function>empty</function>. A String containing
|
|
only the character '0' (zero) is now considered empty while it
|
|
wasn't in PHP 3.
|
|
</para>
|
|
<para>
|
|
This new behavior makes sense in web applications, with all input
|
|
fields returning strings even if numeric input is requested, and
|
|
with PHP's capabilities of automatic type conversion. But on the
|
|
other hand it might break your code in a rather subtle way,
|
|
leading to misbehavior that is hard to track down if you do not
|
|
know about what to look for.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.missing'>
|
|
<title>Missing functions</title>
|
|
<para>
|
|
While PHP 4 comes with a lot of new features, functions and
|
|
extensions, you may still find some functions from version 3
|
|
missing. A small number of core functions has vanished because
|
|
they do not work with the new scheme of splitting parsing and
|
|
execution as introduced into 4 with the Zend engine. Other
|
|
functions and even complete extensions have become obsolete as
|
|
newer functions and extensions serve the same task better and/or
|
|
in a more general way. Some functions just simply haven't been
|
|
ported yet and finally some functions or extensions may be missing
|
|
due to license conflicts.
|
|
</para>
|
|
|
|
<section id='migration4.missing.concept'>
|
|
<title>Functions missing due to conceptual changes</title>
|
|
<para>
|
|
As PHP 4 now separates parsing from execution it is no longer
|
|
possible to change the behavior of the parser (now embedded in
|
|
the Zend engine) at runtime as parsing already happened by
|
|
then. So the function <function>short_tags</function> no longer
|
|
exists. You can still change the parsers behavior by setting
|
|
appropriate values in the &php.ini; file.
|
|
</para>
|
|
<para>
|
|
Another feature of PHP 3 that is not a part of PHP 4 is the bundled
|
|
debugging interface. There are third-party add-ons for the Zend engine
|
|
which add similar functionality.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.deprecate'>
|
|
<title>Deprecate functions and extensions</title>
|
|
<para>
|
|
The Adabas and Solid database extensions are no more. Long live
|
|
the unified ODBC extension instead.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.unset'>
|
|
<title>Changed status for <function>unset</function></title>
|
|
<para>
|
|
<function>unset</function>, although still available, is
|
|
implemented as a language construct rather than a function.
|
|
</para>
|
|
<para>
|
|
This does not have any consequences on the behavior of
|
|
<function>unset</function>, but testing for "unset" using
|
|
<function>function_exists</function> will return &false; as it would with
|
|
other language constructs that look like functions such as
|
|
<function>echo</function>.
|
|
</para>
|
|
<para>
|
|
Another more practical change is that it is no longer possible to
|
|
call <function>unset</function> indirectly, that is
|
|
<literal>$func="unset"; $func($somevar)</literal> won't work
|
|
anymore.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section id='migration4.extensions'>
|
|
<title>PHP 3 extension</title>
|
|
<para>
|
|
Extensions written for PHP 3 will not work with PHP 4, neither as binaries
|
|
nor at the source level. It is not difficult to port extensions to PHP 4
|
|
if you have access to the original source. A detailed description of the
|
|
actual porting process is not part of this text.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.strings'>
|
|
<title>Variable substitution in strings</title>
|
|
<para>
|
|
PHP 4 adds a new mechanism to variable substitution in
|
|
strings. You can now finally access object member variables and
|
|
elements from multidimensional arrays within strings.
|
|
</para>
|
|
<para>
|
|
To do so you have to enclose your variables with curly braces with
|
|
the dollar sign immediately following the opening brace:
|
|
<literal>{$...}</literal>
|
|
</para>
|
|
<para>
|
|
To embed the value of an object member variable into a string you
|
|
simply write <literal>"text {$obj->member} text"</literal> while
|
|
in PHP 3 you had to use something like <literal>"text
|
|
".$obj->member." text"</literal>.
|
|
</para>
|
|
<para>
|
|
This should lead to more readable code, while it may break
|
|
existing scripts written for PHP 3. But you can easily check for
|
|
this kind of problem by checking for the character combination
|
|
<literal>{$</literal> in your code and by replacing it with
|
|
<literal>\{$</literal> with your favorite search-and-replace
|
|
tool.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.cookies'>
|
|
<title>Cookies</title>
|
|
<para>
|
|
PHP 3 had the bad habit of setting cookies in the reverse order
|
|
of the <function>setcookie</function> calls in your code. PHP 4
|
|
breaks with this habit and creates the cookie header lines in
|
|
exactly the same order as you set the cookies in the code.
|
|
</para>
|
|
<para>
|
|
This might break some existing code, but the old behaviour was so
|
|
strange to understand that it deserved a change to prevent further
|
|
problems in the future.
|
|
</para>
|
|
</section>
|
|
|
|
<section id='migration4.variables'>
|
|
<title>Handling of global variables</title>
|
|
<para>
|
|
While handling of global variables had the focus on to be easy in
|
|
PHP 3 and early versions of PHP 4, the focus has changed to be more
|
|
secure. While in PHP 3 the following example worked fine, in PHP 4 it
|
|
has to be unset(<literal>unset($GLOBALS["id"])</literal>);. This is
|
|
only one issue of global
|
|
variable handling. You should always have used <varname>$GLOBALS</varname>, with
|
|
newer versions of PHP 4 you are forced to do so in most cases.
|
|
Read more on this subject in the <link linkend="references.global">
|
|
<literal>global</literal> references section</link>.
|
|
</para>
|
|
<example>
|
|
<title>Migration of global variables</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:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|