Friday, April 21, 2006

PHP & Application Frameworks

About Application Frameworks
An application framework's foremost goal is to ease development of applications. Usually a framework consists of a set of classes that provide common functionality found in applications, such as authentication, authorization, and database connectivity. As an alternative to creating such functionality from scratch, a framework can significantly reduce the amount of time needed to develop an application.

The more standard functionality a framework can offer, the bigger the advantages. The downside is that the bigger the framework, the more it influences the architecture of the application. The ability to customize the framework is therefore essential. Fortunately, most object-oriented frameworks offer this possibility.

Lately, the term business framework has been gaining momentum. Whereas a "regular" framework targets application development in general, and as such offers functionality found commonly in applications and Web sites, a business framework is targeted at professional business applications. A business framework should help developers write a business application by letting them focus on the business logic. All application "plumbing," such as how to handle the user interface, how to interact with a database, how to handle sessions, and so on, should be dealt with by the framework (but remain customizable, should the need arise).

Business frameworks usually make use of reusable "business objects," or "entities," that define the data model of the application and contain all the business logic. These business objects form the core of an application. Some frameworks use XML to describe these objects; others, such as ATK, use code. The Oracle Application Development Framework (ADF) for Java is an example of a framework that uses a combination of XML and code.

About Achievo ATK
Achievo ATK is a business framework that has taken the goal of speeding up development to heart. All parts of the framework are intended to reduce the amount of code an application requires. Instead of providing a large set of utility classes to maximize functionality, it provides a common framework to minimize coding. All new features are carefully considered and are added only if they reduce development time in some area.

The addition of new Achievo ATK features is partly a matter of evolutionary development. No development team is responsible for new features; rather, the framework is extended based on the requirements of the applications that use it.

Prerequisites
To be able to work with the examples in this article, note the following:

You need a working Oracle database (Oracle9i or Oracle 10g).
The scott/tiger example schema should be installed and usable.
You need a Web server with the PHP scripting language that can connect to the Oracle database (see the documentation on this site for help on installing this).
You need a Web browser.
Some knowledge of PHP would be useful but is not essential for understanding the examples in this article.
In php.ini, make sure the setting for error_reporting is set to E_ALL~E_NOTICE, because ATK contains a few notices that might show up. This setting is the default on most PHP installations. On Windows installations, it tends to be set to E_ALL by default, though.

PHP and ASP.NET Go Head-to-Head

When it comes to Web development these days, you have a lot of options. Many of these methods involve preprocessing—that is, embedding code into HTML pages with special tags that signal to a preprocessor that they contain code, and that it should do something with it. Much like a CGI, this code is then run on the server, and it returns some content, which then assumes part of the shape of the resulting HTML page sent back to the browser. Both the open source scripting language PHP and languages within Microsoft's ASP.NET framework fall into this category; JavaServer Pages (JSP) and Perl/Mason operate this way as well.

In this article I'll focus on PHP, the technology Oracle has chosen to incorporate into its products, and ASP.NET. I'll overview the various strengths and weaknesses of each, discussing in particular those areas that will help you make your decision on which to go with for your development project. There are a lot of factors to consider, and different projects may appeal to a different technology. In conclusion you'll find a point-by-point comparison in terms of price, speed and efficiency, security, cross-platform support, and the advantages of an open source solution.

What is ASP.NET?

The latest incarnation of ASP, ASP.NET, is not completely backward-compatible with previous versions of ASP, as it is a complete rewrite of the software. Previous ASP technology actually has a lot more in common with PHP than with ASP.NET, which is a complete framework for building Web applications. One of the principal features of this model is the flexibility to choose your programming language. ASP.NET works with scripted languages such as VBScript, JScript, Perlscript, and Python, as well as compiled languages such as VB, C#, C, Cobol, Smalltalk, and Lisp. The new framework uses the common language runtime (CLR); your language source is compiled into Microsoft Intermediate Language code, which the CLR then executes.

The framework also provides for true object-oriented programming (OOP), and true inheritance, polymorphism, and encapsulation are supported. The .NET class library is organized into inheritable classes based around particular tasks, such as working with XML or image manipulation.

Besides the programming language and the methodology, database access is a significant concern. When you program in ASP.NET, integration with databases can be accomplished through ODBC, which provides a consistent set of calling functions to access your target database.

Strengths and Weaknesses

ASP.NET's strength lies clearly in its clean design and implementation. It is an object-oriented programmer's dream, with language flexibility, and with sophisticated object-oriented features supported. In that sense, it is truly interoperable with your programmers' existing skills.

Another strength of ASP.NET is the development environment. For instance, developers can use WebMatrix, a community-supported tool, Visual Studio .NET, or various Borland tools such as Delphi and C++ Builder. Visual Studio, for instance, allows setting of breakpoints, tracing sections of code, and reviewing the call stack. All in all, it's a sophisticated debugging environment. Plenty of other third-party IDE solutions for ASP.NET are certain to surface as well.

But what you gain in robustness, you pay for in efficiency. ASP.NET is expensive with respect to memory usage and execution time, which is due in large part to a longer code path. For Web-based applications, these limitations can be a serious problem, because on the Web, your application is likely to scale to thousands and thousands of users per second. Memory usage can also become an issue on your Web server.

What is PHP?

PHP is a scripting language based on the model of preprocessing HTML pages. When the PHP preprocessor in your Web server notices a PHP language tag like the following, the PHP engine is invoked to execute that code:


some code here
?>


PHP will be familiar to any programmers who have worked with imperative programming languages; you'll notice syntactical similarities with Perl, C, and Java. Strictly speaking, Java is an imperative programming language, but it also makes use of object-oriented constructs and concepts. PHP borrows from this structure when it is convenient, but it is not a pure OOP language.

In the discussion of ASP.NET above, I mentioned the ODBC driver, and how applications can be built with database abstraction in mind. In PHP, you can also use ODBC to talk to databases, so you already have a whole list of supported databases to choose from. There are also native drivers for MySQL, Oracle, and Postgres. Furthermore, if you are connecting to Oracle, a special OCI8 library provides more feature-rich access to Oracle, allowing you to use such features as LOB, BLOB, CLOB, and BFILE.

You might ask, at this point, "Why are database-dependent libraries being touted as features of PHP?" Database abstraction, or independence, is a feature if you seek to build an application that works with multiple databases in one application or that can easily be ported to another database—when moving from development to production, for instance. And these are indeed valid concerns and considerations.

But, as Tom Kyte points out in his latest book, Effective Oracle by Design (Oracle Press), database dependence should be your real goal because you maximize your investment in that technology. If you make generic access to Oracle, whether through ODBC or Perl's DBI library, you'll miss out on features other databases don't have. What's more, optimizing queries is different in each database.

Zend Technologies, a commercial software company that contributes significantly to PHP, has created a commercial-development environment called Zend Studio that includes a sophisticated debugger, a profiler, and other features. It has also built the free Zend Optimizer, which, in combination with the Zend Encoder, compiles PHP code to speed performance. Additional commercial products also exist, such as the Zend Performance Suite, which can cache precompiled PHP pages, further speeding overall performance tremendously

Implementing MVC in PHP: The Model

The Model is where the majority of the application's logic sits. It is where you run queries against the database and perform calculations on input. A good example of what a Model would look like is a simple login script. The login script gets user input from a form, validates it against the database, and then logs in the user.

The first application using the newly created framework will be the users module. I will be creating three Models:

login.php validates input from a form against the database
logout.php logs a user out and destroys the associated session
whoami.php displays simple user information, similar to the Unix program of the same name
Because I am introducing the idea of sessions and users into the framework, I will need to create a few more foundation classes as well as a table in a database. Before I go over the code of login.php, I'd like to walk through these classes.

FR_Session
FR_Session is a wrapper for the built-in PHP sessions. The code isn't very involved and provides only basic support for starting, destroying, and writing sessions.


