PHP is a server-side, HTML-embedded scripting language, and an easy alternative to CGI scripting. Stronghold Web Server 3.0 comes with two PHP modules:
Use this module for new, PHP3-compliant scripts. You can also modify your legacy scripts for compatibility with this module. The original PHP3 documentation is located at http://www.php.net/manual/.
This chapter describes
If you already have PHP/FI 2.0 or PHP3 scripts that you want to serve through Stronghold Web Server 3.0, you can quickly install them.
To install PHP filesIf httpd.conf does not already contain these lines, you must add them and reload the server.
Make sure your PHP filenames include the filename extension that matches their MIME type:
Stronghold processes requested files automatically with the appropriate PHP module based on the filename extension.
If a .php or .php3 file contains no PHP script elements, PHP simply inserts access information at the foot of the file. If PHP script elements are present, PHP processes them each time the file is requested before sending it to the client.
If you do not want footers appended to your PHP files, you can turn them off globally or on a per-file basis. To turn them on or off globally, use the phpShowInfo configuration directive. To turn them off in individual files, add this tag:
<?setshowinfo(0)>PHP configuration takes two forms:
When you install Stronghold, you also install its PHP modules. By default, the modules are installed with all special features disabled. In order to enable the following features, you must recompile the PHP module you are using:
In order to reconfigure the PHP module to implement these special features, you must;
# cd ServerRoot/src/php3
# ./setup
The script first asks you whether you want to compile PHP3 as an Apache module.
Rule WANTHSREGEX=yes
EXTRA_LIBS= ... -lphp -lm ...
Module php3_module mod_php3.o
If you are linking database connectivity or other libraries, the EXTRA_LIBS line must include those libraries.
If you installed Stronghold Web Server 3.0 from scratch, the default server configuration file includes basic enablement for PHP3 files:
# config sample goes hereAll PHP3-compliant scripts automatically work with this configuration if they
The core of PHP has been completely rewritten from scratch to create PHP3. Several improvements were made to the language that also render it backwards-incompatible. Some low-level, undocumented features of PHP 2.0 may not to work in PHP3. It's possible that some documented behaviour of PHP 2.0 has also changed in this release and is not specified here.
The PHP3 module comes with a conversion program that can automatically convert your old PHP/FI 2.0 scripts. It can be found in the convertor/ subdirectory of the PHP3 distribution. However, this program only catches the syntax changes; your scripts may still require manual modification. Read this section carefully and take all changes into account.
This section explains three kinds of changes:
Several new aspects of the language render PHP 2.0 code incompatible with PHP3. Affected features include
<?echo $title;>
<?echo $title;?>
PHP3 also includes support for a longer-form start tag that is XML-compliant:
<?php echo $title;?>
Support for the short start tag (<?) can be enabled and disabled using the php3_short_open_tag directive.
if (expr);in PHP3 is
statements
...
elseif (expr);
statements
...
else;
statements
endif;
if (expr):
statements
...
elseif (expr):
statements
...
else:
statements
endif;
Note that the endif is followed by a semicolon and not a colon. Even in PHP3, a semicolon must mark the end of the entire if sentence. Also note that the implementation of the colon mode and curly braces mode in PHP3 is identical; one is not preferable to the other.
while (expr);
statements
...
endwhile;
while (expr):
statements
...
endwhile;
| Failing to change the semicolon to a colon can result in scripts that get stuck in the while loop because the loop-condition never changes. |
|---|
$a[0]=5;In PHP 2.0, this would display both of $a's indices. In PHP3, it doesn't display anything. The reason is that in PHP 2.0, a string comparison was made because the left argument's type was string and "" does not equal "0," so the loop went through. In PHP3, when a string is compared with an integer, an integer comparison is made (the string is converted to an integer). This results in comparing atoi(""), which is 0, and $key, which is also 0. Since 0==0, the loop doesn't go through at all.
$a[1]=7;
$key = key($a);
while ("" != $key) {
echo "$keyn";
next($a);
}
The fix for this is simple. If we replace the while statement with
while ("" != stringval($key)) {the script would first convert the integer 0 to a string "0," then compare "" and "0," which are not equal, and the loop would go through as expected. Casting operators are supported in PHP3 as a quicker and more readable way of changing variables' types. For example, you could use the following:
while ("" != (string)$key) {
$a = 123;
$string = "This is as easy as " . $a;
$string = ereg_replace("This is as easy as ", "", $string);
(1 || test_me())
the function test_me() would not be executed since the nothing can change the result of the expression after the 1. This is a minor compatibility issue, but may cause unexpected side effects.
An example of the old return values:
$fp = fopen($file, "r");
if ($fp == -1);
echo("Could not open $file for reading<br>\n");
endif;
An example of the new return values:
$fp = @fopen($file, "r") or print("Could not open $file for reading<br>\n");
PHP3 includes some new language features, including:
advanced expressions support for `for' loops support for `do...while(expr)' loops support for `break' and `continue' statements inside loops support for C-style declaration of functions OOP support support for function pointers more powerful indirect references new string concatenation operator support for passing function arguments by reference support for multidimensional arrays or `hyperdimensional variables' support for array initialization support for perl-style lists support for colons in `case' and `default' statementsassignment operators (+=, -=, *= etc.), pre and post increment/decrement (for example $i++, ++$i), and the question mark operator ( (expr?expr:expr) ). Every assignment is now an expression with a value, which means that code like $a = $b = $c = $d = 0; work.
for (expr; expr; expr) statement;or
for (expr; expr; expr) { statements ... }The first expression is executed the first time the loop is encountered. The loop is run as long as the second expression is evaluated as TRUE. After each iteration, the 3rd expression is evaluated.
| There is no support for colon-mode for loops (for:...endfor,). and notsupport is planned. |
|---|
As with its C parallel, the statements inside a do...while loop are run once the first time the loop is encountered, and then as long as the expression evaluates as true.
do {
statements;
} while ($i++ < $max);
for ($i=0; $i<10; $i++) {The first break statement would end the inner loop every time $j is greater than 5. The second break statement would end both the inner and outer loop when $i is greater than 5.
for ($j=0; $j<10; $j++) {
if ($j>5)
break;
if ($i>5)
break 2;
}
}
| In addition, switch statements are treated as loops. If you write "break 2;" inside a switch statement, you are asking to break out of the switch and the innermost loop in which it is nested. |
|---|
function concat($str1,$str2)Old-style function declarations should be changed from function to old_function.
{
return $str1.$str2;
}
class simple_class {
var $property1,$property2;
var $property3=5;
function display() {
printf("p1=%d, p2=%d, p3=%dn,"
$this->property1,
$this->property2,
$this->property3);
}
function init($p1,$p2) {
$this->property1 = $p1;
$this->property2 = $p2;
}
};
The next example shows how to create an object of that class:
$obj = new simple_class;
At this point, $obj is an object with two uninitialized variables, one initialized variable, and two member functions. No protection is made on the internals of the object, and using its properties is simple:
$obj->property1 = 7;
This assigns 7 to $property1 inside $obj. Calling member functions is also simple:
$obj->display()
This runs the display() member function of $obj. Note that the implementation of display() uses the special variable $this, which is replaced with the object the function is called on.
class complex_class extends simple_class {The class complex_class inherits everything from its parent, simple_class, except properties or member functions which override the ones in the parent. In this example, since we supply an alternative display() function, it would be used with complex_class objects instead of the display() function that was declared in simple_class. On the other hand, since we don't supply an alternative in it() function, complex_class objects would have the same init() function as simple_class objects do.
var $property4="test";
function display() {
printf("p1=%d, p2=%d, p3=%d, p4=%dn,"
$this->property1,
$this->property2,
$this->property3,
$this->property4);
}
}
$a[0] = $obj;
but you cannot reference to $a[0]'s properties using
$a[0]->...
This will be implemented in a later release of PHP.
$func_ptr = "time";is identical to
$current_time = $func_ptr();
$current_time = time();
$a = "b";This displays $e's content, which is "Testing."
$b = "c";
$c = "d";
$d = "e";
$e = "Testing";
echo $$$$$a;
In addition, one can use complex expressions to generate variable names using a perl-like notation:
$i="123";This assigns 5 to $test123.
${"test"+$i} = 5;
function inc($arg)
{
$arg++;
}
$i=0;
inc($i); /* here $i in the outer scope remains 0 */
inc(&$i); /* here $i is passed by reference and becomes 1 */
$a[0]=5;
$a[1]["testing"]=17;
$b["foo"]=$a;
$months = array("January," "February," "March,"This example assigns $months[0] to be January, $months[1] to be February, and so on. Alternatively, you may want the count to start at 1 instead of 0. You can do so easily:
"April," "May," "June," "July," "August,"
"September," "October," "November," "December");
$months = array(1=>"January," "February," "March,"You can also specify an index for every entry, not just the first one:
"April," "May," "June," "July," "August,"
"September," "October," "November," "December");
$first_names = array("Doe"=>"John,"This example assigns $first_names["Doe"]="John" and so on.
"Gates"=>"William," "Clinton"=>"Bill" });
$str = "johndoe:x:555:555:Doe, John:/home/johndoe:/bin/tcsh";
list($username,$passwd,$uid,$gid,$realname,$homedir,$shell) = explode(":,"$str);
This example assigns "johndoe" to $username, "x" to $passwd, and so on.
switch($value) {
case `A':
statement;
break;
case `B':
statement;
break;
case `C':
statement;
/* fall-through */
default:
statement;
}
PHP3 includes some new features that are not language-related:
This means that there's now an easy way of writing the SQL drivers so that they don't open and close the SQL link every time, but instead open it the first time it's required, and then use it on every later hit. As of PHP3a1, only the MySQL, mSQL and PostgresSQL drivers have been changed (rewritten) to take advantage of this option. To use it, use mysql_pconnect() instead of mysql_connect() (or the equivalents for the two other databases).
PHP now has its own configuration file, and many compile-time options of PHP2 are now configurable at runtime.
A syntax highlighter has been built into PHP3, which means PHP3 can display your code, syntax highlighted, instead of executing it. Right now, it's only easy to do this by telling Stronghold to execute a certain extension (for example, .php) and syntax highlighting another extension (for example, .phps). A future version will probably include display_source (filename) which works like include(), only it displays the syntax highlighted source instead of executing the included code.
This has a huge impact on the Windows version, and will probably be used in the UNIX environment as well. One can now add PHP internal functions at runtime by loading a dynamic module. This is known to work under Solaris, Linux, and Win32 at this time, but will be ported to any other capable platform if an incompatibility is found.
The performance of PHP3 is much better than that of PHP 2.0. Memory consumption has been dramatically reduced in many cases, due to the use of an internal memory manager, instead of Stronghold's pools. Speed-wise, PHP3 is somewhere between 2 and 3 times faster than PHP 2.0.
While PHP 2.0 performed well on simple, and fairly complex scripts, a fundamental design difference from PHP3 makes it more prone to errors. In PHP3, obscure parser problems are much less likely.
If you're a C coder, adding functionality to PHP was never easier. A well-documented API is available (apidoc.txt), and you no longer have to touch the parser or scanner code when adding your function. Also, it's more complicated to "go wrong" when implementing a PHP3 function than it was in PHP2 (no stack to maintain).