Monday, May 25, 2009

Moved

This blog (as you may recall) is no longer used.

I've created a new blog: bolddream.com
Feel free to update you readers. :)

Tuesday, April 22, 2008

Zend Framework and Doctrine - Part 1 "Bootstrapping"

Hi, this is my blog, the place to throw my ideas and hope someone will catch (read) them. If your new and like it here, feel free to subscribe.

Zend Framework is a great framework. But one of the places it lags is proper ORM. It has an implementation of Table/Row Data Gateway. This is a good pattern, but requires a lot of work around it. It's best suited for complex domain logic, that differs substantially from your database schema. But, in real (web) world, this is usually not the case.
The ActiveRecord pattern, on the other hand, is modeled after the database - you get a wrapper around each of your records. It's more tied to the persisting method, but allows for faster development. Having a proper ActiveRecord implementation is (at least for me) what kicked Rails in the prime time.
The php community also has a few options when it comes to ActiveRecord implementations. One of them is Propel, which relies on the idea of code generation, and the other is Doctrine.
In a few posts I will try to share my experiences when using ZF and Doctrine together.

Part 1 - "Bootstrapping"

We'll need the two frameworks (yeah, imagine :)
  1. Zend Framework - http://framework.zend.com/download
  2. Doctrine - http://www.phpdoctrine.org/download
Choose the zip downloads or whatever suits you.
Let's create our project.
Create somewhere a folder and name it after the project name. I'll name mine zdhello. In this folder we'll need to create a directory structure.
/zdhello
/app
/lib
/www
Note that both framework does not enforce any kind of restrictions on directory structure.
In the /app folder we'll store our controllers (it's MVC, right? :)
The /www will be the document root - the files that will be public (eg. images, stylesheets, javascripts the bootstrap file - more on that latter)
The /lib folder - this is where we'll place the frameworks to help us build the next killer app :).
In both archives there's a /lib folder as well - those hold the frameworks themselves. Extract the files form both in your /lib folder.
After doing that you should have something like this:
zdhello
/app
/lib
/Doctrine
/Zend
Doctrine.php
/www
You've probably guessed by now that the /lib folder will be (in) our include path. I tend to place my own models, view helpers, plugins and other stuff I need. I put them in a folder with the name of the project and follow Zend's naming conventions (Doctrine's are very close to those, too).
By doing this I keep only one directory in my include path, so loading classes is as fast as it can get.

Now, let's setup the bootstrap.
In the /www folder we'll place an index.php file, that will handle the requests to our app. Look at the ZF manual how to setup the url rewriting (mod_rewrite in case you use apache).
Since index.php will be invoked on every request it's seems a good place to place the startup logic of the app.

<?php
set_include_path
('../lib');
// Setup the include path, so the loaders can find our classes



require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload('Doctrine');
Zend_Loader::registerAutoload();
// Register the autoloaders. They are very simmilar, but
// there are few differences, so we need them both


// Setup the doctrine connection

$mgr = Doctrine_Manager::getInstance();
$mgr->openConnection('mysql://user@localhost/zdhello');

// NOTE: This line prevents Zend's autoloader from complaining
// about missing classes. Doctrine, by default, looks for a
// class named MyModelTable when you load MyModel. Setting
// this options to false turns this off.

$mgr->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, false);

This tutorial should give you the jump start you need to get started with ZF and Doctrine, providing you are a little bit familiar with them and PHP, in general.

Read the documentation of Doctrine and Zend Framework to move ahead.
There are also few other tutorials like this:
Ruben's tutorial is a lot deeper, so be sure to check it out.

Tuesday, March 18, 2008

Google Summer of Code 2008

Google Summer of Code has begun. The list with the featured projects and ideas is out. If you are a student and want to make a good use of your summer, consider participating. It's a great opportunity to show yourself to the world (of software). Also, the fact that you have a mentor assigned will make sure you'll grasp the stuff under the hood of your project of choice quickly.

There's one particular project that looks very interesting to me: the Io language - an OO prototype based dynamic language (UPDATE: which actually wasn't accepted for this year's campaign). I find it even better that Ruby (and hope to find some time to blog about it soon). Consider having a look at it.

