incorporate php3 to php4 migration notes from website into manual

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@39864 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
jim winstead 2001-01-20 03:49:35 +00:00
parent eb70859cdf
commit 8a7cc8d608

View file

@ -1,91 +1,213 @@
<appendix id="migration">
<title>Migrating from PHP/FI 2.0 to PHP 3.0</title>
<title>Migrating from older version of PHP</title>
<sect1 id="migration-about">
<title>About the incompatbilities in 3.0</title>
<sect1 id="migration.php4">
<title>Migrating from PHP 3 to PHP 4</title>
<simpara>
PHP 3.0 is rewritten from the ground up. It has a proper parser
that is much more robust and consistent than 2.0's. 3.0 is also
significantly faster, and uses less memory. However, some of
these improvements have not been possible without compatibility
changes, both in syntax and functionality.</simpara>
Migration from PHP 3 to PHP 4 is relatively easy, and should
not require you to change your code in any way. There are
minor incompatibilities between the two versions; You may want
to check the incompatibilities list to make sure that you're
indeed not affected by them (the chances you're affected by
these incompatibilities are extremely slim).
</simpara>
<sect2 id="migration.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 PHP3 and PHP4 to use APXS
(--with-apxs) and the necessary link extensions
(--enable-versioning). Otherwise, all standard installations
instructions apply. For example:
<informalexample><programlisting>
$ ./configure \
--with-apxs=/apache/bin/apxs \
--enable-versioning \
--with-mysql \
--enable-track-vars
</programlisting></informalexample>
</para>
</sect2>
<simpara>
In addition, PHP's developers have tried to clean up both PHP's
syntax and semantics in version 3.0, and this has also caused some
incompatibilities. In the long run, we believe that these changes
are for the better.</simpara>
<sect2 id="migration.php4.configuration">
<title>Migration Configuration Files</title>
<sect3 id="migration.php4.configuration.global">
<title>Global Configuration File</title>
<simpara>
The global configuration file, php3.ini, has changed its name to php.ini.
</simpara>
</sect3>
<sect3 id="migration.php4.configuration.apache">
<title>Apache Configuration Files</title>
<para>
The MIME types recognized by the PHP module have changed.
<informalexample><programlisting>
application/x-httpd-php3 --&gt; application/x-httpd-php
application/x-httpd-php3-source --&gt; 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>
AddType application/x-httpd-php3 .php3
AddType application/x-httpd-php3-source .php3s
<simpara>
This chapter will try to guide you through the incompatibilities
you might run into when going from PHP/FI 2.0 to PHP 3.0 and help
you resolve them. New features are not mentioned here unless
necessary.</simpara>
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>
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 - safe mode (if you could override safe mode settings in .htaccess files, it would defeat safe-mode'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.0 is bundled with scripts that automatically convert your Apache configuration and .htaccess files to work with both PHP 3.0 and PHP 4.0. 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>
~/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 aphtaccess-conv.sh script (available in the scripts/apache/ directory as well):
<informalexample><programlisting>
~/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>
</sect3>
<simpara>
A conversion program that can automatically convert your old
PHP/FI 2.0 scripts exists. It can be found in the <filename class="directory">convertor</filename> subdirectory of the PHP 3.0
distribution. This program only catches the syntax changes though,
so you should read this chapter carefully anyway.</simpara></sect1>
</sect2>
</sect1>
<sect1 id="migration-startendtags">
<title>Start/end tags</title>
<sect1 id="migration.php3">
<title>Migrating from PHP/FI 2.0 to PHP 3.0</title>
<para>
The first thing you probably will notice is that PHP's start and end
tags have changed. The old <literal>&lt;? &gt;</literal> form has been
replaced by three new possible forms:
<example>
<title>Migration: old start/end tags</title>
<programlisting>
<sect2 id="migration-about">
<title>About the incompatibilities in 3.0</title>
<simpara>
PHP 3.0 is rewritten from the ground up. It has a proper parser
that is much more robust and consistent than 2.0's. 3.0 is also
significantly faster, and uses less memory. However, some of
these improvements have not been possible without compatibility
changes, both in syntax and functionality.</simpara>
<simpara>
In addition, PHP's developers have tried to clean up both PHP's
syntax and semantics in version 3.0, and this has also caused some
incompatibilities. In the long run, we believe that these changes
are for the better.</simpara>
<simpara>
This chapter will try to guide you through the incompatibilities
you might run into when going from PHP/FI 2.0 to PHP 3.0 and help
you resolve them. New features are not mentioned here unless
necessary.</simpara>
<simpara>
A conversion program that can automatically convert your old
PHP/FI 2.0 scripts exists. It can be found in the <filename class="directory">convertor</filename> subdirectory of the PHP 3.0
distribution. This program only catches the syntax changes though,
so you should read this chapter carefully anyway.</simpara></sect2>
<sect2 id="migration-startendtags">
<title>Start/end tags</title>
<para>
The first thing you probably will notice is that PHP's start and end
tags have changed. The old <literal>&lt;? &gt;</literal> form has been
replaced by three new possible forms:
<example>
<title>Migration: old start/end tags</title>
<programlisting>
&lt;? echo "This is PHP/FI 2.0 code.\n"; &gt;
</programlisting></example>
As of version 2.0, PHP/FI also supports this variation:
As of version 2.0, PHP/FI also supports this variation:
<example><title>Migration: first new start/end tags</title>
<programlisting>
<example><title>Migration: first new start/end tags</title>
<programlisting>
&lt;? echo "This is PHP 3.0 code!\n"; ?&gt;
</programlisting></example>
Notice that the end tag now consists of a question mark and a
greater-than character instead of just greater-than. However, if
you plan on using XML on your server, you will get problems with
the first new variant, because PHP may try to execute the XML
markup in XML documents as PHP code. Because of this, the
following variation was introduced:
Notice that the end tag now consists of a question mark and a
greater-than character instead of just greater-than. However, if
you plan on using XML on your server, you will get problems with
the first new variant, because PHP may try to execute the XML
markup in XML documents as PHP code. Because of this, the
following variation was introduced:
<example><title>Migration: second new start/end tags</title>
<programlisting>
<example><title>Migration: second new start/end tags</title>
<programlisting>
&lt;?php echo "This is PHP 3.0 code!\n"; ?&gt;
</programlisting></example>
Some people have had problems with editors that don't understand
the processing instruction tags at all. Microsoft FrontPage is one
such editor, and as a workaround for these, the following variation
was introduced as well:
Some people have had problems with editors that don't understand
the processing instruction tags at all. Microsoft FrontPage is one
such editor, and as a workaround for these, the following variation
was introduced as well:
<example><title>Migration: third new start/end tags</title>
<programlisting>
<example><title>Migration: third new start/end tags</title>
<programlisting>
&lt;script language="php"&gt;
echo "This is PHP 3.0 code!\n";
&lt;/script&gt;
</programlisting></example></para></sect1>
</programlisting></example></para></sect2>
<sect1 id="migration-if-endif">
<title>if..endif syntax</title>
<sect2 id="migration-if-endif">
<title>if..endif syntax</title>
<para>
The `alternative' way to write if/elseif/else statements, using if();
elseif(); else; endif; cannot be efficiently implemented without
adding a large amount of complexity to the 3.0 parser. Because of
this, the syntax has been changed:
<example>
<title>Migration: old if..endif syntax</title>
<programlisting>
<para>
The `alternative' way to write if/elseif/else statements, using if();
elseif(); else; endif; cannot be efficiently implemented without
adding a large amount of complexity to the 3.0 parser. Because of
this, the syntax has been changed:
<example>
<title>Migration: old if..endif syntax</title>
<programlisting>
if ($foo);
echo "yep\n";
elseif ($bar);
@ -94,9 +216,9 @@ else;
echo "nope\n";
endif;
</programlisting></example>
<example>
<title>Migration: new if..endif syntax</title>
<programlisting>
<example>
<title>Migration: new if..endif syntax</title>
<programlisting>
if ($foo):
echo "yep\n";
elseif ($bar):
@ -106,46 +228,46 @@ else:
endif;
</programlisting></example>
Notice that the semicolons have been replaced by colons in all
statements but the one terminating the expression (endif).</para></sect1>
Notice that the semicolons have been replaced by colons in all
statements but the one terminating the expression (endif).</para></sect2>
<sect1 id="migration-while">
<title>while syntax</title>
<para>
Just like with if..endif, the syntax of while..endwhile has changed
as well:
<example><title>Migration: old while..endwhile syntax</title>
<programlisting>
<sect2 id="migration-while">
<title>while syntax</title>
<para>
Just like with if..endif, the syntax of while..endwhile has changed
as well:
<example><title>Migration: old while..endwhile syntax</title>
<programlisting>
while ($more_to_come);
...
endwhile;
</programlisting></example>
<example><title>Migration: new while..endwhile syntax</title>
<programlisting>
<example><title>Migration: new while..endwhile syntax</title>
<programlisting>
while ($more_to_come):
...
endwhile;
</programlisting></example>
</para>
<warning>
</para>
<warning>
<simpara>
If you use the old while..endwhile syntax in PHP 3.0, you will get
a never-ending loop.
</simpara>
</warning></sect2>
<sect2 id="migration-expr">
<title>Expression types</title>
<simpara>
If you use the old while..endwhile syntax in PHP 3.0, you will get
a never-ending loop.
</simpara>
</warning></sect1>
PHP/FI 2.0 used the left side of expressions to determine what type
the result should be. PHP 3.0 takes both sides into account when
determining result types, and this may cause 2.0 scripts to behave
unexpectedly in 3.0.</simpara>
<simpara></simpara>
<sect1 id="migration-expr">
<title>Expression types</title>
<simpara>
PHP/FI 2.0 used the left side of expressions to determine what type
the result should be. PHP 3.0 takes both sides into account when
determining result types, and this may cause 2.0 scripts to behave
unexpectedly in 3.0.</simpara>
<simpara></simpara>
<para>
Consider this example:
<informalexample><programlisting>
<para>
Consider this example:
<informalexample><programlisting>
$a[0]=5;
$a[1]=7;
@ -156,151 +278,152 @@ while ("" != $key) {
}
</programlisting></informalexample>
In PHP/FI 2.0, this would display both of $a's indices. In PHP
3.0, it wouldn't display anything. The reason is that in PHP 2.0,
because the left argument's type was string, a string comparison
was made, and indeed <literal>""</literal> does not equal
<literal>"0"</literal>, and the loop went through. In PHP 3.0,
when a string is compared with an integer, an integer comparison is
made (the string is converted to an integer). This results in
comparing <literal>atoi("")</literal> which is
<literal>0</literal>, and <literal>variablelist</literal> which is
also <literal>0</literal>, and since <literal>0==0</literal>, the
loop doesn't go through even once.
In PHP/FI 2.0, this would display both of $a's indices. In PHP
3.0, it wouldn't display anything. The reason is that in PHP 2.0,
because the left argument's type was string, a string comparison
was made, and indeed <literal>""</literal> does not equal
<literal>"0"</literal>, and the loop went through. In PHP 3.0,
when a string is compared with an integer, an integer comparison is
made (the string is converted to an integer). This results in
comparing <literal>atoi("")</literal> which is
<literal>0</literal>, and <literal>variablelist</literal> which is
also <literal>0</literal>, and since <literal>0==0</literal>, the
loop doesn't go through even once.
</para>
<para>
The fix for this is simple. Replace the while statement with:
<informalexample><programlisting>
</para>
<para>
The fix for this is simple. Replace the while statement with:
<informalexample><programlisting>
while ((string)$key != "") {
</programlisting></informalexample></para></sect1>
</programlisting></informalexample></para></sect2>
<sect1 id="migration-errors">
<title>Error messages have changed</title>
<simpara>
PHP 3.0's error messages are usually more accurate than 2.0's were,
but you no longer get to see the code fragment causing the error.
You will be supplied with a file name and a line number for the
error, though.
</simpara></sect1>
<sect2 id="migration-errors">
<title>Error messages have changed</title>
<simpara>
PHP 3.0's error messages are usually more accurate than 2.0's were,
but you no longer get to see the code fragment causing the error.
You will be supplied with a file name and a line number for the
error, though.
</simpara></sect2>
<sect1 id="migration-booleval">
<title>Short-circuited boolean evaluation</title>
<simpara>
In PHP 3.0 boolean evaluation is short-circuited. This means that
in an expression like <literal>(1 || test_me())</literal>, the
function <function>test_me</function> would not be executed since
nothing can change the result of the expression after the
<literal>1</literal>.</simpara>
<simpara>
This is a minor compatibility issue, but may cause unexpected
side-effects.</simpara></sect1>
<sect2 id="migration-booleval">
<title>Short-circuited boolean evaluation</title>
<simpara>
In PHP 3.0 boolean evaluation is short-circuited. This means that
in an expression like <literal>(1 || test_me())</literal>, the
function <function>test_me</function> would not be executed since
nothing can change the result of the expression after the
<literal>1</literal>.</simpara>
<simpara>
This is a minor compatibility issue, but may cause unexpected
side-effects.</simpara></sect2>
<sect1 id="migration-truefalse">
<title>Function true/false return values</title>
<simpara>
Most internal functions have been rewritten so they return TRUE
when successful and FALSE when failing, as opposed to 0 and -1 in
PHP/FI 2.0, respectively. The new behaviour allows for more
logical code, like <literal>$fp = fopen("/your/file") or
fail("darn!");</literal>. Because PHP/FI 2.0 had no clear rules
for what functions should return when they failed, most such
scripts will probably have to be checked manually after using the
2.0 to 3.0 convertor.</simpara>
<para>
<example>
<title>Migration from 2.0: return values, old code</title>
<programlisting>
<sect2 id="migration-truefalse">
<title>Function true/false return values</title>
<simpara>
Most internal functions have been rewritten so they return TRUE
when successful and FALSE when failing, as opposed to 0 and -1 in
PHP/FI 2.0, respectively. The new behaviour allows for more
logical code, like <literal>$fp = fopen("/your/file") or
fail("darn!");</literal>. Because PHP/FI 2.0 had no clear rules
for what functions should return when they failed, most such
scripts will probably have to be checked manually after using the
2.0 to 3.0 convertor.</simpara>
<para>
<example>
<title>Migration from 2.0: return values, old code</title>
<programlisting>
$fp = fopen($file, "r");
if ($fp == -1);
echo("Could not open $file for reading&lt;br&gt;\n");
endif;
</programlisting>
</example>
<example>
<title>Migration from 2.0: return values, new code</title>
<programlisting>
</example>
<example>
<title>Migration from 2.0: return values, new code</title>
<programlisting>
$fp = @fopen($file, "r") or print("Could not open $file for reading&lt;br&gt;\n");
</programlisting>
</example></para></sect1>
</example></para></sect2>
<sect1 id="migration-other">
<title>Other incompatibilities</title>
<sect2 id="migration-other">
<title>Other incompatibilities</title>
<itemizedlist>
<listitem><simpara>
The PHP 3.0 Apache module no longer supports Apache versions
prior to 1.2. Apache 1.2 or later is required.</simpara></listitem>
<itemizedlist>
<listitem><simpara>
The PHP 3.0 Apache module no longer supports Apache versions
prior to 1.2. Apache 1.2 or later is required.</simpara></listitem>
<listitem><simpara> <function>echo</function> no longer
supports a format string. Use the
<function>printf</function> function instead.</simpara></listitem>
<listitem><simpara> <function>echo</function> no longer
supports a format string. Use the
<function>printf</function> function instead.</simpara></listitem>
<listitem><simpara>
In PHP/FI 2.0, an implementation side-effect caused
<literal>$foo[0]</literal> to have the same effect as
<literal>$foo</literal>. This is not true for PHP 3.0.</simpara></listitem>
<listitem><simpara>
In PHP/FI 2.0, an implementation side-effect caused
<literal>$foo[0]</literal> to have the same effect as
<literal>$foo</literal>. This is not true for PHP 3.0.</simpara></listitem>
<listitem><simpara>
Reading arrays with <literal>$array[]</literal> is no longer
supported</simpara>
<listitem><simpara>
Reading arrays with <literal>$array[]</literal> is no longer
supported</simpara>
<simpara>
That is, you cannot traverse an array by having a loop that does
<literal>$data = $array[]</literal>. Use
<function>current</function> and <function>next</function>
instead.</simpara>
<simpara>
Also, <literal>$array1[] = $array2</literal> does not append the
values of <literal>$array2</literal> to <literal>$array1</literal>,
but appends <literal>$array2</literal> as the last entry of
<literal>$array1</literal>. See also multidimensional array
support.</simpara></listitem>
<simpara>
That is, you cannot traverse an array by having a loop that does
<literal>$data = $array[]</literal>. Use
<function>current</function> and <function>next</function>
instead.</simpara>
<simpara>
Also, <literal>$array1[] = $array2</literal> does not append the
values of <literal>$array2</literal> to <literal>$array1</literal>,
but appends <literal>$array2</literal> as the last entry of
<literal>$array1</literal>. See also multidimensional array
support.</simpara></listitem>
<listitem>
<simpara> <literal>"+"</literal> is no longer overloaded as a
concatenation operator for strings, instead it converts it's
arguments to numbers and performs numeric addition. Use
<literal>"."</literal> instead.</simpara></listitem>
</itemizedlist>
<listitem>
<simpara> <literal>"+"</literal> is no longer overloaded as a
concatenation operator for strings, instead it converts it's
arguments to numbers and performs numeric addition. Use
<literal>"."</literal> instead.</simpara></listitem>
</itemizedlist>
<example>
<title>Migration from 2.0: concatenation for strings</title>
<programlisting>
<example>
<title>Migration from 2.0: concatenation for strings</title>
<programlisting>
echo "1" + "1";
</programlisting>
<para>
In PHP 2.0 this would echo 11, in PHP 3.0 it would echo 2. Instead
use:
<para>
In PHP 2.0 this would echo 11, in PHP 3.0 it would echo 2. Instead
use:
<programlisting>
<programlisting>
echo "1"."1";
</programlisting>
<programlisting>
<programlisting>
$a = 1;
$b = 1;
echo $a + $b;
</programlisting></para>
<para>
This would echo 2 in both PHP 2.0 and 3.0.
<para>
This would echo 2 in both PHP 2.0 and 3.0.
<programlisting>
<programlisting>
$a = 1;
$b = 1;
echo $a.$b;
</programlisting>
This will echo 11 in PHP 3.0.</para>
</example></sect1>
This will echo 11 in PHP 3.0.</para>
</example></sect2>
</sect1>
</appendix>
</appendix>
<!-- Keep this comment at the end of the file
Local variables: