PHP 5, Oracle, and the Future

2020 年 9 月 14 日1810

PHP 5, Oracle, and the Future
by Andi Gutmans

Get an overview of some of the new features in PHP 5—as well as comments on its future for Oracle users—from its release manager.

PHP 5 (PHP: ) was officially released on July 13, 2004. Not surprisingly, the release was widely covered by the media due to the leadership role PHP plays in the Web application market. It is true that technologies such as .NET and J2EE have had more exposure and hype than PHP, but ease-of-use, performance, tight integration with the Apache Web server, and a large collection of application building blocks have made PHP one of the leading Web application development languages.

You might ask yourself, since PHP 4 featuring the Zend Engine was so successful, why do we even need PHP 5 and the Zend Engine II? The truth is that there are certain areas in which PHP 4 does not excel. Most of these areas are more important for large projects and companies, where project management is more structured and interoperability between systems is a must. PHP 5 addresses these issues, allowing PHP not only to be more attractive for such projects but also to remain a leading technology for Web application development.

In this article I will address:

The reasoning behind PHP 5

A short overview of some of its new features

A brief look at the future for PHP and Oracle users.

The New Object-Oriented Model of the Zend Engine II

Background With PHP's adoption growing steadily, its use in larger projects is also constantly increasing. There does seem to be a connection between large projects and the use of object-oriented (OO) methodology. Not that you can't write a small OO application, and it is certainly possible to write large, impressive applications without object-oriented programming (OOP). However, there does seem to be a tendency to pick the OO paradigm in these cases—probably because OOP offers more conventional tools for functional and technical design (UML — Unified Modeling Language), reuse of solutions for recurring problems (design patterns), and built-in mechanisms in the OO languages themselves that help enforce software designs and contracts.

The main problem with PHP's object model in prior versions was that objects were implemented as native types with copy semantics similar to integers and strings. This not only led to some very confusing behavior, due to sometimes unexpected implicit object cloning by PHP, but it also didn't allow us to implement some basic features, such as the ability to de-reference objects that are returned from methods.

The following examples illustrate these two problems.
a) Implicit object cloning:

<?php

class Person {

var $name;

function Person($name) {

$this->name = $name;

}

function setName($name) {

$this->name = $name;

}

function getName() {

return $this->name;

}

}

function lowerCaseName($obj)

{

$new_name = strtolower($obj->getName());

$obj->setName($new_name);

}

$obj = new Person("Andi");

lowerCaseName($obj);

print $obj->getName();

?>

Most developers would expect this example to print out "andi." However, surprisingly, this example prints out "Andi" in PHP 4. This is due to the previously mentioned way PHP 4 treats objects like regular native types, and as a result, passing $obj to lowerCaseName() by value actually clones the object. The resulting manipulation that lowerCaseName() performs on $obj is done on a cloned version of the object. This behavior not only leads to surprising results but, for developers who were aware of this problem, it would require passing and returning objects by-reference, which would make the code harder to maintain because they'd have to insert "&" in many places (passing by-reference, returning by-reference, and assigning by-reference).

b) Inability to de-reference objects returned from methods:

$obj->getParentObject()->method();

If you aren't familiar with PHP 4, you would probably expect this example to work. However, as a result of the before-mentioned implicit cloning, the ability to de-reference an object that is returned from a method did not exist and could not be implemented. As a workaround, a lot of PHP 4 code would look as follows:

$temp_obj &= $obj->getParentObject();

$temp_obj->method();

There are other examples of how the basic infrastructure of objects was flawed in PHP 4, but these two examples should give you a good idea.