Friday, March 14, 2008

Binary XML

The W3C has a working group whose job is to develop a binary format for transporting xml in an efficient manner.
Today I checked the site and there was this:
Note: This Working Group ended successfully, and on schedule. The actual technical work to establish an internationally recognized standard for efficient interchange of XML is being done by the W3C Efficient XML Interchange Working Group.
There's even a draft, a primer and best practices. The date of these documents is 19 Dec 2007.

All this sounds great, as it will address some of the issues with xml (large files), probably parsing costs. On size - we've had a solution for a long time in the face of compression (eg. (g)zip). Minding that XML is usually sent via HTTP, the compression is not a problem at all (most of the modern web servers support output compression).

As the group states, there will be performance improvements - faster parsing, ability to deal with XML on resource-constrained devices, integrating with existing (XML) technologies.

All of the pros (and cons respectively) are about to be seen...

Wednesday, January 9, 2008

Zend Framework - how a framework should be done

In this post I'll try to explain you about a PHP framework in a very abstract way. I hope that after reading it you'll consider it very seriously for your next (or maybe current) project.

My first meet with Zend Framework (ZF) was in the beginning of last year. It was version 0.1 or so. Back then it was "something promising". Now, it's reached it stable 1.0 and it is something you should seriously consider for your PHP toolbox.

First of all - this is a component based framework, rather than a Full-stack framework. What this means it that ZF is made by many little pieces, that can work very well together, but can also be used standalone, unlike a full-stack framework, that forces you to marry it.

It has a high test coverage, it's very actively developed, very feature rich, nice documentation, plus a helpful community.

ZF consists of many objects. I'll cover the only some of those, although all of them are worth checking out.

Let's start with the MVC part.
ZF includes a well-designed MVC part, consisting of Controller (C) and a View (V). Like all ZF components these are easily configurable for your needs and easily extensible for pushing the existing boundaries even further.

A ZF powered web app will consist of a few things.
First - that is a bootstrap file - a simple php file, that accepts all request (redirecting usually is done via mod_rewrite, although not necessary).
All you need to place in the bootstrap file is a line to run the front controller to do it's "magic"... No. There isn't any magic in ZF - this isn't Rails, where there almost everything is "magic". The framework design is straightforward and and (almost) consistent (this is a flaw I find about the framework. I'll tell you about this a bit later).
The routing process is easily extensible via routes.
http://framework.zend.com/manual/en/zend.controller.router.html
And the controller part - it's really well though - extensible almost everywhere you can think of and even on places you wouldn't think of. :)
This is achieved either via Controller plugins, or inheritance. Simple, and yet very powerful.
All you need to get it working is extend the abstract class Zend_Controller_Action and implement your actions in temrs of class methods. Check out the documentation for more info.

About the view part - that was a bit short on features. It used to be just a php file wrapped in a class, so you can pass variables to it. But not any more. Currently if you get the framework from svn trunk (witch I think is a very good practice when developing with a high level tool as a web framework), there is support for layouts, partials, place-holders - everything you need to take full advantage of code reuse. The new view system will be released with version 1.5 (that will be the next major version). A release candidate is expected on 24th of January. (I remind you that it's already available in the svn, version 1.5 or any other are just a label on a snapshot).
Also, the ViewRenderer controller plugin will load your views for you with a single line of code telling it where are the views (it very good, but it doesn't read minds :).

The model part, well - there isn't a strict one, that you would expect to see in a framework like Rails. The model could be anything - database, xml, feeds - whatever you need.

Zend framework has a database abstraction layer - Zend_Db. In particular Zend_Db_Table - it's an implementation of the Table/Row Data Gateway pattern, rather than Active Record like in Rails, CakePHP and others. I, personally, think this is the weakest part of the whole framework. Not because it's not active record, but because something small and simple - it looks just like the core functions of php - inconsistent. The parameters you pass to specify a where clause in select and delete are quite different. It's a annoying. But that's about it's problems. I hope that this will be fixed really soon.
Now on the good stuff about Zend_Db_Table part. It is a lot lighter than a full blown active record implementation (check Doctrine for a php one). Zend_Db will abstract you from the differences between different database backends and give a lot more control to what you are doing. There is Zend_Db_Table which is the Table data gateway. There is one simple, yet importatnt thing to grasp about it - do not use Zend_Db_table objects as business objects (ignore only for very simple cases). Rather that, use it as part of your business objects. In other words - threat Zend_Db_Table like "has a", rather than "is a". You'll be surprised by the power of it.

On the model part - there are a lot of clients for different web services (Flickr, Yahoo, Delicious...).
You are limited only by your imagination what you can achieve.

The framework provides a way to manage caching - Zend_Cache. It will (just like Zend_Db) abstract you from different backends (which may be a File, Memcache, APC...). It supports nice built-in stuff that allows for fine control over the cached data. You can tag it, and then expire all data that is flagged with a particular tag. You can cache whole pages, parts, even method calls! When you decide it's time to switch - just edit a line in you config file. Simple? It is. :)

Speaking of configuration - there is Zend_Config - currently it supports php arrays, xml and ini files, but more backends are in development. Do I have to say that it abstracts you from the different formats?

Zend framework provides a good set of tools when it comes to i18n and l10n. Be sure to check out Zend_Translate, Zend_Date, Zend_Currency, Zend_Locale and Zend_Measure.

The framework features also a Zend_Auth to manage authentication and Zend_Acl to manage user rights. If you want to authenticate against database, there is a complete solution in terms of Zend_Auth_Adapter_DbTable, LDAP support will be in 1.5, too. In order to have a database based acl - you'll have to implement it yourself, but it's fairly easy.

I saved the best part for last - Zend_Search_Lucene. If you know what is Apache Lucene - this is a PHP port of it, compatible with it's index files (version 1.9, 2.0). If you don't read on.
Zend_Search_Lucene is a very powerful full text searching engine written in PHP and part of ZF. Using it you can very simply add google like capabilities you your site. Simple text box that understands human text (wow :). It supports complex queries, result relevance, and lot's of options for fine tunning. This component can be used standalone, so you just may grab it and stick it to your php-powered site.

Well, I hope I convinced you to take a serious look at Zend Framework - it's a very well though piece of software, built with the idea of ease-of-use, extensibility and robustness.
PHP is a good language, that can be used "enterprice". Yeah, those .NET and Java folks really like to claim themselves "Enterprise level".

Wednesday, June 6, 2007

Implementing your very own lightweight, secure and extensible MVC framework in PHP.

Hello,

You might have heard about MVC frameworks like Rails, Symfony, Struts and many others. However, i recently started a new project and none of the existing frameworks seemed to suit my needs perfectly, so I decided to forge my own. Actually, I really enjoy doing everything by myself (most of the time this is not the best solution, though). So...
I would like to share with you an idea of mine, about implementing a lightweight, simple, secure and extensible (sounds promising :) model-view-controller framework in PHP with search-engine friendly URLs.
Note that, I'm writing this post mainly to share my ideas - the implementation is more like a proof-of-concept.


I will start with a few words about the model-view-controller (MVC) pattern itself. If you are already familiar with it, you might skip this section.
The MVC design pattern is all about modularization and dividing an application into multiple part, so it can be easier to maintain and extend (plus a lot of other things).
The Model: This part of the application is the representation of user-useful data into the computer world. It consists of many models, each representing a business object and encapsulating business logic in itself.
The View: The view is the part, responsible for outputting data to a user (not necessarily a human) and retrieving input from the him.
The Controller: The controller is basically the glue between the other two parts. It's also responsible for calling the model to apply the business logic based on the user input (from the view) and passing the view the data, gotten from the models to display.

If you want to know more about the MVC pattern simply google for it.


So, lets get on implementing our very own MVC framework in PHP.

What you need is PHP5+, since will be using a lot of it's object oriented features.
(Note: Implementing it in PHP4 is also possible, but I would not recommended it. Try always to use latest PHP for new projects and port old ones to PHP5, as PHP4 support will be discontinued by the end of the year)


Lets first lay down the basic design of out home-made framework.

We will implement only two of the parts of the model-view-controller pattern - the view and the controller. Since the models are very task specific and can vary a lot we won't (and shouldn't) deal with them.

The controller will be a lot simpler by the ones that you've probably seen on other frameworks (like Rails and Zend Framework). It will not have actions - each controller will be an action itself. This helps keeping logic more separated, since controllers with actions tend to grow a lot it most of the projects. I, personally, really don't like dealing with files of 2000+ lines. I have the feeling I'm scrolling forever, just to change a single line, even when using code bookmarks.
The controller part will be consisted of two parts - an abstract controller and a dispatcher.
The abstract controller will be the starting point for the framework's user in implementing his custom controller, where the dispatcher will decide to which controller to pass the execution.

The view part will be relatively simple, but quite powerful.
Remember, we are building lightweight framework, so it doesn't require a supercomputer to run on.


First, we will make the dispatcher. It will be a piece of PHP code (think class), that will instantiate the right controller and pass the execution to it, so later, when using our framework we will think of the controller as out starting point, and the dispatcher will do its job, without us even knowing it.

This class will take the URL for a start, and based on it will know which controller to instantiate. So, how it will work?
Consider the following URL entered by the user:

http://www.mysite.com/show/product/123

Our dispatcher will threat slashes (/) as token delimiters. It will take the part immediately after the host name for a controller name - in our case this is show and the rest of the data will be considered parameters in a name/value pairs.
Now you might be asking what will happen if the user enters just

http://www.mysite.com/

Well, we will consider s/he is requesting the index (the default) controller.

The next part is quite tricky - what of the user requests a page with name

http://www.mysite.com/product/123

Should we call the product controller or the index (default) one passing it a parameter with name product and value 123?
Actually determining weather it is the default controller or not is quite easy.
We need to count the tokens (parts delimited by a slash) and call the index controller if the tokens are an even number or call a specific controller if they are odd. Why would such a simple check work for us? Because we mentioned, that our parameters (part in the URL after the controller name) will be name/value pairs - so if there are odd tokens - this means there is one extra, so the first one must be the controller name. Simple, isn't it?
Also will use another delimiter, the dash (-) to indicate internal subdirectories where to look for controllers. Will cover that a little bit later.
Note: According to PEAR's coding standards the underscore (_) is used for directory separator - feel free to use it for the same purpose here.

Alright, we know how to determine to which controller to pass execution to - whether the index controller or a special one, but what if the user requests a non-existing controller? Well, we should simply call a special no-route controller to notify him that the address he requested does not exists. (Consider this as our indoor 404ErrorDocument).


The first thing in implementing our dispatcher will be extracting the tokens (controller name and parameters) from the URL. We can obtain the URL from the $_SERVER['REQUEST_URI'] variable.
Note: This variable comes from the user and holds a potential security risk, so make sure you have validated it properly (e.g. by using filter_input())

Here is my code:

protected function
_parseUri($requestUri) {
// Strip GET parameters
$questionPos = strpos($requestUri, '?');
$requestUri = substr($requestUri, 0, $questionPos !== false ? $questionPos : strlen($requestUri));
// Prepare the uri to be splitted by '/'
$requestUri = trim($requestUri, '/');
// Parameters to be passed to the controller -
// will be empty if there are no parameters
$matches = explode('/', $requestUri);
// Remove empty occurences (in case the address looks like http://www.mysite.com/con////name//value)
$matchesCount = count($matches);
foreach (
$matches as $key => $match) {
if (empty(
$match))
unset(
$matches[$key]);
}
// Reindex

$uriItems = array_values($matches);
$start = count($uriItems) % 2;

$params = array();
$uriItemsCount = count($uriItems);
for (
$i = $start; $i < $uriItemsCount; $i += 2) {
$params[$uriItems[$i]] = $uriItems[$i + 1];
}

if (
$start === 1) // Controller specified
$controllerPrefix = $uriItems[0];
else
$controllerPrefix = $this->_indexPrefix;
//Generate the controller prefix if the name is in format word-word => controller word/WordController
$words = explode('-', $controllerPrefix);
$controllerPrefix = array_pop($words); // Get the last word
$controllerSubDirectory = implode (DIRECTORY_SEPARATOR, $words);

return array (
'controllerPrefix' => $controllerPrefix,
'controllerSubDirectory' => $controllerSubDirectory,
'params' => $params
);
}


We just need to pass this function the $_SERVER['REQUEST_URI'] variable and it will extract the information we need.

We'll need to pass our dispatcher a path, where the controllers reside, using a convention, so we know that, for example, class IndexController is located in a file named indexcontroller.php.

Using the controller name we have discovered when parsing the URL, we capitalize it and append a word to it, for instance - Controller. So, a path http://www.mysite.com/show/ will look for a class named ShowController in file showcontroller.php in our controllers directory and a path http://www.mysite.com/cars-show/ will look for a file cars/showcontroller.php again in our controllers directory.

After parsing the URL we know which controller should be used (either default one or not) and where to find it.

Now it's time to check whether the controller that should be called exists. That can be accomplished by using the path, we passed to the dispatcher pointing to the location of out controllers.
Then we need a simple method that checks if that file exists and is readable using is_readable(). If not - this means the controller is not implemented - so we should call to the no-route controller.
Note: Your application must have at least index and no-route controller implemented to work (if that can be called working).

protected function _loadClass($className, array $paths, $subdirectory = null) {
/* $paths is an array pointing all the paths with controllers
* We search them one by one until we find a match or run out
* of paths.
*
* $subdirectory is the subdirectory, extracted from the URL (word-word -> word/WordController)
*/
foreach ($paths as $path) {
$fullFilePath = $path . DIRECTORY_SEPARATOR . $subdirectory . DIRECTORY_SEPARATOR . $className . '.php';
if (
file_exists($fullFilePath)) {
include (
$fullFilePath);
if (
class_exists($className))
return
true;
}
}
return
false;
}

After checking the file loading is easy - since php is dynamic language you can put the name of the class in a variable.

protected function _dispatchToController($controllerPrefix, $controllerSubDirectory = null, $params = array()) {
$controllerName = '';
if (!(
$controllerName = $this->_loadController($controllerPrefix, $controllerSubDirectory))) {
// Controller not implemented - go to noRoute contoller
if (!($controllerName = $this->_loadController($this->_noRoutePrefix))) {
// No route not implemented. Halt.
throw new Exception('No-route controller not implemented');
}
}
$controller = new $controllerName();
/* @var $controller AbstractController */
if (!$controller instanceof AbstractController)
throw new
Exception($controllerName . ' is not an instance of AbstractController');
$controller->_execute($params);
}


Basically, that's the dispatcher.

Now we need to make our abstract controller. It's pretty straightforward with one consideration to be taken - since we want out framework to be secure, the best way to do this is push the user (not over the window :) to validate his data, as this is the most common security problem.
We'll leave this problem for now and move into implementing the abstract controller.

abstract class Controller {
public abstract function
run();
}


And that's it!
The user will need to extends this class and implement the run() method. This method will be the starting point for the request from the user's point of view.

Now it's time to put the security.
Note: When I say "put" I actually don't mean it. Security is not just added to an application - an application should be designed with security in mind. Security is not a feature you put into your application to add it in to the advertising headlines.

What we'll do is we will put a validate() method that will be empty, define a final constructor (one that cannot be overrode) . What we'll do to actually tighten our security is after the validate method has finished, we will unset all the global variables, that hold potential security risk, so the user will have to validate them first, before using them.
So the new controller will look something like this:

abstract class AbstractController {
/* A predefined array for the user to store validated data */
protected $_clean = array();


final public function
_execute(array $params) {
$isValid = $this->validate($params);
unset(
$_POST, $_GET, $_COOKIE, $_FILES, $_REQUEST, $_ENV, $_SERVER);
$this->run();
}

public function
validate(array $params) { }
public abstract function
run();

protected function
_redirect($url) { /* A simple, but very useful redirect method */
header('Location: '. $url);
exit(
0);
}
}


Note: Most people tend to forget the $_SERVER super-global - actually the web server populates it, but in most cases it uses data, provided by the user. The only super-global that can be considered safe is $_SESSION (although it's not 100% secure, but if it's been compromised - you are doomed).

I know this isn't a 100% secure, but if the user doesn't care about the security of his's application the only way to make him care is point a gun at his head.

The user will simple override the validate(array $params) method, use PHP's filter extension and stuff the valid data into the $this->_valid array.

So this is the controller part of the MVC .

The next part is the view. I've seen some implementations in PHP using output caching to guarantee that headers are send properly. However - this is a major performance issue and doesn't worth paying the price.
The view is relatively simple - it will have a class, that will know where the view files (regular PHP files) are located and a render method to display a file by simply including it. Well also implement the magic PHP methods __get(), __set(), __unset() and __isset() so we can push data in the view and display it later. The view will not support any templating facilities such as Smarty, because I think it's stupid to have a templetes over PHP, since PHP is itself a templating language. So why do we need another one over it? (Personal opinion)

Let's get the view done, shall we?

class View {
protected
$_path;
protected
$_vars = array();

public function
__construct($path = '.') {
$this->_path = $path;
}

public function
setViewScriptsPath($path) {
$this->_path = $path;
return
$this;
}

public function
getViewScriptPath() {
return
$this->_path;
}

public function
__set($variableName, $value) {
$this->_vars[$variableName] = $value;
}

public function
__get($variableName) {
return
$this->_vars[$variableName];
}

public function
__isset($variableName) {
return isset(
$this->_vars[$variableName]);
}

public function
__unset($variableName) {
unset(
$this->_vars[$variableName]);
}

public function
render($view) {
include(
$this->_path . DIRECTORY_SEPARATOR . $view);
}

public function
escape($string) {
return
htmlEntities($string);
}
}


I've left the view completely uncommented, so you can see how simple it is.

Using it is even simpler:

<?php
class IndexController extends AbstractController {
public function
run() {
$view = new View(PATH_TO_VIEWS);
$view->title = 'My Cool Page';
$view->date = date('Y-m-d');

$view->render('index_v.php');
}
}

And index_v.php:

<html>
<head>
<title><?php echo $this->title ?></title>
</head>
<body>
Today is:
<?php echo $this->date ?>
</body>
</html>


An additional, also very useful part will be a registry object. It's basically a singleton (a class that can have only one instance).

class Registry {
protected
$_items = array();
/**
* The singleton Registry instance.
*
* @var $_instance Registry
*/
protected static $_instance = null;

protected function
__construct() {}

public static function
set($name, $value) {
self::$_instance->_items[$name] = $value;
}

public static function
get($name) {
return
self::$_instance->_items[$name];
}
}


Once the fellows that make PHP such a great language implement static __get/set this will be made even cooler :).
You can use it to store the view in it, so you don't have to instantiate and configure it every time
you need it. Also this is a good place for your database connection.

And, there you have it - you very own MVC framework you that can use to make the next cool app you have in mind.

Using it is very simple: create a directory structure like this:

|_ project home
|_ webroot <- here will be your document root
|_ index.php
|_ .htaccess
|_ lib <- here you put the framework
|_ app
|_ views <- put your view here
|_ models <- your models (business objects)
|_ controllers <- controllers
|_ bootstrap.php

Tune your web server to redirect all requests to index.php in the docroot directory, using mod_rewrite and adding the following lines to the .htaccess file.

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php


Then in the index.php file add only this code:
<?php
require('../app/bootstrap.php');

By doing so you ensure that even if the server for some reason doesn't execute .php files you are still not providing any potentially dangerous information.

In the bootstrap.php file run the dispather and watch it work :)

<?php
define
('PATH_CONTROLLERS', '../app/controllers');
define('PATH_VIEWS', '../app/views');

$view = new View(PATH_VIEWS);
Registry::set('view', $view);

Dispatcher::run(PATH_CONTROLLERS);

Any suggestions are welcomed.

Take care, and remember that life is all about living it the way you (not your boss) want it.

Note: This is my first blog post ever in my life. Hope you like it.