Wednesday, February 23, 2011

DAO vs ActiveRecord

There are a lot of discussions about DAO/DataMapper & ActiveRecord. Here are some articles:

static methods VS singleton

Well this is an old topic but i've never seriously thought about it. We can grab a lot articles from internet, but here is what i agree most:

1. singleton is an instance, instance is an object. so, you can pass it as a parameter. If you were using static classes, the other function would have to use the class statically too and if you ever needed to change the behavior, you would need to rewrite parts of that function too instead of just having the first one pass a different class as the parameter.

2. You can also give a singleton some parameters. When working with static classes, you may need to pass a lot of parameters to the methods of the class because you aren't "constructing" it

3. singleton can become multiton(read db connection, write db connection)

4. If you use the reference in your class and decide that you won't need a singleton anymore, but a normal class, you will just need to change the behavior of the class itself and perhaps replace the line which gets an instance of it to constructing a new one or such. If you were using a static class, you would have to rewrite a lot of the code to use the new reference to the class instead of the static class name. A singleton class should also work almost out of the box as a normal class too. If you had a static class and wanted to convert it to a normal one, you would have to rewrite many parts of it.

6. You can't extend static classes, but singletons you can. Except it doesn't work very well in PHP due to some issues with static method inheritance, but it's not the only language in the world and it can be done but slightly hackily

7. Last and least:D dude, you can find many singleton in Zend Framework. Could you find any static class there?

So to the end, where is the place for static methods? Well, they definitely have their places too:
For example for library code they can be nice, such as the static System.Math class in C#

Unset problem with Collection implements Countable, Iterator, ArrayAccess

I just have one problem with my Collection class implements Countable, Iterator, ArrayAccess. Let's look at the code below:

foreach ($Collection as $index => $model) {
//do something

But, obviously, I haven't found any solution to make the above code work properly. It is all about the array internal pointer, the valid() method and the offsetUnset() method. I tried different with my own implementation and with others' code(code searched from google, and code implemented by some open source software like tomatocms)

Sunday, February 20, 2011

php xdebug not formatting var_dump

I installed php 5.3 and xdebug on my ubuntu 10.10. However, the xdebug is not formatting php's var_dump().

The reason is in php.ini, by default html_errors = off. Simply change html_errors = on and you will see var_dump is formatted by xdebug.

Thursday, February 17, 2011

Magento Hierarchical Category Database Design

First of all, there are two ways to manage hierarchical data in MySql(or other relational database). One is Adjacency List Model and the other is The Nested Set Model. They both have pros and cons. Again, i recommend you read this article first before you start to work on hierarchy related issue.

Magento uses Adjacency List Model for some reasons, which i don't know what they exactly are. The problem of Adjacency List Model is traversing hierarchy tree is very difficult and low efficient. Usually you have to recursively query database to find out the depth/level of a node.

To address the problem of Adjacency List Model, Magento's category table has three extra columns:level, path, children_count. As the names suggest, 'level' stores the level of a node, 'path' saves the path from the root node to this node and 'children_count' records the number of children the node has. If you are interested in what they really look like in Magento's database, you can simply download and install Magento.

As you can imagine, with the three extra columns, traversing hierarchy tree becomes extremely easy.

You may also find out that in this way, the difficult part goes to manipulating: adding/deleting/moving a node. For each of these operations, you have to update those three extra columns for the nodes involved in your operation.

However, there is no perfect solution to hierarchy data(even in Nested Set Model, manipulation is very hard) because relational database is not designed to handle hierarchical data, not like XML. It is a trade-off. We either sacrifice one side for the other side. And i think traversing hierarchy is obviously the most critical part.

Monday, February 14, 2011

Magento category management flaw (bug)

Category is a typical hierarchical data structure. Two options of Managing Hierarchical Data in relational database are Adjacency List Model and Nested Set Model. Here is a very excellent article about this topic:

Theoretically, Magento allows a user to create unlimited level of categories. Magento uses Adjacency List Model to manage hierarchical data. To overcome the disadvantages of Adjacency List Model, Magento's catalog_category_entity table includes these columns: depth, level, children_count, path.

As far as i can see, the flaw is caused by the column 'path'. 'path' is a varchar(255), it stores the path from the top level category to itself. For example, the current category id is 5. It is a sub category of 4, a sub category of 3, a sub category of 1. The path data of id 5 will be like "1/3/4/5". Problem occurs when the length of the path string exceeds 255. The new category won't be able to displayed correctly.

I think this is a minor issue cause most of the time we don't need to create such huge and deep level of categories, or do we?

Mysqli VS PDO

The reason i prefer PDO is it supports both binding named parameters and binding positioned parameters. Mysqli, on the other hand, only supports binding positioned parameters.

$sql = "select * from user where id > ? and id < ?";
$bind = array(1, 10);

As a developer, you must ensure your $bind array elements are in correct position. For the above example, if your $bind array is array(10, 1), the query will actually become "select * from user where id > 10 and id < 1)".

$sql = "select * from user where id > :start and id < :end";
$bind = array("end"=>10, "start"=>1);

My opinion is binding named parameters really improves the program's readability.

Tuesday, February 1, 2011

setup LAMP on ubuntu10.10

1. apache:
install apache
apt-get install apache2 apache2.2-common.

enable mod rewrite
sudo a2enmod rewrite

2. mysql
apt-get install mysql-server mysql-client

3. php
apt-get install php5 libapache2-mod-php5 php5-common php5-gd php5-mysql php5-imap php5-cli php5-cgi php-pear php-auth

4. pdo-mysql
Any one is not using pdo on his new projects?

sudo apt-get install php5-dev
sudo apt-get install php5-mysql

Restart your apache and it is done