PHP LINQ: A nice alternative

A few days ago, I was browsing through the CodePlex projects, to see if I could find something nice to try, and it happens I did. I’ve always been a defender of .NET and it was the motive of several discussions with my (not so fan of .NET) friends. One feature that I’ve always enjoyed on C# was the introduction of LINQ on .Net 3.5 which I believe is one of those life changers of the language.

For those of you who hate .NET or just don’t care about it, LINQ is a powerful way to access/query your data through a set of extension methods created on the IEnumerable interface. For those of you who’ve never heard of it, you can do amazing things like this:

var aCollection = new List<AnySortOfClass>();

var query = from item in aCollection 
   where item.APropertyName == “Nice!!” 
   select item;

foreach (var item in query )
 Console.WriteLine(“Found an item: ” + item.Name);
 

This is a pretty neat stuff to have when programming, at least you can kiss goodbye to all the nasty for loops (or foreach loops) looping into an array just to filter data. The idea of taking the SQL approach into other programming languages, at least for performing data related tasks is very reasonable one, so I believed that LINQ would be conceived for at least a few other languages.

Due to the fact of LINQ heavy use of anonymous types and lambdas (supported on PHP until 5.3, at least directly, before we could use create_function() ), I didn’t had much hope for a PHP version of LINQ to show up, then I found PHP LINQ, a project hosted in CodePlex and maintained by Martin Balliauw.

After browsing for a couple minutes the source code and the examples, I have to say, that PHP LINQ does have some potential. For instance, there is a Zend_Db_Table adapter for those who use Zend framework, which is kinda neat. You can do something like this:

Assuming you have a EmployeeTable (employee.php)

class EmployeeTable extends Zend_Db_Table {
    // table name
 protected $_name = 'employees'; 
 
    protected $_primary = 'Id';
}
 

You can now perform this query:

$employeeTable = new EmployeeTable(array('db' => $db));
$employeeTable->setRowClass('Employee');

$result = from('$employee')
 ->in( $employeeTable )
 ->where('$employee => strlen($employee->Name) < 5')
 ->orderBy('$employee->Name')
 ->select('$employee');
   
foreach ($result as $employee){
 // do something with $employee...
}
 

I think this is a rather nice way to work around queries for the database. Anyways, will try to do on my free time (which is kinda scarce these days) a driver for using with Propel, which is the ORM I like using!

Applying design patterns to web development

Part 1: The strategy pattern

One of my biggest efforts as a developer is to apply design patterns to my software designs and implementations. When I’m working with PHP is where I most feel the lack of OO approaches in many cases. PHP started as a procedural language, with a few functions serving for a limited amount of tasks, but like anything in this world, it has evolved into a more mature language. The problem is that many tutorials around the web are meant for starting as a developer and tend to leave Object Orientation out of the box, which is a trend that I find awful.

Sadly, there are still many PHP developers writing procedural code and calling it object oriented because they use the word class. Writing OO code is a bit more complex than that, we need to “think” how to express our problem into objects and how to make them communicate, not to create monolithic systems with strongly coupled components, which turns into software impossible to maintain, document, test and most importantly reuse and scale.

Well, back to the main idea, in this blog post I intend to use the strategy design pattern, which is one of the most implemented design patterns when it comes to web systems. The definition of the strategy pattern is:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

The classic scenario is a situation where we can employ different variants depending on the environment. For instance, Session Management is an important task on every web application. If we are going to create a small application, then using the standard PHP session implementation, we are good to go. But this does pose two main problems:

  1. If we are in a shared hosting, anybody in the same server can work around the server´s security and copy the session files thus gaining access to data we don’t want them to have.
  2. If we want to scale our application, like adding extra servers, moving the application to a cluster or something like it, sharing the session files is a nightmare for managing the sessions

So, we have two main scenarios, where we are able to use the standard session driver and where we have to use a more advanced session management system, like for instance a database approach or integrating with Memcached or another powerful solution.

The initial approach is to write a PHP file called sessions.php and there do something like this:

$driver = $configuration[“session”]->getFile();
include $driver . “.php”;

And driver would be a file performing the calls to the session_set_save_handler function which changes the functions for managing the sessions, and of course, the implementation of such functions.

An approach like that one does the job, but we would have no objects, just a bunch of files. The real Object oriented version would be defining the contract of how we want to interact with the drivers. In our case, we have a session driver, which could hold a few operations, basing on the session_set_save_handler function arguments, we would need 6 methods in our interface: Open, Close, Read, Write, Destroy and GarbageCollect.We would have something like this:

interface ISessionDriver
{
   public function Open();
   public function Close();
   public function Read();
   public function Write();
   public function Destroy();
   public  function GarbageCollect();
}

Now, we have an interface, and we can register the interface as the session provider. To do that we have again two methods, the first one is loading from the configuration the class we want to load, and we’ll see the second soon on how to use Dependency Injection.

