soledad penadés
repeat 4[fd 100 rt 90]

Archive for the ‘cakephp’ Category

20070122 PHP will never have a (real) Rails-like framework

I know the title is harsh but it's so true. At least it is according to nowadays php's implementation of classes and objects, which do not permit to "reopen" and add or redefine new methods to an existing class definition, which is the basis upon Rails (and I presume lots more of applications and frameworks) is built.

This ruby feature managed to freak me out when I first read about it. Redefining an existing class? Who would think of it as a good idea? Where is the maintainability and the good practices of object oriented programming? How can we rely on some class behaving as expected if some piece of code is changing its internal behaviour?

But then I got the answer - when used within reason, this allows you to extend existing classes. Extend. Morph. Adapt. Improve. Refine. Lots of concepts which started jumping around me and made me understand all in a sudden how Rails plugins worked so seamlessly, without having to do any extra include, or without having to touch Rails very core files, or defining hooks at certain places. If you don't like some aspect of Active Record, you could write a plugin which overwrites that behaviour - only that one. The rest remains the same.

The aesthetics is somehow shocking for php-only programmers. It's something like this:

class A
function hello_world
puts "I'm hello_world"
end

Any instance of A running hello_world will output "I'm hello_world"

But if you add this anywhere after the definition of A

class A
function hello_world
puts "I'm hello_world v2"
end

and run hello_world again, you will get "I'm hello_world v2". Which definitely is impossible to do in PHP - you would get a Fatal error: Cannot redeclare class error as soon as you tried to "reopen" a class and add or redefine some methods.

While this is not a problem for the average use of php, it turns to be the opposite when you want to do something smart with php5's new and shiny objects model. Something like, for example, building a cool framework like Rails.

There have been some attempts already, like for example CakePHP or Symfony. I just have experience with CakePHP and while it is magnifically built (given that it maintains compatibility with php4 and php5) it will never reach the whole expressivity and power that Rails has.

A quick example is the AppModel class. AppModel is the CakePHP's equivalent of ActiveRecord::base. In Rails, when you declare a model you just extend ActiveRecord. Simple as that; you don't need extra stuff in the middle. In CakePHP you need to extend AppModel, and if you want to modify AppModel in your application, you have to write a new AppModel.php - which cake will load instead of the default, empty one. Yes, AppModel is an empty class whose sole purpose is extending Model (which has the real ActiveRecord-like methods). That doesn't sound very flexible.

So at the end, AppModel is not more than a simple intermediate step for overcoming the limitation of php's inability to redefine the underlying class, that is, Model. We need to add an extra class in the middle for each level that you anticipate the user of your classes will want to redefine or extend.

Meanwhile, in Rails you would just add some code in the plugins directory with the new functions for ActiveRecord, and your models would still extend ActiveRecord::base. No extra levels of hierarchy whatsoever.

Another interesting example is the famous acts_as_taggable plugin, which allows programmers to add the ability to tag items (i.e. ActiveRecord models) just by adding a single line of code to the model (acts_as_taggable), using ruby's ability to reopen classes and add a series of new methods to existing models.

Even more, there are some Ruby core classes, like Date, to which Rails adds new methods, while they still belong to the Date object, not an artificial AppDate intermediate object in the middle, and without modifying Ruby's core files. Isn't it beatiful?

