PHP4 Uncovered

by ServerWatch Staff

PHP4 is a major overhaul of PHP3. If you've been considering making the migration, check out our discussion of the latest and greatest version of this popular scripting app.

The long-awaited PHP4 version has been available since the end of May 2000. After having reached Beta-test and Release Candidate status, the final version is finally a reality.

The questions that come up systematically with each new version of a software program are, "What's new in this version?" and "Which of these new features are truly useful?" These are certainly legitimate questions, as the simple availability of a new version does not justify migration to it. Looming behind what seems to be a simple update is always a myriad of potential problems that must be zeroed in on before moving forward, especially because once updated, there's often no turning back.

Users currently questioning the availability date of PHP4 support by their favorite hosts, should note that such a task represents a considerable amount of work.

This article examines PHP4's new features, which will allow you to appreciate the tremendous work that has been carried out by Zeev Suraski and Andi Gutmans, as well as all of those of other PHP contributors.

PHP4 is a complete rewrite of PHP3 at the heart of the language's engine. But why did the authors decide to completely rewrite the language?

The manner in which PHP3's scripting engine works is not adapted to the execution of rich, large-scale applications such as Phorum or KeyStone. Indeed, this engine reads PHP script instructions line-by-line and then executes them one-by-one, thus enabling PHP3 to obtain good performance with short and simple scripts. However, it yields rather mediocre performance with larger applications, and users must understand that PHP3 was not designed to execute such applications.

Thus, PHP3's two creators decided to implement a scripting engine capable of reading all PHP code and "compiling" it before executing it. And Zend was born. This was not an easy task. Although incompatibilities could be conceived at the time of migration from PHP2 to PHP3, such differences had to be limited as much as possible between PHP3 and PHP4 due to the installed base and the number of PHP3 scripts already in use. We can congratulate PHP4's authors on a job well done because the incompatibilities that do exist are only minor.

Although Zend is an integral part of PHP4, it is actually a scripting/runtime engine independent of the PHP language. On this account, it is possible to use Zend in MySQL as the basis for the development of a stored procedure language specific to this database system.

Without going into the details of internal implementation, we can point out a few things about the Zend/PHP4 combination.

PHP4's new architecture enabled its authors to add an abstraction layer in relation to the Web server at the heart of its language. Until now, with PHP3 users had the choice of using it as a specific module for the Apache server or in CGI mode for all other HTTP servers. With PHP4 it is now possible to imagine better integration with Web servers other than Apache. This is in fact the case for Microsoft's HTTP server, IIS. PHP4 now works as an ISAPI filter for Microsoft's IIS server. For this reason, different parts of PHP4 code had to be made compliant with use in a multithread environment (PHP4 is "thread-safe").

Many new features concern PHP4's internal implementation; however, they don't really concern PHP programmers directly. Nonetheless, it is worth noting two important points: memory allocation and reference counting mechanisms. In other words, those mechanisms that free up resources that were no longer used were completely rethought. Performance and memory use are thus improved, especially for objects and tables. The more data the variables contain, the more memory saved.

With PHP3, all of the content produced by echo () or print() was sent directly to the server. In PHP4, an intermediate storage layer makes it possible to defer the sending the Web server's output flow. To do this, features so new they have yet to be documented, are available:

  • ob_start(): activates output buffering
  • ob_end_flush(): sends the contents of the output buffer and deactivates buffering
  • ob_end_clean(): empties the output buffer and deactivates buffering
  • ob_get_contents(): returns the output buffer contents
This functionality makes it possible to prepare the contents displayed via complex processes requiring several database queries, for example, and the sending of results only when all of the queries have been carried out successfully. In the opposite case, users can empty the output buffer contents and display an error message in its place. The example below shows a typical case of how these functionalities are used:

// activate output buffers
// the output is not displayed, it enters the buffer print "Hello, world!";
// read buffer contents
$output = ob_get_contents();
// deactivate the buffer, empty the buffer
// display contents
print $output;

A new evaluate for identical operator makes its debut in PHP4. This operator makes it possible to test the equality of the values and types of two different variables or expressions. With implicit PHP-type conversions, the value 5 could be compared with the string containing the character "5." These two values were considered equal in a comparison. The new operator is represented by the three equal signs ("= = =") and sends back "TRUE" only if the variable type and value are identical. Thus, in the following example, the four tests using the equality operator with the numbers 1 to 4 are true. In the subsequent four, which use the evaluate for identical operator, only tests 5 and 8 are true.

$valint1 = 1;
$valint2 = 2;
$valint3 = 3;

$valfloat1 = 1.0;
$valfloat2 = 2.0;
$valfloat3 = 3.0;

$valstr3 = '3';

$res = (($valint1+$valint2)==$valint3) ? ('TRUE'):('FALSE') ;
print " TEST 1 : " . $res . "<br>\n";