The idea is very much like the first functional approach, include the template file, but now we know that we’ll have a class implementing the ISessionDriver interface, a class which respects a contract previously established by me. Again, we would do a code quite similar, but now we would check:

$driver = $configuration[“session”]->getFile();
   include $driver . “.php”;
   $driverInstance = new $driver();

   if ($driverInstance instanceof ISessionDriver){
      //register the session driver
   }
   else
      throw new SystemException(“Expecting an ISessionDriver here!”);

With that we finish the first part of how to decouple our classes into a more reusable environment, applying the strategy design pattern and we will get deeper into it soon by using dependency injection to make this design even more decoupled.

Using Propel with CodeIgniter

CodeIgniter is a nice development framework used for PHP applications. Is light, small, compact and it does provide an “Object Oriented” solution for web development. However, it lacks a major component, which is a database infrastructure. CodeIgniter’s models provide a rather quick and dirty solution for database access, which is nice for small projects, because we cannot be thinking on the large solution every time we write a piece of code, but for most decent application, a small approach like that one, just won’t do it.

The solution? Well, using an ORM framework. I’m a defender of ORM mapping solutions and I believe that they are here to stay, just like the Korn song. Anyways, there is no easy way to integrate CodeIgniter with Propel; they just don’t seem to get along. I’ve read a wiki post explaining how to do it, but I found it quite disturbing for a few reasons

  • A solution shouldn’t tell you to change the apache configuration
  • Propel has a really powerful autoloading system, why did they not prepared for using it?

