A Tale of PHP IDE’s

  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 40.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 41.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 42.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 43.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 44.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 45.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 46.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 47.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 48.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 49.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 50.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 51.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 56.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 57.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 58.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 59.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 60.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 61.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 62.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 63.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 64.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 65.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 66.
  • warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Denver' for 'MDT/-6.0/DST' instead in /home/lyniqne/public_html/planetcakephp.org/drupal/sites/all/modules/token/token_node.inc on line 67.

I have been an Ecipse PDT user for the last couple of years, and while I have gotten it to “work” with CakePHP, I have always found it a messy solution, as you have to “hack” up your sources pretty good in order for Eclipse to understand the CakePHP world.
While this does work, it is not a pretty solution, is not easily manageable, and leaves a bad taste in my mouth, so I figured that there must be a better way…and there is with Netbeans !

So, off I go again seeing if there are any new developments in the PHP IDE arena these last 6 months or so, and what do I find…Netbeans for PHP. Because I have tried almost every other PHP IDE on the planet, but have never tried Netbeans (since it never really had good PHP support until recently)…I decide that this will be the week.
As I am downloading and installing the thing, I start browsing around to see if there are any tips for CakePHP integration. About 30 seconds later,  I find something – and it looks promising.
So, I load up my usual test project, make some modifications to the source’s comments so that Netbeans understands the Cake world, and what can I say – I was really, really, really floored. This worked MUCH better then anything I had ever used before – much, much better then I ever had with Eclipse, in a much cleaner, and more manageable way.
Before I start talking too much about Netbeans, let me just cover the issues that I had with Eclipse’s code completion with CakePHP. To get Eclipse to understand that $this->Model in your controller was a model, you had to add something like the following to your controller:
/**
 * @var ModelName
 */
var $ModelName;
Now, this doesn’t seem like a big deal at first, but once you realize that you have to do this for every component, helper, model that your controller uses, it gets a little nasty. Now, let’s just say that our $ModelName model has multiple relationships with other models. The CakePHP way is to access them as such:
$this->ModelName->OtherModel->find();
So, Eclipse knows about ModelName, and we have code completion for that. But it knows nothing about ModelName->OtherModel…no code completion, we are stuck. So off we go again adding more comment blocks to try and manage Eclipse.
Now, again, you multiply this by all of your application models, and you end up with a mess pretty quickly. This even gets worse.
For components, cakePHP uses a component array to define which components your controller will use. Let’s say that I have some core components that I will use in every controller. Instead of loading them up manually in each and every controller, it makes more sense to load them up in my AppController, where all the other controllers are derived from.
So, in your AppController you start adding the Eclipse @var code blocks for all the components so that Eclipse can figure out the code completion, and it works great… in your AppController at least. Next you open one of your other controllers and start typing $this->ComponentName->….and nothing. No code completion again!! Eclipse, for whatever reason, can’t code complete an inherited @var comment block. Maybe I just did something wrong, but this never really worked well at all for me, at least not consistently.
Ok, so how do you get it working…well, you have to include the stupid @var comment blocks in each and every controller that you want code completion for…this is insane and is a complete mess.
You do this for all your Model’s, all the Model relationships, all the components, and then count how many lines of code in your entire project that was added just to make eclipse’s code completion work…it’s a lot. A lot of code, a lot of redundancy, and when you have to change things, it’s a lot of new code to add – simply stated, it’s a lot. Too much if you ask me.
Ok, so now I have talked about how all the Eclipse hacks are messy, how does Netbeans compare?
At first Netbeans seems to use a very similar method for helping it understand CakePHP’s world. You use @property javadoc comments in the codeblocks just before the class’s declaration, like so:
/**
 * @property ModelName $ModelName
 */
