Any comments on SolarPHP and CakePHP framework?

Hi everybody,

SolarPHP ( ) and CakePHP ( ) are among the best and most actively developed PHP frameworks today.

Both have good design and more important, good documentation to get started.

Have you tried them? What do you think about their advantages and disadvantages?

Thanks in advance.

Hi McGruff – yes, Solar has tests in place, and there are many more to come. Every documented class is .phpt tested; you can find them in the “tests” directory of the package. :slight_smile:

(Full disclosure: I am the author of Solar <> and have never used Cake <>).

My own take on this would be that Cake is more closely related to Ruby-on-Rails, and strives to be nearly identical in features and implementation. It appears that Cake (like RoR) is for building applications in-place on individual systems, but I could be wrong there.

Solar, on the other hand, is more closely related to such projects as PEAR <> and Horde <> in that it is first a class library and second a framework. Granted, it’s still a framework, but the structure is based on a library approach. The Solar_App structure for applications is superficially similar to Ruby-on-Rails in some respects, but it is not a direct derivative.

In addition, Solar is geared toward easy distribution of applications once they are built, and sports built-in localilzation features. As such, you can build applications in-place on individual systems, but if you build them according to Solar conventions, it becomes very easy to distribute your application and its libraries on a PEAR channel. Adding translations for distributed applications is as easy as creating a PHP-array-based locale file.

One point on which Cake and Solar are very similar is that they both use PHP-based templates for their views. While Cake appears to use PHP directly, with helpers, Solar uses the Savant3 template system with plugins. I think the functional difference is minimal, but I could well be missing a benefit of Cake in this regard.

Solar is built for PHP5, is E_STRICT|E_ALL compliant, and is committed to unit-testing for all components (alhtough unit tests are only partially completed). I don’t know the status of Cake regarding these points.

I hope this helps to illustrate some of the strengths of Solar; perhaps Cake developers can contrast and highlight their own.

Whenever I look at new code the first question I ask myself is where are the tests? If someone is testing I think they probably know how to code. If they’re not testing, I think they probably don’t. Even if the app was otherwise well-written, it would be useless to me without tests.

I know this might sound elitist or arrogant but testing brings many real, practical benefits. Once you’re test-infected, working with un-tested code feels like trying to hit a target with a bow and arrow wearing a blindfold. The only way you know you missed your shot is if you hear a scream. But you’re never quite sure who it was you hit.

On the cake site, I found a mention of unit tests on the second or third page so I would have gone on to look at the code (if I didn’t already have a million other things to do today). I didn’t see any mention of testing on the Solar site - I might have missed it and I think the developer is planning to write tests for all the code.

I haven’t used cake for development, but I’ve poked around the source code; the framework has support for easy testing of the code you write, but there aren’t any tests for the framework itself.

Cake is rails like, but it’s not a port; there is some similarity in terms of features, but implementation wise, they’re quite different.

Very good; thanks for the correction. :slight_smile:

Cake was created for PHP4 and it does not generate warnings on E_ALL.

Portability is an important issue in Cake development too, but it’s aimed at installation of applications on production machines, rather than at being widely deployed via Pear or similiar mechanisms.

Cake’s initial aim was to enable commercial developers (like me) to create dynamic websites quickly and easily, and deploy them without hassle and with flexibility. Therefore it uses PHP4 but also runs on PHP5, it can be used with or without a correctly set document root and mod_rewrite, and while it ships with a set of its own OO database classes it can also use PearDB and AdoDB.

It’s not really a Rails clone, but most of the philosopy and conventions are taken directly from it. Learning Cake can be helpful in learning Rails – and vice versa.

By default, Cake gives you:

  • custom, nice-looking URLs with automatic pre-fixing of all the links and image paths for deploing applications in website subdirectories,
  • customizable, automatic mapping of requests to Controller classes, i.e. /item/preview/10 is mapped to an ItemsController->preview(10) call,
  • a Model class that allows for reading data from the database with methods like $person->findAll(“age > 18”, “name, phone”, “name desc”, “50”) that returns the results of an SQL query “SELECT name, phone FROM persons WHERE age > 18 ORDER BY name desc LIMIT 50” as an associative array,
  • a templating system that uses pure PHP and helper objects, i.e. $html->imgTag(‘logo.gif’, ‘Home’) creates an absolute-path image tag to [/application_url]/img/logo.gif with an alt text of ‘Home’,
  • form tags generators that are automatically filled with data, i.e. $html->inputTag(‘name’) is automatically filled with $this->data[‘name’] of the Controller object rendering the template,
  • integrated SimpleTest testing class and a framework to make testing very easy,
  • integrated CSSPP library for on-the-fly compression of CSS files.

I hope this helps you decide.

a Model class that allows for reading data from the database with methods like $person->findAll(“age > 18”, “name, phone”, “name desc”, “50”) that returns the results of an SQL query “SELECT name, phone FROM persons WHERE age > 18 ORDER BY name desc LIMIT 50” as an associative array,

You should in fact, be using the Query pattern for that I would think? Look on the Martin Fowler site for more on what this pattern is all about, as the approach that you’ve just gone and described is inflexible.

Also I suspect that the way you map the request to a controller, and it’s executable class method (that processes the request), ie