Main new language features. The most basic and important change in PHP 5 is to use handles (or id's) for objects instead of implementing them as native datatypes. When copied, only the handle (the id number) itself is actually being copied; the objects these handles represent are not being copied. This seemingly minor change in the semantics of the language is the major driving force behind the majority of the new PHP 5 features. It allows the addition of new language features and new PHP extensions, such as the great SimpleXML that takes full advantage of the new semantics.

Without going into too much detail (or this article would become a book), the following is a list of new language features in PHP 5.

New object cloning semantics As mentioned, the scripting engine never automatically clones objects in PHP 5, whether they are assigned, passed by-value, or returned by-value from a function. If cloning is required, then the developer may explicitly clone an object by using the new clone keyword (for example, clone $obj;). The developer may also implement a method named __clone() in his class, which will be called on the new resulting object, after the clone operation has copied all of the original object's properties. Implementing this callback is not required but can be useful if the developer wishes each object to have its own copy of a certain resource, thereby creating a new version of that resource for the cloned object (otherwise, both objects would be using the same resource). An example of such a resource is a file.

Public/private/protected access modifiers. PHP 5 supports the PPP (Private/Public/Protected) access modifiers commonly found in other object-oriented languages, such as C++ and Java. These access modifiers may be used on both properties and methods, and impose access restrictions.

Interfaces and abstract classes and methods. We at Zend Technologies received many requests for multiple inheritance (MI) in PHP, so we decided to address this issue in PHP 5. After comparing the implementation of many languages—mainly C++ and Java—to see which could be most easily adapted to PHP's dynamic nature, we decided to provide a solution for MI by using Java-style interfaces and abstract classes.

Ability for PHP extensions to overload PHP object syntax. Probably one of the most significant features of PHP 5 is the way the Zend Engine II has an abstraction layer between the object syntax and its semantics. This approach allows PHP extensions to create their own objects, which have different behavior than the user-level PHP objects. For example, the new COM extension uses these overloading capabilities in order to access COM objects in a way that is natural for PHP developers, using the regular PHP object syntax:

$ie = new COM("InternetExplorer.Application"); 

$ie->Visible = true;

$ie->Navigate("http://http://www.zjjv.com///");

Other extensions that take advantage of this ability include the SimpleXML, SOAP, and Perl extensions.

Other New Features There are probably a dozen more new language features in PHP 5, such as class constants, static properties and methods, __autoload(), and instanceof operator.You can find a more complete list at http://http://www.zjjv.com///php5.

Design Patterns As previously discussed, the ability to use design patterns in large (and often also small) PHP software projects is extremely important. It was possible to take advantage of such patterns in PHP 4, but—lacking important language features such as static properties and methods, PPP access modifiers, and interfaces—it was often hard to enforce all of the semantics of these patterns.

Singleton Pattern An often-used and excellent example is the Singleton pattern. Although it is one of the simpler patterns, in order to implement it in its entirety, static properties and methods and PPP access modifiers are a necessity.

For example:

<?php

class MySingleton {

static private $instance = NULL;

private function __construct() {

}

private function __clone() {

}

static public function Instance() {

if (self::$instance == NULL) {

self::$instance = new MySingleton();

}

return self::$instance;

}

// ... Additional code for the MySingleton class.

}

This implementation takes advantage of the new PHP 5 features, which results in a cleaner and less error-prone Singleton implementation. For example, the ability to declare the constructor and clone methods as private prevents developers from mistakenly instantiating an additional copy of the MySingleton class, as only the class itself may access these methods. The support for static properties is used in order to have a globally accessible property (self::$instance) that references the single instance of the class. Declaring the property private makes sure that only the class itself may fiddle with this property.

Immutable Object Pattern Another slightly less common design pattern is the Immutable Object pattern. This pattern is usually used in applications where a large amount of references to a relatively small group of values exists. It allows the application's code to share objects by making the objects immutable (forbidding their state to change), and forcing code that wants to do so to create a new instance of the class.

The following example shows how you can create a class that represents a SQL query. The assembled query statement itself might be used in many places in your application. Code that wishes to change the value of the query may do so using the changeStmt() method, which returns a handle to a new object that represents the specified query string.

<?php

final class ImmutableQueryStatement {

private $stmt;

public function __construct($stmt) {

$this->stmt = $stmt;

}

public function getStmt() {

return $this->stmt;

}

public function changeStmt($stmt) {

return new ImmutableQueryStatement($stmt);

}

}

This example takes advantage of a few new PHP 5 language features. To begin with, it uses the final keyword so that the class may not be "subclassed." This approach prevents developers from subclassing and implementing a version that may be mutable. In addition, changeStmt() takes advantage of the new object handles and returns the newly created object by-value (in PHP 4, a new object instance would have to be returned by reference, complicating the implementation). Last but not least, similar to the previous example, access modifiers are used to specify the access contract this class should adhere to.

XML and Web Services in PHP 5

Background In the past few years, XML has become increasingly important, allowing different applications and systems to interoperate using standard tools and methodology for dealing with data. This is one of the reasons for Oracle's and other vendors' strong support and adoption of the technology. In every company, the data is the centerpiece of the organization.

XML support in PHP 4 was quite a mess. Although it supported SAX (Simple API for XML), DOM (Document Object Model) and XSL (eXtensible Stylesheet Language), there was no unified and standards-conforming implementation. The SAX implementation was based on the aging Expat XML parser, the DOM extension's naming conventions weren't standards-conforming, and the extension never left experimental status. Also, XSL was supported using yet another XML library called Sablotron.

It was decided to rewrite the XML support in PHP 5, and a few developers from the PHP community stepped up to make this rewrite a reality. The first and most important decision was that all XML functionality be based on the excellent libxml2 library from the Gnome's project. With this in mind, all three existing extensions were rewritten. Most important, the DOM extension was revamped and its interface redefined to be W3C-compliant. At the time of PHP 5's release, DOM was no longer experimental but full-featured and stable.

SimpleXMLBesides the importance of rewriting and unifying the existing XML extensions, a new XML extension has emerged. This extension, called SimpleXML, allows developers to access XML files as if they were native PHP objects. Going back a few sections in this article, this became possible due to the new Zend Engine II giving extensions the ability to overload the object-oriented syntax.

Consider the following XML file:

<clients>

<client>

<name>John Doe</name>

<account_number>87234838</account_number>

</client>

<client>

<name>Janet Smith</name>

<account_number>72384329</account_number>

</client>

</clients>

The following PHP 5 code iterates over the XML file and prints out the names and account numbers of the clients:

<?php

$clients = simplexml_load_file('clients.xml');

foreach($clients->client as $client) {

print "$client->name account: $client->account_number\n";

}

Running this sample script would result in the following output:

John Doe account: 87234838

Janet Smith account: 72384329

With SimpleXML, accessing XML files becomes extremely easy. I have no doubt that SimpleXML will revolutionize the ease-of-use provided to the PHP developer for dealing with XML files. And if there are certain things SimpleXML cannot do, then due to the fact that both SimpleXML and the DOM extension use the same underlying library, the SimpleXML object can be converted to a DOM tree and more-advanced XML manipulations can be done in DOM. This conversion back and forth between SimpleXML and DOM is zero-copy, meaning it costs neither time nor additional memory.

SOAP Going back to my introduction, I mentioned interoperability as a key issue for large companies. Web services— and more specifically, the SOAP protocol—are becoming increasingly popular for solving interoperability issues between two or more systems.

As PHP 4 did not feature native integrated SOAP support in the default distribution, we believed that this issue had to be addressed for PHP 5. Therefore, we created a new native implementation for SOAP (client as well as server APIs) that allows PHP developers to create and consume Web services easily.

The following example shows just how easy it is to call SOAP services from PHP. You might notice that this extension uses the same object-oriented overloading capabilities as mentioned previously.

<?php

$client =

new SoapClient("http://http://www.zjjv.com///soap/urn:xmethods-delayed-quotes.wsdl");

print($client->getQuote("ORCL"));

At the time of this writing, running this example resulted in printing 11.23.

The Future and Oracle

General Released in July 2004, PHP 5 has only been around for a short time. Despite that, there are already quite a few interesting things happening in PHP development. There has been a lot of work on improving the performance of the scripting engine and, most importantly for the Oracle readers, there are many new database-related initiatives. Use of Oracle is strong in the PHP community, and a large amount of Zend customers are Oracle users. Their use of Oracle varies as it does with other databases but is usually a very conscious choice, which has to do with Oracle's proven track record, advanced features, and often an already existing investment in Oracle infrastructure.

Scripting Engine Performance When developing PHP 5, Zend and the community focused more on functionality than on performance. Therefore, except for a few exceptions, performance of the scripting engine was not improved between PHP 4 and 5.

In most PHP applications, the raw execution performance of PHP is not the main bottleneck. The most common bottlenecks are related to I/O and are usually database-related. That said, we still believe that improving the performance of the scripting engine itself will definitely benefit the PHP user. For this reason, we decided to invest significant resources to improve performance for PHP 5.1.x.

Since the release of PHP 5, we have invested a lot of resources in tuning the scripting engine. Many ideas were taken from a performance patch that Thies Arntzen and Sterling Hughes published about a year ago. Other ideas came from inside Zend and the PHP developer's community. The end result is an engine that is commonly more than twice as fast as PHP 4.0 and PHP 5.0 for synthetic benchmarks (benchmarks that don't include I/O and real-world code).