Anyways, the idea I came up with is to integrate Propel as an independent library for the framework using the libraries autoloader, which is much like the post I’m talking about, but I made a few tweaks. CodeIgniter stores it’s plugins into the folder system/libraries, so the best way to start is copying Propel’s runtime into that folder. Create a folder called propel and copy the runtime files (propel/runtime/lib/*) there.

After copying Propel we can create the library’s entry point, which is a file called propel.php and there we will write a class to load Propel:

class CI_Propel
{
  public function CI_Propel()
  {
 define(DIRECTORY_SEPARATOR, “DS”);
     require dirname(__FILE__) . DS . "propel" . DS . "Propel.php";
     Propel::init(BASEPATH . "application/config/propel-conf.php");
  }
}

In this class we require the Propel main file (Propel.php) and we tell it where he can find the configuration file. The configuration file is the xml file generated by Propel storing the database configuration and we must specify it in order to get propel running.

Now we’ve created our driver, we need to tell CodeIgniter to load our library, and this is done by going into the application/config/autoload.php file, where CI stores the libraries to be loaded with the application. We need to look for the line:

$autoload['libraries'] = array();

And change it with the information we need to load propel:

$autoload['libraries'] = array('Propel');

Now, we need to copy Propel’s models into the models folder located in the application folder and the configuration files generated should be on the application/config folder. Now the mapping configuration files should be edited to load the models properly; Propel works with relative routes to the models and it breaks when we try to load those models from a different path. You should look for lines like this one:

'CategoriesTableMap' => 'Northwind/map/CategoriesTableMap.php'

And change them for the real CI path:

'CategoriesTableMap' => BASEPATH . DIRECTORY_SEPARATOR . "application" . 
DIRECTORY_SEPARATOR . 'models/map/CategoriesTableMap.php'

Well, all we need to do now is use Propel! Keep in mind that using Propel’s classes directly from the controller is a bad practice, because you’d be coupling your data access layer to your presentation layer, you can take a look on this post if you want to read a bit more about it.

For our practical purposes we can just call the Propel query object from the controller now, much like this:

function index()
{
  $query = ProductsQuery::create()->limit(10)->find();
  $data =  array();
  $data['rows'] = $query;

  $this->load->view('welcome_message', $data);
}

And it will retrieve the results quickly and using a nice ORM mapper. I hope you’ve found this post useful and as usual commenting is highly encouraged!

Using ORM classes as Business models?

For a long time, Object Relational Mapping (ORM) has proved to be a very good solution for data driven applications. Dynamic web applications are those who serve data store in a database; and this data is introduced by a (often not so friendly) user interface, hence the “dynamic” part. As design patterns emerged, one particular pattern became very used in frameworks and applications, which it was the Object Relational Mapping design pattern.

The basic idea behind the ORM pattern is to “map” each table (relation) to a class in our application. Following this notion, then a particular instance of a class was a row in the table, which could, at some point of the application’s lifecycle, be persisted or not. ORM frameworks handled the process of creating, retrieving, updating and deleting rows as objects, finding a way to know if a particular object has been saved or not. The basic layout of the behavior of a ORM tool/framework would be like this:

A class is generated for each relation we found in the database. We make our data model, then we generate the classes for it. Notice how I’ve made some underlining on generate, that is because most of the ORM frameworks has a built in class generator. After all, what good would they do if they don’t bring this?

The two major ORM frameworks I know for PHP, which are Propel and Doctrine, both have built in generators for our models. With these generators, we get a set of classes each handling a task on the tables we have on the data backend. So far, this sounds great! But the good part hasn’t yet arrived. 

For the purpose of this application, let’s create a sample database with the Northwind database script, which has been used for these purposes for a long time due to the fact that has a few relationships, some good data and all the cool things to create a nice playground for testing an sort of data technology.

When we are developing a full blown application, we have some validation rules and some desired behaviors, like for instance, to know the full price of an order we use an equation, in a typical scenario, this would be a simple equation like this one:

Full Price = (Unit Price * Amount) + Shipping + Handling – Discount

This is what we call a business rule, and they are extracted from the client, which sometimes can be ourselves. Business rules define how our application responds to input and are the very core of it, however the can change at any point of our application. We could embed our business rules into the data extraction routine (although is not always possible); for instance, we could store a view in database returning the rows we need, something like this:

SELECT  
   `orders`.OrderID,
   (`orderdetails`.UnitPrice * `orderdetails`.Quantity) AS RawPrice,
   `orders`.Freight AS ShippingHandling,
   `orderdetails`.Discount as Discount,
   (`orderdetails`.UnitPrice * `orderdetails`.Quantity + `orders`.Freight) -  
                   `orderdetails`.Discount AS Total
FROM
   `orderdetails`, `orders`
WHERE
   `orderdetails`.OrderID = `orders`.OrderID
GROUP BY
   `orders`.OrderID
ORDER BY Total DESC

This approach is (sadly) used by many online applications nowadays, where the business logic is embedded in the data source. With this approach, one main issue comes to scene: maintainability. Maintainability is the nightmare of many applications; in this case, the big trouble would occur if any of the calculating equations needs to be changed. To do so, we would require access to the database, change the view and use the new equation. This is a viable solution, because after all, it works! But attaching these application specific calculations to the data store is not good because you would have to change the way your data is stored to make changes, and practice demonstrates that whenever possible you should avoid messing with your database.

The other way to do this is by using the same classes generated by those ORM frameworks we talked about, like Propel (example are using Propel 1.5). The code doing the same function we just did would now be:

   $query = OrderDetailsQuery::create();

$result = 
    $query->joinOrderDetails()
          ->withColumn("`orderdetails`.UnitPrice *  
                        `orderdetails`.Quantity", "RawPrice")
          ->withColumn("`orderdetails`.UnitPrice *  
                        `orderdetails`.Quantity + `orders`.Freight -
                        `orderdetails`.Discount", "Total")
          ->Select(array("RawPrice", "Total", 
                        "Orders.Discount", "Orders.OrderID"))
          ->groupBy("Orders.OrderID")
          ->OrderBy("Total")
          ->find();

The outcome of this query is the same than before, but now our business rules are on the data layer, however, this is not quite yet the result we want. For this example, a development like this one might work since we are just making a simple and plain query, but suppose we have another table called Customer2Product to store the preferences of customers using products and we need to insert a row into this table every time we add a product into a customer’s orders. Obviously this behavior cannot be attached into the data store, but in some cases we might do it in the data access layer.

Having the business rules in the data layer is not good, because we need to keep in our architectures a clean separation of concerns. The data layer is concerned only on managing (CRUD) data, not handling logic rules regarding the application. To handle such rules, we need to create another set of classes, which are the business models.

The business layer should have a common gateway to our Data Access Layer, thus allowing communication with the data source. At first glance, the most important improvement would be the independency of data store. If we choose to change from Propel to Doctrine, or to anything else, we would only need to change our models, and the middle point between the Business classes and the Data Access Layer.

To communicate the Data Access Layer and the Business Layer we need to create a class working as a middle man, let’s call it an Adapter. The Adapter should be an interface, to allow the use of implementations. How this Adapter is implemented is a different problem on every architecture, but do keep in mind the development premise called YAGNI (You ain’t gonna need it). A sample interface would be like this:

public interface ITranslator
{
    public function Select($criteria);
       
    public function Count($criteria);
       
    public function SelectOne();
   
    public function Save($model);
       
    public function Delete($criteria);
}

After this interface is built, we would just need to implement it for each Data Access Provider we might use regardless of the type of provider.

Another setback of having the business (logic) rules of our application in the Data Access Layer is that we are directly introducing a dependency on a 3rd party tool, which is our ORM framework (this applies for every ORM frameworks, even those made by yourself). If at some point of development, we choose to remove the ORM framework in use, because of any reason, we would need to rebuild/remake most of our classes, which would be awful!

You might think… My ORM framework is very strong; I won’t be in need to change it ever!

Well, if that’s the case, then think about the amount of projects failing each day due to dependency problems. Remember that there have been many software crises and that software is a field constantly in development, meaning that tools will evolve and patterns will evolve as well. Every day there are new patterns, new technologies and many new or improved resources available for developers, so we cannot tie our architecture to any specific tool/library just because is the hot thing.

Following the wise words of many designers and architects we need to keep in mind that in software history we have never seen such thing as a “Software Silver Bullet”.