// ...
class Controller {
// ...
public function preview( $id /* the 10 in above example */ ) {
// ...

So that means that the class methods naming convention is dependable on the URL huh? Not very smart in my view :frowning:

Sorry, but I couldn’t use your framework, there are just too many faults in it’s design.

Actually, this is configurable, and is what the “routes” system is for. By default, the mapping is /controller/action/id, but it can be anything you want, and you can setup as many mappings as you want. The url is compared against each route, in descending order of priority, and the appropriate one is executed.

I think you’re being unfair; there’s often a direct correlation between flexibility and complexity, and the goal of frameworks like rails and cake is try to make things as simple as possible without sacrificing too much flexibility. I agree that cake’s ORM leaves a bit to be desired, but I can see that it would be good enough for many situations, and I definietly wouldn’t go as far as calling it faulty.

Unfair?? Who, me? Umm…

Well maybe if the separation is complete between the URL and the controllers, then fair enough but I’m not a fan of Ruby, nor Ruby on Rails, and since Cake is based on that, of course I’m going to have doubts :slight_smile:

I have doubts because Ruby on Rails has been designed and developed on one langauge, ie Ruby, and not PHP. If on the other hand, if you had designed and developed Cake based on PHP, then you’d have the full benifits of what PHP has to offer you, no?

Both Ruby, and PHP have their own strengths and weaknesses. As for the other point, I have to stand by it, as there is enough documentation on-line for you to make a complete refactoring, and proberly in doing so, a complete improvement.

But I admit that ORM is complex and is not something that can easily be tackled, and PHP at the moment does lack this tool/support :frowning:

The separation is complete to the point that you can use a single method to handle all the requests with a very simple route:

$Route->connect(‘/*’, array(‘controller’=>‘AllPages’));

All the routes would then be passed to AllPagesController->index() with parameters being slash-separated URL elements, so calling:

…would translate into an AllPagesController->index(‘reports’, ‘detailed’, ‘2005’, ‘07’) call. I would think that the routes system is one of the smartest things in Rails. BTW, the default route is nothing out of ordinary, it’s a simple:

$Route->connect(‘/:controller/:action/*’, array(‘controller’=>‘Pages’));

…where PagesController is the default controller, and ‘index()’ is the default action. The colons in front of :controller and :action inform the routing system that you want the contents of the particular URL element to be parsed into a variable in the $params array. The ‘controller’ and ‘action’ are magic names (i.e. they are used directly by the routing system), but you can add your own to automatically translate URLs into script execution parameters in $params ($this->params in the controller).

As for being derived from Rails – I think that the general concepts are similar in all programming languages and methods for solving web-related problems can usually be ported between different script languages.

I invite you to try Cake and take what you like from it.

As I said before, cake isn’t a port of Rails, it just borrows the philosophy and some of the features of rails. I’d say it does make pretty good use of what PHP has to offer, and the devs seem to know what they’re doing.

Having said that, I’m not sure I’d use the complete framework, as there are things I would prefer were done differently (the ORM being one of them), but you’re doing yourself and the developers of cake a disservice by dismissing it outright simply because you dislike ruby and/or rails.

Could you please elaborate why is that a bad idea? What’s, according to you, the problem with mapping directly an URL instead of any other cumbersome mapping? (I’d think it is actually a clever thing to do, but it’s probably due to lack of knowledge).

One problem I see with using that type of mapping is that once a url is spidered you don’t really wanna change it. That means that the way the mapping works has been “hardened” and can’t be changed. I don’t like the idea of creating method and method paramters names that are dictated by url parameters. I don’t know if it would cause any real problems, I just don’t like the idea. If I were gonna use the framework I think I’d definitely use the routing system.

That means that the way the mapping works has been “hardened” and can’t be changed.

It can’t be changed, not easily anyways. The chances are that you’d find you need to do a major overhaul of the framework to achieve something more flexible. That is what is bothering me… The framework flow shouldn’t be dictated to by an URL, or for that matter, the Request.

The URL can easily be abused, but I suppose with good design and security this could be countered, but I’m still not convinced.

instead of any other cumbersome mapping?

One approach that I’ve found that works, and is easy to implement, and I’ve since stuck with it, is to map to a hierarchy. I think that this is far more clever no?

I find this argument perplexing. Neither the URL nor the Request “dictates the framework flow” - the Router takes the URL and maps it into variables (that are essentially part of the Request) by the help of the mentioned Routes, returning the results to the Dispatcher that is free to act any way it finds fitting. I think you should find this to be not that different from what we had in the skeleton thread.

One approach that I’ve found that works, and is easy to implement, and I’ve since stuck with it, is to map to a hierarchy. I think that this is far more clever no?
Would you care to elaborate on that?


I’m afraid this thread is very old… the first comment that got me is built in localization… I’ve been using CakePHP for several years now and got my hands dirty with CakePHP 1.2. The most difficult scenarios I found for a newbie are figuring out how to properly map many-to-many relationships to the models, and figuring out how to add custom third party objects like PHPMailer.

Currently I got put on a project that was build in SolarPHP. I must say after using CakePHP’s i18n localization system, I was disappointed with having to go back to manually creating array strings for each individual controller. In CakePHP any text you want to localize you surround with a base-level function … __(“localize this text”);, run the command-line cake i18n and it generates a localization file that you can update using a windows tool called poedit, you can re-run without clobbering existing localization information. CakePHP + i18n + poedit for the localization WIN.

Third Party Objects:
In both frameworks, adding third-party objects (Salesforce PHP API, PHP Mailer, Captcha components for example) require you to create an object within the framework and instantiate the third-party object within it for use. I found SolarPHP’s approach much simplier as its basically an object with a special class name. There’s a bit more plumbing if you want to accomplish the same thing with CakePHP.

Folder Organization:
CakePHP has a clear separation between its “cake” class folder and your “app” folder, and everything is clearly separated into model, view, controller as you’d expect. SolarPHP’s app folder contains the controllers, views, locale files, but the models are on the same level as the app folder and the global controllers… source folders, config folders also confusing… in general the file structure of SolarPHP isn’t as organized as CakePHP’s.