Getting Started with Quercus
Resin 3.1

Documentation
Examples
Changes

Overview
Installation
Configuration
Quercus
SOA/IoC
JSP
Servlets and Filters
Admin (JMX)
EJB
Amber
Security
Performance
Hessian
XML and XSLT
Third-party
Troubleshooting/FAQ

Getting Started
Overview
Security
Module Status
Resin Module
Java Interface
List of PHP Applications
Quercus
Quercus
Overview

Introduction to Quercus

Running an Existing PHP Application on Quercus

In general, getting an application to run on Quercus instead of the standard PHP interpreter requires only a little extra work. To demonstrate this simple process, let's install WordPress. Suppose WordPress has been extracted to $resin_home/webapps/ROOT/wordpress, where $resin_home is the home directory of Resin Application Server.

Step 1. Create the $resin_home/webapps/ROOT/wordpress/WEB-INF directory and add the web.xml file below into that directory. The web.xml file let QuercusServlet, the Java Servlet that interfaces to Quercus, parse .php files. Since WordPress uses special ISO-8859-1 characters in their PHP scripts, we need to change the script encoding from the default UTF-8 to ISO-8859-1. If you need to set ini values, see php.ini.

$resin_home/webapps/ROOT/wordpress/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
       servlet-class="com.caucho.quercus.servlet.QuercusServlet">
    <init>
      <script-encoding>iso-8859-1</script-encoding>
    </init>
  </servlet-mapping>
</web-app>

Step 2. If you have not already done so, download the MySQL Connector/J JDBC driver into $resin_home/lib. to enable mysql database functions.

Step 3. The configuration for Resin/Quercus is now complete. Now you'll need to go through the application's installation routine. For Wordpress, go to http://localhost:8080/wordpress/wp-admin/setup-config.php to start the installation.

That's it for Wordpress on Quercus. If you are encountering issues with a certain application, please see Resources for assistance.

For a list of applications running successfully on Quercus, see List of PHP Applications Running on Quercus.

Configuring Quercus

Php.ini

At the moment, Quercus does not have the option to read in an entire php.ini file upon startup. However, individial PHP initialization values can be set in web.xml. For example, to set the settings for sending mail:

$webApp_home/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
       servlet-class="com.caucho.quercus.servlet.QuercusServlet">
    <init>
      <php-ini>
        <sendmail_from>my_email_address</sendmail_from>
        <smtp_username>my_email_username</smtp_username>
        <smtp_password>my_email_password</smtp_password>
      </php-ini>
    </init>
  </servlet-mapping>
</web-app>

Character Encoding Issues

Because Quercus is 100% Java, Quercus has native support for Unicode and will, by default, parse PHP scripts in UTF-8. This also means Quercus supports the new PHP 6 Unicode keywords like this Unicode typecast: (unicode)"foo". If a PHP application uses special ISO-8859-X characters (i.e. the copyright symbol, accented characters), Quercus will complain because the byte code of those characters are illegal in UTF-8.

To solution is to tell Quercus to parse PHP scripts using the correct character set (ISO-8859-1 for most applications). For example, to tell Quercus to use ISO-8859-1, add <script-encoding> to the init tag of QuercusServlet:

$webApp_home/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
       servlet-class="com.caucho.quercus.servlet.QuercusServlet">
    <init>
      <script-encoding>iso-8859-1</script-encoding>
    </init>
  </servlet-mapping>
</web-app>

Garbage Output On Browser

There are three encodings you need to worry about: script encoding, output encoding, and runtime encoding. By default, Quercus uses UTF-8 for all three. Script encoding is for when your scripts are in an encoding other than UTF-8.

Output encoding is the charset used to display output to the browser. You can set it in your resin-web.xml:

$webApp_home/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
      servlet-class="com.caucho.quercus.servlet.QuercusServlet">
    <init>
      <php-ini>
        <unicode.output_encoding>MY_ENCODING</unicode.output_encoding>
      </php-ini>
    </init>
  </servlet-mapping>
</web-app>

There is another encoding that you need to know about. It is the unicode.runtime_encoding and it defaults to UTF-8. It is a PHP 6 directive that tells Quercus what encoding to assume a binary string is in when doing implicit conversions to Unicode. You would set runtime encoding in the same way as you would for output encoding.

In PHP 6, there are two types of strings, Unicode and binary. A binary string is a string where the data is binary, the encoding is unknown, or the encoding is not Unicode (UTF-16). If you ever use a function that will likely return a binary string, then you probably need to set unicode.runtime_encoding. Quercus may convert your binary string to Unicode and then to your output encoding for output to the browser. If your runtime encoding is wrong, then you would see garbage in your browser.

Compiling PHP Scripts for Increased Performance

Quercus can automatically compile PHP scripts into Java classes for better performance. This is available only in Resin Professional.

To turn on compilation, the <init> tag of QuercusServlet needs to have the <compile> tag:

$webApp_home/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
       servlet-class="com.caucho.quercus.servlet.QuercusServlet">
    <init>
      <compile>true</compile>
    </init>
  </servlet-mapping>
</web-app>

Using Databases

JDBC drivers are required to use databases in Quercus. There are JDBC drivers for MySQL, Oracle, SQLite, and many other database engines. The desired JDBC driver should be downloaded into Resin's lib directory. Resin will automatically load jars in the lib directory upon startup.

For example, PHP mysql functions will only function properly when the MySQL Connector/J JDBC Driver is downloaded and placed in the $resin_home/lib directory.

If a database with JNDI name jdbc/myDatabase is defined in resin.conf, (see Database Configuration), Quercus can do a JNDI lookup for the database when database functions are called. Thus, database connection parameters like user name can be omitted within PHP scripts. This allows easier maintenance and enables Java and PHP database settings to be centrally located in resin.conf.

<?php

  // standard PHP
  //mysql_connect($host, $username, $password, $dbname);

  // using JNDI lookup
  mysql_connect("jdbc/myDatabaseName");

?>

JNDI

jndi_lookup() is a Quercus-only function that can be called to retrieve JNDI objects. It is useful in a SOA (Service Oriented Architecture) system to locate a Java service.

Adding PHP Functions by Creating a Quercus Module

The core PHP functions are implemented inside Quercus modules. Quercus modules are the Java equivalent of PHP modules.

All Quercus Modules need to implement AbstractQuercusModule. Functions defined in your modules are callable from within PHP script by using just the function name. Function names need to be distinct in order to prevent name collisions, though Quercus does support function overloading (for Java functions only).

A typical Quercus Module looks like:

$webApp_home/WEB-INF/classes/example/HelloModule.java
package example;

import com.caucho.quercus.env.Env;
import com.caucho.quercus.module.AbstractQuercusModule;

public class HelloModule extends AbstractQuercusModule
{
  /**
   * @param env provides Quercus environment resources.
   * @param str
   */
  public void HeLLo_TeST(Env env, String str)
  {
    // 'echos' the string
    env.println("hello " + str);
  }
}
example.php
<?php

  // PHP 5 is case-insensitive
  // just prints "hello me" to the browser.
  hello_test("me");

?>

For a tutorial on how to implement your own Quercus module, see the Quercus Module tutorial.

Using Plain Old Java Objects (POJO) in PHP Scripts

You do not need to create a Quercus Module in order to use your Java code in a PHP script. Quercus provides the java() function to call constructors of Java objects and java_class() to obtain the Java class without calling the constructor. At the moment, you will need to edit your web.xml so that Quercus will find your custom Java classes.

$webApp_home/WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
  <servlet-mapping url-pattern="*.php"
       servlet-class="com.caucho.quercus.servlet.QuercusServlet">
       <init>
         <class name="myPackage.MyClass"/>
       </init>
  </servlet-mapping>
</web-app>
$webApp_home/example.php
<?php

  // Quercus specific construct
  import java.util.Date;

  $date = java("Date", 123456789);
  $list = java("java.util.ArrayList");

  $class = java_class("java.lang.System");

  $in = $class->in;
  $time = $class->currentTimeInMillis();

?>

Quercus does automatic conversion from Java objects to PHP objects. Function overloading is supported (for Java functions only). For more information and a list of Java Annotations that you can use in your code, see Java Interface.

Java Function Arguments/Return Marshaling

Quercus does marshaling to and fro Quercus Values and Java objects. If a Java function requires a String, Quercus will automatically convert the internal Quercus StringValue to a String. If a Java function returns an int, Quercus will create a Quercus LongValue for it.

For other Java Objects like java.util.Data that are returned to PHP, Quercus puts them into wrappers to expose their public methods and members to the PHP script. Java Collection, List, and Map instances have the additional ability to be used within a PHP script like any other PHP array.

For more information, see Java Interface.

Quercus-specific Functions

Quercus has several Quercus-only PHP functions for debugging and Java interfacing (JNDI, JMS, and JMX). For more information, see Resin PHP Functions.

The list of debugging functions are below:

Debugging Functions

  1. resin_var_dump($a) - dumps the argument to standard out
  2. resin_call_stack() - returns an array containing the PHP function call stack.
  3. resin_debug($a) - logs the argument into Resin's log at the INFO level
  4. resin_thread_dump() - dumps the Java stack to standard out

Differences from PHP 6

Quercus implements PHP 5 but supports most of PHP 6 language features that are available in the PHP 6 preview distribution. Differences from PHP 6 are:

  1. Unicode support cannot be turned off.
  2. For performance considerations, Unicode string indexing is done by Unicode code units. A Unicode code unit is equivalent to a Java char primitive. In PHP 6, it is done by code points. A code point consists of 1 or 2 code units. Quercus uses code units because determining code point boundaries takes a lot of resources.

Resources


Quercus
Quercus
Overview
Copyright © 1998-2006 Caucho Technology, Inc. All rights reserved.
Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology.