Feb 12

tomcat-php01.pngAs you can gather from the title of this website, I create software in Java, Scala, and PHP. While Java and Scala compile to bytecode that runs on the same virtual machine, PHP is executed by a separate interpreter. The most efficient way to run PHP scripts is to integrate the interpreter directly into the webserver. Hence, most PHP developers use a local Apache Httpd server with mod_php for development. If you also do Java programming, this raises the problem that you need two different web servers, namely Tomcat (or another web container or appserver) for Java development and Apache for PHP development.

Running two servers is a bit of a nuisance. Two servers consume more resources than one and you cannot run both on the same port. This problem can be solved in three different ways: you can only run one server at a time, you can use a different port number for one server which has to be included in the URLs, or you can integrate the two servers. There are again at least three different ways to accomplish the latter: you can proxy requests from Apache to Tomcat, you can proxy request from Tomcat to Apache, or you can use a connector module, such as mod_jk. Of course, maintaining two servers is is more complicated than maintaining one, and the integration adds additional complexity. Fortunately, there is an easier way to integrate PHP and Java web applications.

PHP/Java Bridge is a free open source product for the integration of the native PHP interpreter with the Java VM. It is designed with web applications in mind: Java servlets can “talk” to PHP scripts and vice versa. The official website describes it as an “implementation of a streaming, XML-based network protocol which is up to 50 times faster than local RPC via SOAP.” PHP/Java Bride requires no additional components to invoke Java procedures from PHP or vice versa. Although there are a number of different use cases, I am going to describe a particular one in this article, namely how to configure Tomcat with PHP/Java Bridge in order to have Tomcat serve PHP web pages. Let’s start with software requirements. We need the following software packages:

Follow the standard installation procedures for the JVM, Tomcat, and PHP. On Linux, you can use the standard packages for your distribution and on Windows you can use the regular installers. Make sure that both Tomcat and PHP are installed properly, which means that you should see Tomcat’s welcome web page at http://localhost:8080 and you should be able to execute a PHP script via the command line by invoking the standalone “php” command. The PHP/Java Bridge product does not use the regular executable, however, but fast CGI. The fast CGI executable is called php-cgi (or Php.cgi.exe on Windows), so you must make sure that your PHP installation contains it. Then you are all set to install and configure the PHP/Java Bridge.

The PHP/Java Bridge package comes with a sample web application named JavaBridge.war. Deploy the application in Tomcat, point your browser to http://localhost:8080/JavaBridge and try out the examples. If this works, you are half-finished. To provide the capability to execute PHP scripts server-wide, not just in a single web application, you need to make some changes to the Tomcat configuration. Find the three jar files named JavaBridge.jar, php-servlet.jar and php-script.jar (look in WEB-INF/lib) and move them to Tomcat’s shared library directory. This is usually found in $CATALINA_HOME/lib (or $CATALINA_HOME/shared in older Tomcat installations). Then edit Tomcat’s conf/web.xml configuration file and add the following lines:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<listener>
  <listener-class>
    php.java.servlet.ContextLoaderListener
  </listener-class>
</listener>
 
<servlet>
  <servlet-name>PhpJavaServlet</servlet-name>
  <servlet-class>
    php.java.servlet.PhpJavaServlet
  </servlet-class>
</servlet>
 
<servlet>
  <servlet-name>PhpCGIServlet</servlet-name>
  <servlet-class>
    php.java.servlet.PhpCGIServlet
  </servlet-class>
  <init-param>
<param-name>prefer_system_php_exec</param-name>
<param-value>On</param-value>
  </init-param>
  <init-param>
<param-name>php_include_java</param-name>
<param-value>On</param-value>
  </init-param>
</servlet>
 
<servlet-mapping>
  <servlet-name>PhpJavaServlet</servlet-name>
  <url-pattern>*.phpjavabridge</url-pattern>
</servlet-mapping>
 
<servlet-mapping>
  <servlet-name>PhpCGIServlet</servlet-name>
  <url-pattern>*.php</url-pattern>
</servlet-mapping>

This adds the listeners and servlets required for PHP script execution to all web applications. While you are at it, you might also want to enable index.php files to display when a directory URL is requested. Simply add it to the list of welcome files in conf/web.xml. My list looks like this:

1
2
3
4
5
6
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.php</welcome-file>
</welcome-file-list>

Now you can copy PHP scripts into the context root directory of any web application and type the script URL into your browser. I suggest you try a script with phpinfo(). It gives you plenty of useful configuration info. If this doesn’t work and you are on Unix, the problem might be file permissions. On my machine, I had to copy the contents of “java” directory in the JavaBridge webapp manually to the context root directory where PHP applications were installed. This directory contains two files Java.inc and JavaProxy.php. Normally, the PHP/Java Bridge software copies it automatically, but it might not be able to do so if it does not have proper permissions:

~$ ls -lh /var/lib/tomcat6/webapps/ROOT/java
total 136K
-rw-rw-r-- 1 root root 64K 2009-12-30 14:14 Java.inc
-rw-rw-r-- 1 root root 64K 2009-12-30 14:14 JavaProxy.php

Now try calling a PHP script. For example, a script containing the phpinfo() command displays information about the server:

tomcat-config.png

I have configured my machine to host all PHP web applications in Tomcat’s ROOT context. This eliminates the extra path component of the webapp context, since the ROOT’s context path is “/”. Then I softlinked the folder that contains all my PHP projects into the ROOT webapp directory, so that the actual source files are kept separate from the Tomcat installation. In order to enable Tomcat to follow symlinks, you need to edit the context.xml of the respective web application -in this case ROOT- and add the line: <Context path=”/” allowLinking=”true” /> .

Another possible gotcha is Tomcat’s security manager, which is enabled by default on Ubuntu, but not on Windows. Although a security manager is not necessary for most development scenarios, it is highly recommended for production. I consider it good practice to enable the security manager on the development machine, because it allows me to recognise security problems early during development, before the application is deployed on the production server. The downside is that additional configuration may be required, for PHP applications to function properly. The respective configuration files are located in $CATALINA_BASE/conf/policy.d. Most likely, you need to grant PHP web applications write access to files in the document root and possibly other permissions, such as opening sockets, etc. It’s probably safest to do this on a per-application basis.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Facebook
  • Mixx
  • Google
  • YahooMyWeb
  • Slashdot
  • LinkedIn
  • blogmarks
  • Live
  • description
  • StumbleUpon
  • Ma.gnolia
  • MisterWong
  • NewsVine
  • Reddit
  • Spurl
  • Yigg
  • E-mail this story to a friend!
Oct 5

Perhaps suggesting to eschew web frameworks for web application development is playing the devil’s advocate. Perhaps it is even foolish. To renounce the productivity boost one gets with a properly designed framework does not sound like sensible advice. Only ignorant script kiddies entertain such ideas. Well, for the most part that is true. A web framework does indeed simplify application development if it is chosen well. It does even more if it is designed well. It can provide architectural support for building maintainable applications. It can help with the plumbing and provide conceptual structure to guide the development process.

So, what speaks against using a web framework? Plenty actually, especially at the lower end of the spectrum and especially with dynamic languages. The main problem with web frameworks is that they add overhead. This means that the added functionality and structure is bought at the cost of performance degradation. The graveness of this problem depends on the system architecture. One  needs to keep in mind, that dynamic languages are interpreted at runtime, which makes them CPU-intensive and relatively slow. Because the life cycle of a script is essentially stateless and single-step, classes and data structures need to be rebuild and reloaded (in theory) at each request. In practice, this does not happen, because servers are designed to provide at least rudimentary caching. However, the runtime performance of interpreted languages is typically several magnitudes smaller than that of a compiled language, which magnifies the problem.

To illustrate my point, consider these benchmarks for PHP frameworks kindly provided by Paul M. Jones. According to these figures, a trivial PHP page is served by Apache 2 at a performance reduction of 43% compared to static HTML. The use of various PHP web frameworks further reduces performance by 85% - 95% compared to a PHP page that merely echoes content. Although it can be expected that these figures develop inverse logarithmically with increasing application code complexity, the slowdown is significant. PHP offers a number of remedies, such as  opcode caching, object caching, and products such as Zend Server, APC, and MCache, yet performance is unlikely to get even close to that of a compiled language.

Furthermore, there is the question whether the complexity of the project justifies the complexity introduced by a web framework. Would you use a web framework for building a guestbook script? Probably  not. What about a blog software? A photo gallery? A bulletin board? These types of applications are the mainstay of dynamic languages, such as PHP. It is the area where PHP really shines. Think of Wordpress, phpBB, Mediawiki, Drupal, osCommerce, Coppermine and other popular applications. They all have one thing in common: they don’t use a framework. Hence, before choosing a web framework for PHP development, it may be worth pondering if any is required. This suggestion may sound a bit contradictory, having just reviewed the Zend framework in a previous article. However, in my own practice I haven’t come across many complex PHP projects.

The commercial PHP projects I worked on during the last 10 years can roughly be divided into three categories: 1. extensions and customisations of open source packages, 2. intranet information systems, and 3. e-commerce systems and “catalogware”. Although the latter two may be considered candidates for web frameworks, the size of these projects was almost always small enough to do without. On several occasions, I chose to implement an “ultralight” MVC architecture by hand instead of using an out-of-the-box framework. The main reason for this was again performance. The “ultralight” approach is defined by implementing only the required functionality, which results in highly specialised design. In practice, this means slimming the controller, reducing DB abstraction to a thin wrapper around the native library, and foregoing a templating system in favour of embedded PHP.

The advantage of this approach is that you get separation of presentation and business logic, componentisation, and customisable control flow without the performance cost of full-blown framework. The disadvantage is that it is slightly more laborious to implement and less flexible. Don’t get me wrong. I have no problems imagining scenarios where I would want to use a PHP web framework such as the Zend framework. However, in these cases I’d probably be drawn towards using Java or (hopefully) Scala in the first place. In summary, I have found myself using PHP mostly in situations where a web framework seemed dispensable, while I have been using Java mostly in situations where a web framework seemed essential.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Facebook
  • Mixx
  • Google
  • YahooMyWeb
  • Slashdot
  • LinkedIn
  • blogmarks
  • Live
  • description
  • StumbleUpon
  • Ma.gnolia
  • MisterWong
  • NewsVine
  • Reddit
  • Spurl
  • Yigg
  • E-mail this story to a friend!
Sep 10

zend-framework.gifEarlier this week, I gave the latest version of the Zend Framework v-1.9.2 another test drive. I had previously dabbled in v-1.7.4 as well as a pre-1.0 incarnation of the framework. I will not repeat listing the whole breadth of its functionality here, since you can find this elsewhere on the Internet. Neither will I present a point-by-point analysis, just the salient points, short and sweet, which you can expect to be coloured by my personal view. Suffice to say that the ZF (Zend Famework) is based on MVC -you’d never guessed- and it provides functionality for database access, authentication and access control, form processing, validation, I/O filtering, web services access, and a bunch of other things you would expect from a web framework.

The first thing to notice is that the framework has grown up and I mean this quite literally from a few megabytes in its early days to a whopping 109 MB (unzipped) distribution package. Only about 21 MB are used by the framework itself; the rest contains demos, tests, and… the dojo toolkit… an old acquaintance, which is optional. The documentation for the ZF was excellent right from the beginning and it has staid that way. Included is a 1170-pages PDF file, which also bears testimony to the growing size and complexity of the framework. Gone are the days when one could hack together a web application without reading a manual.

One of the first things to realise is that ZF is glue-framework rather than a full-stack framework. This means, it feels more like a library or a toolkit. ZF does not prescribe architecture and programming idioms like many other web frameworks do. This appears to fit the PHP culture well, though it must be mentioned that most ZF idioms come highly recommended, since they represent best OO practices. Another thing that catches the eye is the lack of an ORM component, which may likewise be rooted in traditional PHP culture. If you want object mapping, you would have to code around ZF’s DB abstraction and use Doctrine, Propel, or something similar. Let’s get started with this item.

Database Persistence
ZF provides a number of classes for DB abstraction. Zend_Db_Table implements a table data gateway using reflection and DB metadata. You only need to define table names and primary keys. Zend_Db_Adapter, Zend_Db_Statement and Zend_Db_Select provide database abstraction and let you create DB-independent queries and SQL statements in an object oriented manner. However, as you are dealing directly with the DB backend, all your data definitions go into the DB rather than into objects. Although this matches with the traditional PHP approach, it means that you need to create schemas by hand, which may irritate people who have been using ORM layers, like Hibernate, for years. On the other hand, a full-blown ORM layer likely incurs a significant performance cost in PHP, so maybe the ZF approach is sane.

Fat Controller
Like many other frameworks, ZF puts a lot of application logic into the controller, and this is my main gripe with the ZF. It seems to be the result of the idea that the “model” should concern itself only with shovelling data from the DB into the application and vice versa. A case in point is the coupling between Zend_Form and validation. This leaves you no option, but to put both into the controller. I think that data validation logically belongs to the model, while form generation logically belongs to the view. If you pull this into the middle, it will not only bulge the controller, but it is likely to lead to repetition of validation logic in the long run. That’s why I love slim controllers. Ideally, a controller should do nothing but filtering, URL rewriting, dispatching, and error processing.

MVC Implementation
Having mentioned coupling, it would do ZF injustice to say that things are tightly coupled. Actually, the opposite is the case, as even the MVC implementation is loosely coupled. At the heart you find the Zend_Controller_Front class which is set up to intercept all requests to dynamic content via URL rewriting. The rewriting mechanism also allows user-friendly and SEO-friendly URLs. The front controller dispatches to custom action controllers implemented via Zend_Controller_Action; if non-standard dispatching is required this can be achieved by implementing a custom router interface with special URL inference rules. The Zend_Controller_Action is aptly named, because that’s where the action is, i.e. where the application accesses the model and does its magic. The controller structure provides hooks and interfaces for the realisation of a plugin architecture.

Views
Views are *.phtml files that contain HTML interspersed with plenty of display code contained in the traditional <? ?> tags. It should be possible to edit *.phtml files with a standard HTML editor. The Zend_View class is a thin object from which View files pull display data. View fragments are stitched together with the traditional PHP require() or with layouts. It is also possible to use a 3rd party templating system. Given the <? ?>, there is little to prevent application logic from creeping into the view, except reminding developers that this is an abominable practice punishable by public ridicule.

Layouts
Layouts are a view abstraction. They enable you to arrange the logical structure of page layouts into neat and clean XML. These layouts are then transformed into suitable output (meaning HTML in most cases). As you can probably infer, this takes a second parsing step inside the PHP application, which is somewhat unfortunate, since PHP itself already parses view components. While layouts are optional, they are definitely nice to have. I think it’s probably the best a framework can do given the language limitations of PHP, which only understands the <?php> tag. If the XML capabilities of PHP itself would be extended to process namespaced tags like <php:something>, then one could easily create custom tags and the need for performance-eating 2-step processing would probably evaporate. Ah, wouldn’t it be nice?

Ajax Support
ZF does not include its own Javascript toolkit or set of widgets, but it comes bundled with Dojo and it offers JSON support. The Zend_Json class provides super-simple PHP object serialisation and deserialisation from/to JSON. It can also translate XML to JSON. The Zend_Dojo class provides an interface to the Dojo toolkit and makes Dojo’s widgets (called dijits) play nicely with Zend_Forms. Of course, you are free to use any other Ajax toolkit instead of Dojo, such as YUI, jQuery, or Prototype.

Flexibility
As mentioned, ZF is very flexible. It’s sort of loosely coupled at the design level, which is both a blessing and a curse. It’s a blessing, because it puts few restrictions on application architecture, and it’s a curse, because it creates gaps for code to fall through. A case in point is dependency injection ala Spring. In short, there isn’t much in the way of dependency management, apart from general OO practices of course. Nothing keeps programmers from having dependencies floating around in global space or in the registry. A slightly more rigid approach that enforces inversion of control when wiring together the Zend components would  probably not have hurt.

Overall Impression
My overall impression of the ZF is very good. It is a comprehensive and well-designed framework for PHP web applications. What I like best about it that it offers a 100% object-oriented API that looks very clean and makes extensive use of best OO practices, such as open/closed principle, programming to interfaces, composition over inheritance, and standard design patterns. The API is easy to read and understand. The internals of its implementation likewise make a good impression. The code looks clean and well structured, which is quite a nice change from PHP legacy code. ZF still involves a non-trivial learning curve because of its size. I’ve only had time to look into the key aspects, and didn’t get around to try out more specialised features like Zend_Captcha, Zend_Gdata, Zend_Pdf, Zend_Soap, and web services, and all the other features that ZF offers to web developers. If I had to choose a framework for a new web application, ZF would definitely be among the top contenders.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Facebook
  • Mixx
  • Google
  • YahooMyWeb
  • Slashdot
  • LinkedIn
  • blogmarks
  • Live
  • description
  • StumbleUpon
  • Ma.gnolia
  • MisterWong
  • NewsVine
  • Reddit
  • Spurl
  • Yigg
  • E-mail this story to a friend!

« Previous Entries