/**
* FR_Session
*
* @author Joe Stump
* @copyright Joe Stump
* @license http://www.opensource.org/licenses/gpl-license.php
* @package Framework
* @filesource
*/

/**
* FR_Session
*
* Our base session class as a singleton. Handles creating the session,
* writing to the session variable (via overloading) and destroying the
* session.
*
* @author Joe Stump
* @package Framework
*/
class FR_Session
{
/**
* $instance
*
* Instance variable used for singleton pattern. Stores a single instance
* of FR_Session.
*
* @author Joe Stump
* @var mixed $instance
*/
private static $instance;

/**
* $sessionID
*
* The session ID assigned by PHP (usually a 32 character alpha-numeric
* string).
*
* @author Joe Stump
* @var string $sessionID
*/
public static $sessionID;

// {{{ __construct()
/**
* __construct
*
* Starts the session and sets the sessionID for the class.
*
* @author Joe Stump
*/
private function __construct()
{
session_start();
self::$sessionID = session_id();
}
// }}}
// {{{ singleton()
/**
* singleton
*
* Implementation of the singleton pattern. Returns a sincle instance
* of the session class.
*
* @author Joe Stump
* @return mixed Instance of session
*/
public static function singleton()
{
if (!isset(self::$instance)) {
$className = __CLASS__;
self::$instance = new $className;
}

return self::$instance;
}
// }}}
// {{{ destroy()
public function destroy()
{
foreach ($_SESSION as $var => $val) {
$_SESSION[$var] = null;
}

session_destroy();
}
// }}}
// {{{ __clone()
/**
* __clone
*
* Disable PHP5's cloning method for session so people can't make copies
* of the session instance.
*
* @author Joe Stump
*/
public function __clone()
{
trigger_error('Clone is not allowed for '.__CLASS__,E_USER_ERROR);
}
// }}}
// {{{ __get($var)
/**
* __get($var)
*
* Returns the requested session variable.
*
* @author Joe Stump
* @return mixed
* @see FR_Session::__get()
*/
public function __get($var)
{
return $_SESSION[$var];
}
// }}}
// {{{ __set($var,$val)
/**
* __set
*
* Using PHP5's overloading for setting and getting variables we can
* use $session->var = $val and have it stored in the $_SESSION
* variable. To set an email address, for instance you would do the
* following:
*
*
* $session->email = 'user@example.com';
*

*
* This doesn't actually store 'user@example.com' into $session->email,
* rather it is stored in $_SESSION['email'].
*
* @author Joe Stump
* @param string $var
* @param mixed $val
* @see FR_Session::__get()
* @link http://us3.php.net/manual/en/language.oop5.overloading.php
*/
public function __set($var,$val)
{
return ($_SESSION[$var] = $val);
}
// }}}
// {{{ __destruct()
/**
* __destruct()
*
* Writes the current session.
*
* @author Joe Stump
*/
public function __destruct()
{
session_write_close();
}
// }}}
}

?>

Hackers Paradise Revisited

Introduction
PHP (http://www.php.net) is a powerful server side web scripting solution. It has quickly grown in popularity and according to the February 2001 usage stats PHP is installed on 19.8% of all web sites (up 7% from when I gave a similar talk last year). Much of its syntax is borrowed from C, Java and Perl with some unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly.

Being a good PHP hacker isn't just about writing single line solutions to complex problems. For example, web gurus know that speed of coding is much more important than speed of code. In this article we'll look at techniques that can help you become a better PHP hacker. We'll assume that you have a basic knowledge of PHP and databases.

The main topics that I want to cover today are:

Laziness is a Virtue
PHP First Principles
Chameleon Coding
Speed of Coding, Not Speed of Code
PHP Hacking
Some of these were covered in more detail in PHP: Hackers Paradise. This revisit has refined a number of ideas, made the transition to PHP4 and focuses a lot more on first principles and good code structure for web applications.