Introducing Quercus, a Java-based PHP framework

Quercus is a new approach to authoring Web services and applications using a mixture of Java™ technology and PHP. With the Quercus framework, Java and PHP are integrated with each other, thus allowing you to conveniently incorporate versatile Java libraries like Spring and Hibernate into applications. This article provides a brief introduction of the framework along with some code samples. Explore the features and advantages of the framework using a simple HelloWorld sample. And finally, understand the framework architecture and look at a real world example in more detail.

Sachin K Mahajan (sachin.mahajan@in.ibm.com), Software Developer, IBM  

Sachin graduated with a Masters degree from the University of Utah, Salt Lake City, U.S. He has worked in both small and large companies in the United States and India performing various technical and managerial roles. Sachin currently works in IBM Software Group's Lotus division.



22 September 2009

Also available in Chinese Japanese Portuguese

Introduction

Quercus is an open source PHP 5 engine which has been fully implemented in pure Java. The Quercus documentation mentions that it runs on top of the Resin application server and takes advantage of Resin features like load balancing, proxy caching, and so on. This article describes the features Quercus provides by running it on top of Apache Tomcat. In addition, it also demonstrates the ease and flexibility of Quercus' PHP plus Java mixed approach to Web services and applications.

Why Quercus?

The Quercus PHP libraries are fully implemented in Java, imparting benefits of being both Java and PHP applications. Because of the tight integration of Java and PHP, Quercus applications can use Java technologies and frameworks like Spring, Hibernate, SOA frameworks, and so on. To facilitate this interoperability, Quercus provides an API to invoke the Java libraries from PHP.

Other benefits include:

  • Ease of development: The PHP libraries are implemented in Java making them fast, reliable, and easy to use. Developers do not have to worry about segmentation faults and C pointer overruns seen in C-based PHP implementations.
  • Scalability: Being a Java-based implementation, Quercus runs on top of application servers like Resin and Apache Tomcat. Thus they can use all the features that the Application Server provides (connection pooling, distributed sessions, and so on).
  • Internationalization: Since it is a Java implementation of PHP, it inherently supports 16-bit Unicode strings and functions.

Installing Quercus

Installing Quercus is as simple as installing a jar file into a Java application, but since it is a feature of the Resin application server, it is built into Resin. Also there is no need to download the PHP engine, since Quercus takes over as the PHP engine. To install Quercus follow these steps:

  • Download the Resin application server from the company Web site (see Resources).
  • Open the zip file and extract the jar files, quercus.jar, resin-util.jar, and javamail-141.jar.
  • Copy these files along with the MySQL connector jar file (if needed) in the WebContent\WEB-INF\lib folder of your Web application.
  • Another easy way to do this is to use the sample application zipped at the end of this article as the base and copy the libraries from there (see Downloads).

Enter Quercus

To describe the features of Quercus I'll show you a simple HelloWorld example. This application can be created using the following steps. (I have created all the applications in this article using the Eclipse IDE and have pasted screen shots to give a general flavor of the steps involved. Any IDE of your choice will work.)

The basic idea of the steps below is to create a dynamic Web application project, pointing it to the application server runtime (Apache Tomcat in this case) and configuring the parameters like php.ini and web.xml.

  • Within the IDE (Eclipse in this case) create a new Web project as shown in Figure 1 (Alt + Shift + N).
Figure 1. Creating the new project
Screenshot of the Eclipse interface, starting a new Dynamic Web Project
  • Type in the project name and the target runtime. A sample set-up screen is shown in Figure 2.
    • Click File --> New (Alt + N) and create a new dynamic Web application called TestHelloWorld in the default workspace.
    • I have configured the use of Apache Tomcat Version 5.5 to be the runtime environment for the application.
Figure 2. Setting up the new project
Screenshot of the New Dynamic Web Project dialog for TestHelloWorld
  • Replicate a structure as shown in Figure 3 which includes the Quercus and allied jars. In addition, create folders called WebContent, META-INF (containing the manifest or context files), JavaScript resources, and so on.
Figure 3. Setting up the directory structure
Screenshot of the project folder showing the javamail-141.jar, quercus.jar, and resin-util.jar under the WEB-INF/lib folders.

The root directory of the project TestHelloWorld includes folders such as:

  • WebContent: This directory includes the WEB-INF directory which contains the libraries like quercus.jar under the lib folder and the META-INF directory for the Manifest.mf file. The WEB-INF folder also has the static and dynamic content for the Web application like php, jsp, or html files.
  • Java Resources: This directory includes libraries like Apache Tomcat, the JRE, and Web application libraries.
  • JavaScript resources: This includes whatever resources you would like to include in the project.