$res = ($valint3==$valfloat3) ? ('TRUE') : ('FALSE') ; print " TEST 2 : " . $res . "<br>\n";

$res = ($valstr3==$valint3) ? ('TRUE') : ('FALSE') ; print " TEST 3 : " . $res . "<br>\n";

$res = (($valfloat1+$valfloat2)==$valfloat3) ? ('TRUE') : ('FALSE') ; print " TEST 4 : " . $res . "<br>\n<br>";

"; $res = (($valint1+$valint2)===$valint3) ? ('TRUE') : ('FALSE') ;
print " TEST 5 : " . $res . "<br>\n";

$res = ($valint3===$valfloat3) ? ('TRUE') : ('FALSE') ; print " TEST 6 : " . $res . "<br>\n";

$res = ($valstr3===$valint3) ? ('TRUE') : ('FALSE') ; print " TEST 7 : " . $res . "<br>\n";

$res = (($valfloat1+$valfloat2)===$valfloat3) ? ('TRUE') : ('FALSE') ; print " TEST 8 : " . $res . "<br>\n";

It is worth noting that PHP4 now includes Boolean-type data.

On Windows platforms, PHP4 now offers support for COM components. This means that practically all Windows applications can be manipulated from PHP4. The COM model at the heart of Microsoft's architecture is such that any Windows application can provide a certain number of components and exposed methods, which are entry points for manipulating applications from other applications.

A few lines of code tend to be more useful than a long description, so let's examine the following example. The code below does nothing less than boot Word, create a new document from it, add text to this document, and then save everything on the disk before quitting.

$word = new COM("word.application") or
 die("Impossible to instantiate WordApp");
print "Word is running, version {$word->Version}\n</br>";


$word->Selection->TypeText("This is a test..."); $word->Documents[1]->SaveAs("test_com_php.doc"); $word->Quit();

Another new feature to PHP4 is a new syntax is modeled after Perl's "here printing." It is possible to display complete portions of HTML code by flanking them with either a print or echo instruction and an end label. Unlike Perl, the operator used is not a double less than sign (<<), but a triple less than sign (<<<) so as to distinguish it from the binary shift operator. For example:


$version = phpversion();
$valstr = "Example of HerePrinting\n";

echo "<hr><br>/n";

print <<< mylabel

<h4>PHP's New Features</h4>
<li>ISAPI support
<li>COM support on Win32
<li>Java and servlets support

<p>$valstr <br>Tested on PHP version $version</p>


echo "<hr><br>/n";

Java support represents without a doubt one of the new features that will open PHP up to existing enterprise systems and applications. With PHP4, users can instantiate and use Java servlets or classes.

Differences Between PHP3 and PHP4
Output Buffering
Evaluate for Identical Operator
COM support on Windows
Displaying Portions of Raw HTML Code
Java Support

This support is not native to PHP4; it necessitates the addition and configuration of an extension. To have this extension at your disposition on a Linux system, it is PHP4 must be recompiled by specifying the adequate configuration options. These extensions are available in the form of objects that have been precompiled for the Windows environment. These extensions can be downloaded from the official PHP Web site. You must choose the extension adapted to the Java version that you use (JDK 1.1.8, 1.2 or 1.3). In the example, we are using a simple JDK 1.1.8.

In the php.ini configuration file, you must add two lines in a new "Java" section as in the following example:

C:\Program Files\Apache\cgi-bin\php_java.jar;
C:\Program Files\Apache\htdocs\phpjava" extension=php_java.dll

Place the Java classes that you would like to use in one of the directories given in the list of paths specified by the java.class.path configuration directive, for example in C:\Program Files\Apache\htdocs\phpjava

Imagine that you have a Java class named Point, which represents a point defined by its coordinates and the various required methods (a constructor, a default constructor, traditional access methods to set and get proprieties, and a toString method). The Point class might look something like the following:

public class Point {

// attributes
public int abscissa;
public int ordinate;

public int type;

// default constructor
public Point() {
  this.type = 1 ;
// constructor
public Point(int x,int y) {
   this.type = 1 ;
// Overloaded object method
public toString String(){
   // Call the display method
   return display();
// Point class methods
public void setType(int mytype){
   // Call the display method
   this.type = mytype;
public int getAbscissa() { return abscissa; }
public int getOrdinate() { return ordinate; }
public void setCoordinates(int abscissa, int ordinate) {   this.abscissa = abscissa;
  this.ordinate = ordinate;
public sayHello String() {
  return "I am a point :-)";
public display String(){
return "("+abscissa+","+ordinate+" Type "+type+")";

Thus, as long as Java support is configured correctly and the bytecode file Point.class is in the appropriate place, we can execute the following PHP code:


$myPoint = new Java("Point");
echo "<br>Point created at (0,0) ...";

echo $myPoint->setCoordinates(15,15);
echo "<br>Point moved to (15,15)";
echo "<br>".$myPoint->display();
echo "<br>".$myPoint->sayHello();
echo "<hr>\n";


Which triggers the following display:

Point created at (0,0) ...
Point moved to (15,15)
(15,15 Type 1)
I am a Point :-)

Even more interesting is that a PointBis class can be derived from a Point class by overloading its constructors.

public class PointBis extends Point {

// constructors
public PointBis() {

public PointBis(int x,int y) {


// methods
public sayHello String() {
  return "I am a PointBis ;^)";

In the same way, we can instantiate and use an object of the PointBis class as in the following example:

$myPointBis = new Java("PointBis");
echo "<br> Point created at (0,0) ...";

echo $myPointBis->setCoordinates(17,21);
echo "<br>Point moved to (17,21)";
echo "<br>".$myPointBis->display ();
echo "<br>".$myPointBis->sayHello();

Which provides the following results:

Point created at (0,0) ...
Point moved to (17,21)
(17,21 Type 2)
I am a PointBis ;^)

But you might also want to transfer objects to methods of other objects. For example, let's take a class that represents a vector. The vector is defined by its origin (a point), its standard and its direction. In Java, the Vector class can be defined in the following manner:

public class Vector {

// attributes
private Point origin;
private int standard;
private int direction;

// constructors
public Vector() {
  Point p1 = new Point();
  setProps(p1, 0, 0);
public Vector(Point orig, int s, int d) {
setProps(orig, s, d);

// Overloaded Object method
public toString() String{
  // Call the display method
  return display ();
// Vector class methods
public Point getOrigin () { return origin; }
public int getStandard() { return standard; }
public int getDirection() { return direction; }
public void setOrigin (Point origin) {
  this.origin = origin;
} ;
public void setStandard(int standard) {
  this.standard =standard;
} ;
public void setDirection(int direction) {
  this.direction = direction;
} ;
public void setProps(Point origin, int standard, int direction) {
  this.origin = origin;
  this.standard = standard;
  this.direction = direction;
public display() String {
  return "( "+origin.display()+
      " / "+standard+" / "+direction+" )";

In PHP, we can instantiate a vector by using the default constructor with the following code:

$myVector = new Java("Vector");
echo "<br>Vector created, default constructor...";
echo "<br>".$myVector->display()." <p>\n<br>\n";


Which results in the following display:

Vector created, default constructor...
( (0,0 Type 1) / 0 / 0 )

But we can also use the Vector class constructor to transfer a PHP object representing a Point object. Consider the example below

// creation of a point that will serve as vector origin $myPoint = new Java("Point", 11, 65);
echo "<br>Point position...";
echo "<br>".$myPoint->display().<p>\n<br>\n";

$myVector = new Java("Vector");
echo "<br>".$myVector->display()."<p>\n<br>\n";

print $myVector->setProps($myPoint, 24, 8);
echo "<br>myVector's origin is MyPoint";

echo "<br>Vector Position...";
echo "<br>".$myVector->display()."<p>\n<br>\n";

This code triggers the following display:

Point Position...
(11,65 Type 1)
( (0,0 Type 1) / 0 / 0 )

myVector's origin is MyPoint
Vector Position...
( (11,65 Type 1) / 24 / 8 )

We can see that the vector was originally created by its default constructor: It is a null vector for which the origin is (0,0), having a null standard and a null angle direction. Then, after calling the setProps() method, we make sure that the vector origin corresponds to the coordinates of our myPoint point (11,65).

This simple example is a way of verifying whether Java can be used from PHP, regardless of if they are your own Java codes or existing Java classes. This Java gateway has many applications. Examples include, using CORBA components via IIOP, distributing processes via IIOP, distributing processes via RMI, and coding portions of "sensitive" code of Java applications so that the source code cannot be unveiled.

Finally, it is very important to note that PHP4 is not distributed under the GNU GPL license as was PHP3. It is instead under a specific license called the PHP License. In essence, the PHP License is quite similar to the BSD license. It authorizes distribution and modification of PHP within open source or proprietary applications. Moreover, Zend, which is an integral part of PHP4, is distributed under yet another license, the Zend License, which was inspired by Troll Tech's QPL.

This license enables authors to take advantage of all of the contributions and corrections made by the community while reserving the right to make money off of the commercial licenses for the Zend library. However, this does not really concern PHP script programmers and designers.

implementation that necessitated conception and a total rewrite on the part of Zeev Suraski, Andi Gutmans and all members of the PHP core team. PHP4 is a free solution that is of high technical quality and which will most certainly result in extremely rich professional applications.
This article was originally published on Thursday Sep 7th 2000
Mobile Site | Full Site