Class ModelNamesController extends AppController {}
So, now you have a single @property javadoc comment to tell Netbeans that $this->ModelName refers to the ModelName model for that controller, and code completion works great. So far so good.
At least this is just a single comment line, and I don’t need to declare a useless variable like I have to do with Eclipse. With Eclipse, I would have a comment block consisting of at least 1 line, but possibly 3 lines (/**, * @var, */) depending on the project’s source code formating policy, and then the actual useless var $name line. That’s either 2 or 4 lines of code to do Netbeans’ 1 line of code. That’s at least a 50% improvement, not bad at all.
What about $this->ModelName->OtherModel-> code completion support? How do I get that to work?
Well, this is where Netbeans really starts to show it’s power. In the comment block that is just before your Model declaration, just add the same @property for each model that it has a relationship with. Example:
/**
 * @property OtherModel $OtherModel
 */
class ModelName extends AppModel {}
That’s it. Again, a single line of code for each relationship that this model has. The best thing about this is that Netbeans, unlike Eclipse, properly understands inheritance when it comes to the @property javadoc comments. As soon as you do this in your Models, all of a sudden, in your controller, $this->MyModel->OtherModel-> has code completion…awesome. This never worked well with Eclipse, and I just got rid of a TON of code duplication all over the place with @var comment blocks to try and get Eclipse to work. Now I am really happy, as this is much more then a 50% improvement…
Now, what about components? Well, components are exactly the same thing. In my AppController’s comment block that is right above it’s class declaration (for all the common components that every controller uses), you just add an ‘@property ComponentNameComponent $ComponentName’ line for every component that you want to use. Again, because Netbeans understands inheritance with these @property comments, they work in every controller – immediately. Wow.
Ok – now I am in heaven. I can get rid of all of these silly @var’s all over the place, which already cleans up the code a lot, and have a much cleaner, and controllable method of telling Netbeans about the CakePHP world.
At this point, I wanted to see how helpers in the views could get code completion, and this works pretty much exactly like Eclipse, so they are the same when it comes to helper code completion support. All you need is a file in a include directory, or somewhere in the “project” that has something like:
<?php
exit();

//this file does nothing, it's just so netbeans can code assist any of these
//objects in all our views

$ajax = new AjaxHelper();
$form = new FormHelper();
$html = new HtmlHelper();    
$javascript = new JavascriptHelper();    
$number = new NumberHelper();    
$session = new SessionHelper();    
$text = new TextHelper();    
$time = new TimeHelper();    
$pagination = new PaginationHelper();    
$rss = new RssHelper();    
$xml = new XmlHelper();    
$number = new NumberHelper();
$paginator = new PaginatorHelper();
?>
As long as Netbeans (or eclipse for that matter), can see this file, you get code completion for helpers in all your views. This is an OK work around, and I have no issues with this method.
Netbeans also has some really nice features out of the box:

  • awesome refactoring support – very cool stuff (look into Ctrl-R)
  • searching with very cool “diff” like displays for all matches in the scrollbar area
  • great CSS code completion
  • awesome javascript support
  • support for multiple language code completion in a single file (ex: css -> javascript -> php)

You add all this up, and I think that it will take a major problem Netbeans to get me back over to the Eclipse camp.
It is at least as good as Eclipse in most areas, and has a much cleaner and easier way of setting up code completion for PHP frameworks. It is also a no hastle-everything just works- installation, unlike Eclipse where you have to download a bunch of add-ons after you get it so that it can do the things you want…that’s if you remember which update site was needed to install the add-on…..that’s also a mess – but let’s not go there right now
The Netbeans add-on’s are more along the lines of Jedit, where you have a single section in Netbeans to view all “stable” add-ons, and you can install them within Netbeans. No browsing around for a while trying to find something and figuring out how to install it like you have to with Eclipse. You can also download alpha/beta add-ons from the netbeans.org site easily, which then you can install them in netbeans with a couple of clicks. I think this is a much better way of handling add-ons.
So – I think I am a Netbeans convert…if you haven’t used it before, I think it deserves a shot.
If you have had similar (or dissimilar) experiences with Netbeans, I would love to hear your comments