The improvement is quite impressive, and when PHP 5.1.0 is released all of the PHP users will enjoy it without having to make any changes to their source code. I believe that PHP 5.1.0 will be released early in the first quarter of 2005, but one can never tell with an open source project.

SQL Relay. SQL Relay (is a very interesting third-party project. It is a project that implements a proxy broker for SQL connections (including Oracle), allowing for connection pooling of database connections using PHP.

The project provides its own version of a PHP database extension (you will be required to change your PHP database code). This extension talks to the SQL Relay broker that relays queries and result sets to and from the database.

Some of SQL Relay's advantages:

Using connection pooling, you can limit the amount of open connections to the database.

In case PHP persistent connections can't be used in your environment, this solution solves the problem of long connect times when initiating an Oracle database connection.

The project supports other programming languages too. If you have a hybrid environment, you can take advantage of the same SQL Relay daemons that are being used from PHP. In addition to PHP, language support includes C, Java, Perl, and quite a few more.

Getting up and running with SQL Relay, although not trivial, is quite simple. I'd also like to note that the SQL Relay author was very responsive to my questions.

Some of SQL Relay's disadvantages:

You have to use a different API than the PHP Oracle extension.

Result sets are copied twice: first to the SQL Relay broker and then to PHP.

You don't have as rich an API as you do when using PHP's native oci8 extension.

I think that if your project does require Oracle database connection pooling, it is a good idea for you to check out SQL Relay. It might not be perfect, but it might still take a while until a better solution comes along, and this one does seem to work.

PDO The PHP community has been working on a new database abstraction layer in addition to the existing oci8 PHP extension that has a native interface to the Oracle Database. As Oracle Technology Network already has an in-depth article covering PHP Data Objects (PDO), by Wez Furlong, suffice to say that PDO is something to watch. PHP has been waiting for quite some time for good native database abstraction. I believe that PDO may very well be the solution we have all been waiting for. The designers of PDO are some of the lead developers of the PHP community, and I like their approach with PDO. The following is a list of their design goals, as written in the PDO README file:

    Be lightweight.

    Provide a common API for common database operations.

    Result in high performance.

    Keep the majority of PHP-specific code in the PDO core (such as persistent resource management); drivers should only have to worry about getting the data and not about PHP internals.

On one hand it gives a common API for working with databases. But it also allows each driver to add its own additional functionality, so that PDO not only supports the least common denominator of the database APIs but will actually give you the opportunity to use all the features your database has to offer. And we all know Oracle has lots of them.

Propel Propel is an object persistence and query framework. It implements object/relational mapping (ORM) and is based on the Apache Torque project, which does the same for Java. Unlike PDO, Propel is a very high-level database abstraction layer, redefining how you query, create, and manipulate persistent objects. Propel, as expected from an OO/RDBMS mapping system, also deals with database schema creation.

There are many advantages to a system like this. For starters, developers can concentrate most of their time on writing business logic and have to deal less with the intricacies of the database—whether it is schema management or writing fancy SQL statements. Database manipulation is very natural, as developers just deal with regular objects and the persistence layer deals with the low-level details of updating the right fields and rows in the database.

The disadvantage is that you do lose some control. The automatic mapping of the OO model to the relational database is not always straightforward. Not only does it make it hard to write fancy, powerful, hand-crafted queries, but you're also not supposed to do so—you break the abstraction, and a tiny update of the mapping might break the application. Therefore, using such a system means you have to play by the rules of the tool. In most cases, this price is acceptable, as increased productivity helps shorten development times and improves code quality. However, there are certain instances where you might absolutely require this control.

Propel is a very interesting project and can come in handy. In addition, it is built on top of a database abstraction layer called Creole. Unlike PDO, this abstraction layer tries to mimic JDBC as much as possible and might be easier to use if you are converting existing Java code to PHP. That said, if PDO becomes mainstream and is distributed as part of standard PHP, it might be best to stick with that.

Java Integration Over a year ago, Zend and Sun Microsystems started Java Specification Request (JSR) 223 to define a standard on how to bridge between PHP and Java. Today the JSR's expert group comprises many software vendors, including Oracle. Although the JSR talks about all scripting languages, the initial interest was in PHP and mainly the possibility of calling Java code from PHP. You can guess that one of the primary motives for such connectivity would be to connect front-end PHP servers to back-end J2EE application servers and, more specifically, the ability to call Enterprise Java Beans (EJBs) directly from PHP code.

The following is an example of what making an Oracle JDBC query would look like using the Java interface:

figure 1

Figure 1: Bridging PHP and Java: What an Oracle JDBC query would look like

You can see that what you'll be able to do is write Java code in PHP. This should allow you to call any Java business logic you might have, specifically EJBs.

Such bridging support opens up new possibilities for Oracle Application Server users, who have invested in back-end business logic but want to take advantage of the fast development times and features of PHP.

Conclusion

PHP 5 has definitely been a great step forward for PHP and the PHP community. At the O'Reilly Open Source conference, a reporter asked some of us PHP community leaders if PHP 5 was everything we had hoped for. The answer was unanimous; PHP 5 has become much more than we initially had planned and expected.

More specifically, I think Oracle users have a lot to look forward to. With Oracle's published Statement of Direction regarding PHP inclusion in future Oracle Application Server releases, it is clear that the company has recognized the importance of PHP technology. I believe that following this recognition will come a variety of solutions that will improve Oracle/PHP productivity and flexibility, both very much required in today's ever-changing market. The initial bundling of PHP in the upcoming version of Oracle 10g and the PHP extension for Oracle JDeveloper are significant first steps for widespread PHP support by Oracle.


Andi Gutmans is Co-founder and Vice President of Technology at Zend Technologies. He has been working on PHP since 1997, when along with Zeev Suraski he created PHP 3, and later on PHP 4. Recently, Andi lead the Zend Engine II's object oriented improvements for the upcoming PHP 5 release and has also co-authored PHP 5 Power Programming (Prentice Hall). He welcomes suggestions about PHP 5 at andi@zend.com.

0 0