And before you discard my arguments as biased towards Rails, there are more languages which allow for classes to be reopened, like Javascript (and I believe ActionScript was like that before, don't know about ActionScript 3). These flexible languages have allowed people to write such amazing stuff as Prototype or Script.aculo.us, by making use of the redefinition and extension of existing classes.

So that's why I say that PHP is not flexible and will never have a real Rails-like framework :-)

Hope it's clearer now…

20061113 Beware of cakephp's requestAction!

We decided to start using database sessions instead of the usual php storage method, just to check if that would fix the extremely annoying problem of cakephp completely ignoring the maximum session time settings (no matter what setting did it have, it always logs out people after 20 minutes).

So seems that it worked, people could be inactive for a while and after that they didn't find a "You've been logged out" message. But it revealed a new problem: each requestAction was forcing the creation of a new Session object. And each time it is made, it generates like 3 or 4 queries. Which absolutely gave me the creeps when I saw the queries list!

I knew about the potential bad performance of requestAction, I had been warned, but I decided to use it for a couple of "blocks" because I couldn't believe it was going to perform so badly. I could cope with creating a new Dispatcher for handling the request, but those repeated accesses to Session objects are just plain terrible.

I'm impressed no one has noticed it already. It could be solved using a Singleton approach, just as they do with the ConnectionManager. It also could use some kind of cache since all the session functions are in cakephp's domain when you use the database session handler, so why does it need to query the database to retrieve something that was already retrieved 20 milliseconds again?

I finally removed all the calls to requestAction (by creating an instance of the model which was called by the controller and asking it the values directly, etc) and did a pseudo-cache of the session data in my code, and minimised as much as possible the calls to Session->read. While this is code optimised, it is not readability-optimised. It hurts my eyes to see this structure, it goes against nature and against MVC and against something else I can't recall now. Endless pain and agony! ARRGHH!

20061030 cakephpbb

So there goes the cakephp + phpbb integration - just commited the files to Subversion and uploaded a tgz package for the lazy ones, some hours ago.

And I don't know if there's expectation about the project or maybe it's just a malfunction in the stats system, but somehow it was one of the most active projects this week. How can it be possible if it was approved two days ago? But hey, it's nice anyway…

20061029 Load avg: 0.95

It's been a very busy week and it doesn't seem to go down, but surprisingly for most people, I quite like the feeling of being busy, since it doesn't allow you to spend the time procrastinating and thinking about the divine wonders of the Things That I Would Do If…

Among other things, past week mr.doob and me went to the London Flash Platform Users Group Meeting, or shortly lfpug meeting. It was very interesting and I went back home willing to get there soon to be able to download and install adobe flex builder 2 in my mac, as it had just been released that very day and was fresh and risky, as any beta version in this world :)

But I finally installed it yesterday and got almost aslept when trying to compile my simple "hello world" test. Or maybe I was already getting aslept and I thought it was because of flex builder, I don't know. I'll have a look at it later when I sort out more urgent things, I suppose…

We also got escena.org v2 in a usable status (or that I think), when I finally fixed the issues with the Spotlight section (thanks to a trace's suggestion, must recognise). I haven't talked here about the site yet because it doesn't have all the features we've planned for it, but will do when it's in a more advanced status. In any case it seems promising :-)

And in a different topic, just registered on Thursday for my first cakeforge project: cakephpbb, which aims to provide a way of integrating a cakephp application with a phpbb forum. It's something terribly simple, and in fact it has not entirely been developed by me, since it's a result of the collaboration of several people (more of a mash up than anything else). But I've been testing it and already fixed a couple of bugs, and I'm going to provide the documentation for it.

The project was approved yesterday but I won't add any file until monday or tuesday, when I finish the docs (otherwise nobody will be able to use it and it will be a useless project) and get to understand how the cakeforge backend works.

There's more interesting stuff coming in but can't be disclosed yet so you'll have to remain intrigued for a bit more… hope you can stand it :-P

20060806 Wrong location of mysql.sock?

I was trying to run bake script (for cakephp!) and it started complaining about not finding /var/mysql/mysql.sock - but why this path? I already had problems with mysql socket and ruby on rails. In that time, I was using xampp for apache, php and mysql, so the mysql socket was inside xampp folder and I could solve it thanks to ccm (see the post if you feel curious).

But past week I decided I was fed up with xampp and not knowing where are the things, and more specially, not having a working version of Apache with mod_rewrite, so I went for the hard way and compiled and installed all from scratch (apache, php, mysql). Then what happened is that mysql socket is now in /tmp/mysql.sock but for some reason cake (and obviously php) is looking for the socket in /var/mysql/mysql.sock. Why, I don't know - since the application I'm developing works perfectly (I presume that's because it's running in a virtual host and thus php doesn't try to connect with localhost but with http, as it believes that it's not localhost actually).

In any case, it's just bake which fails.

Well, it was just bake which failed, since I decided to solve it all quickly. Did it want a socket in /var/mysql/mysql.sock?

There you go! Open a terminal and…

cd /var
sudo mkdir mysql (if a mysql directory doesn't exist there)
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock

bye bye error! now enjoy bake!

This trick is maybe dirty but I'm fed up of running ./configure and friends. If you know why it failed before, you can leave a comment… and I'll appreciate it much :)