The server can be created and configured through the IDE and can be executed in a normal or debug mode (see Figure 4).

The J2EE perspective in Eclipse has a server tab which when right-clicked shows the user an option of creating a new server (see Figure 4). This server can be used to manage the application server from the Eclipse IDE.

Figure 4. Configuring a new server configuration
Screenshot of the eclipse server configuration. User has right-clicked on the Tompacat server and selected New, Server

Defining the new server involves just selecting the defaults unless otherwise required (see Figure 5). The server runtime is the same one which was selected while creating the project, which in this case was Apache Tomcat Version 5.5.

Figure 5. Options selected for the new server configuration
Screenshot of the New Server configuration dialog, showing the defaults for Tomcat v5.5 Server
  • After configuring the server, the resource can be added from the left "available" column to the right "configured" column.

After the new server is configured, the newly created resources need to be configured on the server (see Figure 6). This server configuration deploys the resources which are created during the course of development.

Figure 6. Configuration of resources on the server
Screenshot of resource configuration for the New Server

Configuring Quercus

The php.ini file is used to configure the PHP behavior, like setting directories, file paths, changing sessions, and so on. This file can be specified in the web.xml file. An example of this is shown in Listing 1.

Listing 1. Specifying php.ini in the web.xml file
	<init-param>
	      <param-name>ini-file</param-name>
      	<param-value>WEB-INF/php.ini</param-value>
	    </init-param>

The encoding of the PHP source file is indicated by script encoding, and this is defined as shown in Listing 2.

Listing 2. Specification of PHP encoding in web.xml file
	<init-param>
	      <param-name>script-encoding</param-name>
      	<param-value>UTF-8</param-value>
	    </init-param>

The QuercusServlet is an interface to the Quercus engine, which parses the php files and is usually configured as shown in Listing 3.

Listing 3. Configuration of QuercusServlet in web.xml file
	<web-app xmlns=”http://java.sun.com/xml/ns/j2ee” 
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” 
	xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd” 
	version=”2.4”> 
	<description>Quercus Hello World on Tomcat</description>
	<servlet>
    		<servlet-name>Quercus Servlet</servlet-name>
		<servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>

Describing the Quercus hello world php file (index.php)

The index.php file defines a method called getTheDate which instantiates a Java object. The ability of Quercus to make use of any Java class through the use of import statements makes it highly interoperable and flexible. Listing 4 shows an example.

Listing 4. Example of the PHP import function
	<?php
		function getTheDate() {
		import java.util.Date;
		$currentDate = new Date();
		return $currentDate;
		}
	?>

The code in Listing 5 demonstrates the call to the getTheDate() and phpinfo() method within the HTML fragment.

Listing 5. calls to getTheDate() and phpinfo()
	<body>
	<h1>This is the Hello World page</h1>
	<h3>but, it does something more then Hello World!</h3>
	<h4> The current date and time is :<?php echo getTheDate() ?></h4>
	<h4> and finally here is the phpInfo: <?php echo phpinfo()?>
	</body>

After the code changes are made I need to start the server so that I can test out the HelloWorld application. This can be done by right clicking the server configuration we created earlier and clicking either the run or debug option.

Figure 7. Starting the server in debug or run mode
Screenshot shows starting the server as described in the text

Figure 8 shows the final output of the application after starting the server and going to the url.

Please note that the sample file, HelloWorld.zip, at the end of the article contains the zipped version of the application (see Downloads). It also includes the metadata files required by Eclipse so that it can be imported directly and seamlessly into that IDE.

Figure 8. Output of the Hello World page
Screenshot of the application output showing the text as well as the current date and time and iformation about the running PHP.

Quercus in action

Now let's look at a real-life example. Figure 9 shows an example of a Manage Customer page through which the user can perform operations like adding a new customer, searching for a customer, and viewing all customers in the database.

Figure 9. Flow of the manage customer application
Architecture diagram for the Manage Customer application. Apache Tomcat sends and receives HTTP with the client on the left side. On the right, Tomcat interacts with 'PHP with HTML,' which calls Quercus for rendering of PHP code. On the back-end, the Quercus/PHP/HTML combination interact with a MySQL server.

As shown in the above diagram, HTTP requests are received by Tomcat. The configuration in web.xml defines the QuercusServlet object to parse php files. This object is a Java servlet which interfaces with the Quercus library. In this sample application a PDO object instantiated within the php file instantiates the connection with the MySQL database through the MySQL connector. PDOs, or PHP Data Objects, provide database access in a uniform manner, including advanced features like prepared statements.

