Thursday, September 30, 2010

I hate $this and array(...) ! [PHP rant]

$this->


I have no reason to hate the explicit reference to 'self' or 'this' object.

But it shouldn't be repeated everywhere all around the codebase, every single time!

Ruby:

@name = @first_name + ' ' + @last_name

Java:

name = firstName + " " + lastName

PHP:

$this->name = $this->first_name . ' ' . $this->last_name

Unnecessary typing, unnecessary duplication. I should create a shortcut just for typing "$this->"

array(...)


array(2, 3, 5) doesn't look so bad.

But when you're dealing with nested associative arrays (and it's quite common), it doesn't look very good.

$this->_voucher->setOptions(array(         'storeId' => 'voucherStore',         'storeType' => 'dojo.data.ItemFileReadStore',         'storeParams' => array(                 'url' => $router->assemble(array('controller' => 'index',                         'action' => 'vouchers-for-number', 'mobile_number_id' => 1)),                 'clearOnClose' => true),         'dijitParams' => array('searchAttr' => 'title') ));
Ruby and JavaScript nails the sweet spot here. As with Scala (on JVM).

Java (the language) is at least as guilty as PHP on this front and much worse hehehe.

Wednesday, September 29, 2010

Two code completion 'FAIL's with PHP

Note that _ denotes cursor.

#1


$user = Doctrine_Core::getTable('User')->find(1); $user->_
Code completion at this point should return all members of the "User" class, but we get nothing!

#2


$logger = Zend_Registry::get('Zend_Log'); $logger->_
It should provide a list of Zend_Log members, but... nothing!

So... it's not about dynamic typing vs static typing. It's more about type safety but maybe more accurately type awareness or simply type information.

The above probably also holds true with Ruby on Rails. (and it's probably the fault of Rails' super-flexible-dynamic design by nature)

Compare Cases with Type Information (or sometimes, Type Inference)


But very rarely heard in Java :

@Inject EntityManager em; ... em->_

You get full code completion above. And even at times when you get a dumb Object, you can always typecast to the type you know you want.

Rendering JSON Data for dojo.data.ItemFileReadStore - Zend Framework

Dojo library has dojo.data.ItemFileReadStore and dojo.data.ItemFileWriteStore which are convenient defaults for a simple data store.

However you still have to generate the JSON data from the server-side application.

Luckily Zend Framework has an utility to render JSON data to match dojo.data format called Zend_Dojo_Data class.

Here's an example usage:

    public function vouchersAction() {             $this->_helper->layout->disableLayout();             $this->_helper->viewRenderer->setNoRender(true);                          $vouchers = Doctrine_Core::getTable('Voucher')->findAll(Doctrine_Core::HYDRATE_ARRAY);             $data = new Zend_Dojo_Data('code', $vouchers, 'title');             header('Content-Type: application/json');             echo $data->toJson();     }

Disabling layout & view rendering for direct response output in Zend Framework

Sometimes you want to disable default layout & view rendering in Zend Framework, for example to output a JSON response.

The following bolded two lines do the job:

    public function vouchersForNumberAction() {             $this->_helper->layout->disableLayout();             $this->_helper->viewRenderer->setNoRender(true);             ...             $data = new Zend_Dojo_Data('code', $vouchers, 'title');             header('Content-Type: application/json');             echo $data->toJson();     }

Creating a module in a Zend Framework web application

Zend Framework MVC web application request dispatch mechanism is structured in modules (optional), then controllers, and finally actions.

You have to enable module support.

Then to create a module, use zf create module command line tool.

$ zf create module deposit Creating the following module and artifacts: /home/ceefour/zendapp/application/modules/deposit/controllers /home/ceefour/zendapp/application/modules/deposit/models /home/ceefour/zendapp/application/modules/deposit/views /home/ceefour/zendapp/application/modules/deposit/views/scripts /home/ceefour/zendapp/application/modules/deposit/views/helpers /home/ceefour/zendapp/application/modules/deposit/views/filters Updating project profile '/home/ceefour/zendapp/.zfproject.xml'

Then you can create controllers, actions, and view templates as usual.

Enable layout support in Zend Framework

Zend Framework application generated by Zend Tool doesn't support layouts by default.

Enabling Layout Support using zf Tool


Run on command line:

zf enable layout

Enabling Layout Support via application.ini


Edit application/configs/application.ini and add to the [production] environment :

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"

Enable modules in Zend Framework

After installing zend framework quickstart, I was looking for a solution to enable modules. Finally I found the solution, add the below line to your application.ini file
in the production environment:

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

Source

Developing PHP Web Application with Zend Framework - First thoughts

I've been doing some PHP Development with Zend Framework using Aptana Studio IDE in the past few weeks.

During the past year or so, my work was primarily with Java EE / Spring Framework and Ruby on Rails.

So, there have been some differences in experience.

Good things

  • It will work on my hosting. Zend Framework requires PHP 5.2, which most hosting nowadays already support.
  • Quick setup... that's the PHP project. The framework, not so...
  • Pretty good manual. The Zend Framework manual is pretty helpful, and comprehensive. It's not extensive or too detailed, but it shows how to do basic tasks. The rest, you still need the Internet and some good luck.

Bad things

I think there are more bad things than good things.

  • PHP 5.3 won't be supported... yet. Most hosting has not yet installed PHP 5.3 due to a number of reasons (laziness probably one of them). So, forget Doctrine 2 and functional programming/lambdas/closures. For example, as of 25 Sep 2010 DreamHost still uses PHP 5.2.14.
  • Insufficient code completion. NetBeans, Eclipse, and IntelliJ IDE have excellent support for Java code completion. In PHP, not so. There is only limited support for code completion, and that's only for PHP and HTML. For INI files, XML, and proprietary data structures (hierarchical associative arrays)... you have to scour the manuals/Internet/tutorials/etc. Same can be said for Ruby on Rails, though.
  • Zend Framework has a very steep learning curve, and difficult to setup as a full-stack framework. This is more the "feature" of Zend Framework than PHP. Zend Framework is not a Ruby on Rails killer, and will probably never be due to different philosophy. It's fairer to compare Symfony to Ruby on Rails. It's probably fairer to compare Zend Framework to Spring Framework. Comparing Zend Framework to Symfony is like comparing Spring Framework or Java EE to JBoss Seam. However, I can see why Magento Commerce chooses Zend Framework... It's very flexible. I can imagine it's harder to tweak Symfony or Seam to fit your app, but Zend Framework and Spring Framework are built to be tweaked, mix-and-matched.
  • Doctrine ORM has to be integrated in manually. This is both a good thing (flexible) and a bad thing (cumbersome). But it's a bad thing for me because I think it should be easy to use Doctrine by default, and also easy to remove it when not needed. I still haven't set up Doctrine "correctly" in my ZF application, I'm too lazy, and that's ZF's fault. Symfony has done a better job at this.
  • Lack of important view/action helpers. By default, using the FlashMessenger is tedious, since I can only access it via controller and has to pass it to the view. Why not a flashMessenger() view helper by default?
I'll post more thoughts later on as I go...