The directory structure of the Manage Customer application, shown in Figure 10, follows the same pattern directory structure as described above in the HelloWorld example.

Figure 10. Directory structure of the Manage Customer application
Screenshot of the Manage Customer project's directory structure

Note that the core of the files for this application are contained within the WebContent folder under the following subdirectories:

  • META-INF: This contains the database credential information for connecting to the MySQL database.
  • WEB-INF: This includes the library folder containing the files like Quercus jar for running the application. It also includes the web.xml which describes the datasource.
  • All the associated php and html files are contained within the WebContent folder. These files serve as the view part of the application providing the dynamic and static content to the Web app.

Please note that the sample file, ManageCustomer.zip, at the end of the article contains the zipped version of the application (see Downloads). It also includes the metadata files required by Eclipse so that it can be imported directly and seamlessly into that IDE.

Configuration of Tomcat and MySQL

The configuration of Tomcat is very similar to the HelloWorld application. In addition, we need to define a resource reference, as shown in Listing 6. This element specifies the name of a resource manager connection factory reference. In this case it would be the database connection specified by jdbc/mysql, which is of javax.sql.DataSource type.

Listing 6. Resource reference definition web.xml
	web.xml
	. . .
	<resource-ref>
	      <description>DB Connection</description>
	      <res-ref-name>jdbc/mysql</res-ref-name>
	      <res-type>javax.sql.DataSource</res-type>
	      <res-auth>Container</res-auth>
	</resource-ref>
	. . .

We need to define the connection resource in the context.xml under the WebContent/META-INF folder, as shown in Listing 7. This contains properties like the driver name, jndi name, username, password, datatype, and the url.

Listing 7. Properties defined in context.xml
	context.xml
	. . .
	<Context>
	<Resource driverClassName="com.mysql.jdbc.Driver" 
	maxActive="4" maxIdle="2" maxWait="5000" auth="Container" 
	name="jdbc/mysql" password="" type="javax.sql.DataSource" 
	url="jdbc:mysql://localhost:3306/customer" username="root"/>
	</Context>
	. . .

The customer database has a single table which can be created by running the following script:

	use customer;
	CREATE TABLE users (
		id INT NOT NULL PRIMARY_KEY AUTO_INCREMENT, 
		name VARCHAR(200)
	);

Please note that configuration steps described during the HelloWorld application, like creating a new server configuration, adding resources, starting the server in debug or run mode, and so on can be applied in this application, too, in a similar fashion.


Summary of the application

The index page of the application shows the list of operations which can be performed by the user (see Figure 11).

Figure 11. Screen shot of the Manage Customer index page
Screenshot shows the Manage Customer page with a text field and button to add a customer name, a text field and button to search for a customer and a button to view all customers.

The operations which are supported are:

  • Add Customer
  • Search Customer
  • View all Customers
  • Delete all Customers

The index.html page which displays all the operations is made up of individual forms having their own actions. Take a look at "Add Customer" in more detail. The corresponding html contains a reference to addCustomer.php as the form action along with the POST method.

	<H2>Add Customer</H2>
	<form action="addCustomer.php" method="post">
	<label>Customer name</label>
	<input type="text" id="customerName" name="customerName"/>
	<input type="submit" value="Add"/>
	</form>

The php code in the action extracts the customerName parameter from the POST and creates an sql statement for the insert. A PHP data object is then instantiated by passing in the jndi name of the datasource.

	<?php
	$custName = $_POST['customerName'];
	$pdo = new PDO("java:comp/env/jdbc/mysql");
	$sql = "insert into users values ('" . $custName . "');";
  	$rows = $pdo->exec($sql);
  	if ($rows>0) {

	echo("<h4> Adding ". $custName . " was successful</h4>");
	}
	else echo('<h4> An error occurred</h4>');
	?>

In a similar fashion, the operations to Look Up, View All, and Delete have been implemented (see the source code attached in the Downloads section).

Figure 12. Screen shot of the View all Customers page
Screen shot of the application displaying a list of all customer names.

Conclusion

This article describes the features of Quercus running on top of Apache Tomcat and connecting to a MySQL database. As a PHP framework fully implemented in Java, it can make full use of Java-based frameworks like Spring, Hibernate, and so on. Quercus also has a high degree of usability for a developer because of its PHP facet, while being robust and scalable since the core framework has been implemented in Java.


Downloads

DescriptionNameSize
Sample codeTestHelloWorld.zip1.7MB
Sample codeManageCustomer.zip1.9MB

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Web development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Web development, Open source
ArticleID=430321
ArticleTitle=Introducing Quercus, a Java-based PHP framework
publish-date=09222009