PHP’s function naming and argument order

Geplaatst in PHP, Webdevelopment Reeds 3 reacties

Just got back from PHPVikinger, a unconference, traveling around the world, organised by Derick Rethans. This year’s conference was held in Leuven, and since that is only a 30 minute drive from where I live I had to attend ofcourse.

For the summary of the event itself I’m happy to point you to Jeroen’s blog but I’d like to talk about something Stefan Koopmanschap brought up during Scott’s and Derick’s session on the PDM.

During the Q&A Stefan asked why the developers of PHP didn’t grab the opportunity to clean up the seemingly random and sometimes messed up functionnaming and argument ordering in some of PHP’s internal functions. Stefan by far isn’t the first one to bring this issue up, there are dozens of people reporting and asking this on the mailinglist and even filing bugs for it (with questionable degrees of success) but he did make a very valid point by stating that the release of PHP6 is the moment of choice to introduce these kind of changes in the core functionality of the language.

Function Naming

So what is this all about? Well really, as much as I love PHP, in several area’s it’s a mess. Especially in function naming.
Take the isset() function for example. Why is the is_null() function written with an underscore, these functions seem to me like they belong together since they both inspect a variable and return true or false if the state of the variable is as the function requested. Well then why is is_null written with an underscore and isset not? Doesn’t really make sense unless you want to confuse people.

Another example is the htmlentities() function, this function encodes some characters in a string with their entity value, the function that does the exact opposite is called html_entity_decode(). Again one is written with underscores, the other without. And again without an obvious reason.

Other examples are all the string functions, there are a dozen function that start with str_ and alot more of them that just start with str.

Argument order

Another issue is argument order. There are several functions that seem rather random in the way they order arguments. Especially function that required needle/haystack arguments.

String functions, like strstr() for example, accept $haystack as a first argument and $needle as a second while array function like array_search accept them in the reverse order. It just seems counter intuitive to me.

PHP 6

What disturbs me the most was the reply Scott and Derick gave Stefan at the conference, their reply simply was that it won’t be fixed because otherwise a lot of developers would be upset about the changes and lacking backwards compatibility.

Well they have a valid point there … if you’d consider fixing it in a minor version upgrade like from PHP 5.2 to 5.3. But if we are talking upgrading from PHP 5 to PHP 6 I’m absolutely sure the majority of PHP developers wouldn’t mind giving up backwards compatibility in exchange for fixing these issues. Over time the amount of functions in PHP really isn’t going to decrease so I’d prefer to have it fixed before it really runs out of control. But who am I?

I hope that with this blogpost I’ve inspired some people to think about this subject too and maybe undertake some action and write about it on their blog or twitter it since this isn’t something that is going to change unless us, PHP users, are asking for it and making the PHP core developers aware of these issues and that fixing them is important to us.


Oracle koopt Sun Microsystems

Geplaatst in Applicaties, Internet, Webdevelopment Nog geen reacties

Het moest me even van het hart maar ik weet nu niet of ik blij moet zijn met de overname van Sun door Oracle of dat ik er bij moet beginnen te huilen?

Door deze overname krijgt oracle niet alleen Java (en NetBeans), maar ook Solaris, VirtualBox, Open Office én MySQL in handen. Als dat geen joekel van een investering is dan weet ik het niet. Dat heeft den Larry weer goed geregeld zou ik zo zeggen. Het is ook niet zo gek dat het bestuur van Oracle de overname unaniem heeft goedgekeurd.

Ik denk en hoop dat Microsoft zich stilaan serieus zorgen begint te maken. Google blijft hun steeds een stapje (met een zevenmijls laars) voor op het internet en op het niveau van besturingssystemen beginnen de verhoudingen ook steeds meer en meer te kantelen. Er zijn steeds meer mensen die overschakelen van Windows naar Mac of een ander OS zoals Linux.

Als we de productportfolio van Sun even bekijken dan zie je al direct 4 direct concurrerende producten van Microsoft;

  • OpenSolaris vs WindowsServer
  • Java vs .NET
  • OpenOffice vs Microsoft Office
  • VirtualBox (xVM) vs VirtualPC (VirtualServer)

En wat gaat er met Open Office gebeuren? Als Oracle zijn schouders onder het project zet wordt het eens te meer een zware concurrent van Microsoft Office, want laten we eerlijk zijn, waarvoor jij en ik office gebruiken hoef je geen €600 neer te tellen, hetzelfde bereiken we met sprekend gemak ook met Open Office. Het enige wat me dan misschiens nog een beetje tegenzit in Open Office is een compleet alternatief voor Outlook. Dat Oracle daar dan maar mee begint, dan hebben ze er al één klant bij … als ze met hun fikken van MySQL af blijven tenminste :)


Dojo Dijits in Zend_Layout

Geplaatst in PHP, Webdevelopment, Zend Framework Reeds 8 reacties

A quick tip on using the Dojo implementation in Zend Framework.

Yesterday I was trying to put a borderContainer on my application. Following the code samples in the manual I had it set up pretty fast in my View, but since all pages should utilize this it seemed normal to me that I would integrate this in my Zend_Layout instead of each View separately.

Thus I moved all the code to my Zend_Layout and tada … no more Dojo, it just stopped working. The code below is the (simplified) code of my Zend_Layout at that time.

< ?php
$this->headTitle()->setSeparator(' :: ');
$this->headTitle()->append('Skyrocket Admin');

echo $this->doctype() ?>
<HTML xmlns="http://www.w3.org/1999/xhtml">
<head>
	< ?= $this->headTitle() ?>
	< ?= $this->headLink() ?>
	< ?= $this->headStyle() ?>
	< ?= $this->headScript() ?>
	< ? $this->dojo()->setLocalPath('/admin/scripts/dojo/dojo.js')
	                ->addStyleSheetModule('dijit.themes.tundra');?>
	< ?= $this->dojo() ?>
</head>
<body class="tundra">

< ?
// Load the Dojo helpers
$this->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');

// The page layout is a borderContainer, the views
// get rendered in the Center pane
$this->borderContainer()->captureStart('masterLayout',
                                       array('design' => 'headline'),
									   array('style' => 'width: 100%; height: 100%'));

	$this->contentPane()->captureStart('leftPane',
	                                   array('region' => 'left', 'splitter' => true),
									   array('style' => 'width: 200px'));
		?>
		<ul id="navigation" style="margin: 0">
			<li><a href="/admin/pages">Pages</a></li>
			<li><a href="/admin/auth/logout">Logout</a></li>
		</ul>
		< ?
	echo $this->contentPane()->captureEnd('leftPane');

	$this->contentPane()->captureStart('contentPane',
	                                   array('region' => 'center'));
		echo $this->layout()->content;

	echo $this->contentPane()->captureEnd('contentPane');

echo $this->borderContainer()->captureEnd('masterLayout');

?>
</body>
</html>

Back then it was almost 2AM so I didn’t feel like going after the solution. I dropped a post on Zfforums.com and went to sleep. Today on the other hand I felt like digging through the classes that are responsible for creating the dijits and it didn’t took too long to realize what was wrong.

The problem lies in the order of execution, the Zend_Dojo_View_Helper_Dojo class is responsible for outputting the javascript code that converts your basic html elements into Dijits. But in the code sample above I was outputting the dojo() helper before I was actually creating Dijits. Thus the HTML elements got created but the javascript code to convert them into Dijits is never outputted.

The solution is to simply move all your dijit creation code to the top of the page or to move the output of the dojo helper to the bottom. My advice is using the first option, simply because if you output it at the bottom you get to see the un dijitized html for a brief moment which is not nice.

Here is the working code for the borderContainer Layout in a Zend_Layout

< ?php
$this->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
$this->dojo()->setLocalPath('/admin/scripts/dojo/dojo.js')
		     ->addStyleSheetModule('dijit.themes.tundra');

$this->borderContainer()->captureStart('masterLayout',
                                       array('design' => 'headline'),
									   array('style' => 'width: 100%; height: 100%'));

	$this->contentPane()->captureStart('leftPane',
									   array('region' => 'left', 'splitter' => true),
									   array('style' => 'width: 200px'));

		if (Zend_Auth::getInstance()->hasIdentity()):?>
		<ul id="navigation" style="margin: 0">
			<li><a href="/admin/pages">Pages</a></li>
			<li><a href="/admin/auth/logout">Logout</a></li>
		</ul>
		< ?
		endif;

	echo $this->contentPane()->captureEnd('leftPane');

	$this->contentPane()->captureStart('contentPane',
									   array('region' => 'center'),
									   array());

		echo $this->layout()->content;

	echo $this->contentPane()->captureEnd('contentPane');

$data = $this->borderContainer()->captureEnd('masterLayout');

$this->headLink()->appendStylesheet($this->autover('/admin/css/style.css'));

$this->headTitle()->setSeparator(' :: ');
$this->headTitle()->append('Skyrocket Admin');

echo $this->doctype() ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	< ?= $this->headTitle() ?>
	< ?= $this->headLink() ?>
	< ?= $this->headStyle() ?>
	< ?= $this->headScript() ?>
	< ?= $this->dojo() ?>
</head>
<body class="tundra">

	< ?= $data ?>

</body>
</html>

I hope this helps at least some of you out, and if there are any questions or remarks i’d be glad to hear them!


Admin CMS routes in Zend Framework

Geplaatst in PHP, Webdevelopment, Zend Framework Reeds 10 reacties

For some time now I’ve been pondering on how to implement a CMS in the websites I build using Zend Framework, there are several options available around the internet. Here I’m going to explain how I solved this issue and why this is my preferred way of working.

No custom routing for me sir

One of the solutions I found involved creating a separate module for each part of your website that requires administration (eg: news, blog, products, …). Then you can easily access the admin for each module. For example to access the news admin you would point your browser to domain.com/news/admin.

At this point this solution has one drawback and that is the URL structure, while for some people this doesn’t really pose a problem, I always like to have the part that identifies the CMS as first part of my URL. domain.com/admin/news instead of domain.com/news/admin. You could however solve this by creating some routes, but I still didn’t feel happy about this solution.

While this might be a good solution when you are building a CMS with plug-and-play modules where all code is contained in one module, this solution wasn’t really what I was looking for. I would rather have all my CMS code close together, preferable in a separate environment from my front-end website.

Modules

The solution I found most suited and flexible to use was creating a separate module for both the front-end and the back-end. This allows you to separate your business code from the CMS from your front-end while still being able to use common models for data access and manipulation.

The automatically registered Zend_Controller_Router_Route_Module route takes care of routing the request to the appropriate module or to the default module if no module has been specified.

My directory layout looks something like this.

Admin module directory Layout

You are ofcourse free to use whatever layout works for you, the most important part is that you have at least a frontend and admin module.
You’ll also notice i’ve split up the public directory to separate the public assets for the admin and frontend modules, keeps everything nice and tidy.

Next up is configuring the Front Controller to use modules which is quite easy.

$frontController = Zend_Controller_Front::getInstance();
$frontController->addModuleDirectory(APP_PATH.'/modules');
$frontController->setDefaultModule('frontend');

In the code above we tell the Front Controller where to find the modules and which module to use when none has been specified in the request or when none is found. Pretty basic and it works!
Just put all your CMS specific controllers in the admin module, and all front-end controllers in the frontend module.

But wouldn’t it be nice if we could also separate our Zend_Layout’s, so we have a separate layout for our front-end and admin area’s and the files for these are contained in the respective module directories? This is where Controller plugins come in handy.

/**
 * Controller plugin that sets the correct paths to the Zend_Layout and
 * Zend_Controller_Plugin_errorHandler instances
 *
 * @package    Skyrocket_Plugin
 * @copyright  Copyright (c) 2005-2008 Skyrocket Concepts (http://www.skyrocket.be)
 */
class Skyrocket_Plugin_Adminsetup extends Zend_Controller_Plugin_Abstract
{
	public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
	{
		// Set the layout directory for the loaded module
		$layoutPath = APP_PATH . '/modules/' . $request->getModuleName() . '/layouts/scripts/';
		Zend_Layout::getMvcInstance()->setLayoutPath($layoutPath);

		// Configure the error plugin to use the loaded module
		// so we can use module-specific error handling
		$frontController = Zend_Controller_Front::getInstance();
		$errorPlugin     = $frontController->getPlugin('Zend_Controller_Plugin_ErrorHandler');
		$errorPlugin->setErrorHandlerModule($request->getModuleName());
	}

}

Create a class file like the one above and register the plugin instance with the Front Controller like this:

$frontController->registerPlugin(new Skyrocket_Plugin_Adminsetup());

The Adminsetup plugin intercepts the request before the Front Controller dispatches and modifies the Zend_Layout path to the current module’s Layout directory. It also registers a separate error handler for the admin module in case you want to handle your errors separately from your front-end errors.

What if I still want to use modules for my front-end?

I can hear some of you asking: But what if i’m building a huge website, with a huge amount of business logic? This is what modules really were made for but you are forcing me to use only one module for all my front-end controllers? Does this mean that I should stuff all the code for my forum in one gigantic controller in my frontend module?

No, not really, you still are free to use modules as you please. Feel free to create a forum module with a TopicController, ForumController, PostController and a CategoryController. These modules still work as expected and are accessible via domain.com/forum/topic

Conclusion

See, no funky routing configuration, no numerous admin controllers spead out over dozens of modules, all your admin controllers and layouts are nicely contained within one admin module and you are still able to separate all your code in individual modules or all into one frontend module. The choice is yours.

That’s it for now folks, any remarks, questions or do you think you are using a better method, feel free to comment.


Overschakelen op ubuntu

Geplaatst in Applicaties, Webdevelopment Reeds 3 reacties

Terwijl Jan de overschakeling naar Mac aan het doen is heb ik thuis de beslissing genomen om op Linux, meer bepaald Ubuntu, over te schakelen.

Niet dat ik niet tevreden ben van Windows XP, er zijn de kleine frustraties van windows maar in vergelijking met Vista ben ik nog steeds zeer tevreden van XP. Maar linux lijkt me echter een zoveel betere omgeving om webontwikkeling in te doen dan Windows dus is de beslissing snel gemaakt. En extra kennis van linux is mooi meegenomen, ik kan mijn plan wel trekken via SSH maar vlot gaat toch anders, maar daar komt zeer binnekort verandering in dus :)

Installatie ging erg vlot, Ubuntu downloaden, op USB stick zetten en installeren is een kwestie van een kwartiertje werk. En alles werkt vlot, drivers worden herkend, netwerk en internet werken out of the box, wat wil je nog meer? Ontwikkeltools natuurlijk!

En daar komt Apt in het spel, eclipse installeren is een kwestie van de terminal open gooien en apt-get install eclipse uit te voeren en even later is eclipse klaar voor gebruik. Apt is zeker en vast de grootste meerwaarde voor Ubuntu. Daarna de Aptana plugin voor eclipse installeren en de IDE is klaar voor gebruik.

Een dev server installeren gaat even makkelijk, apt-get install apache2, daarna svn, php5, MySQL en phpmyadmin nog, een paar virtual servers aanmaken in apache en de ontwikkelomgeving is klaar.

Nu Zend framework nog downloaden en we kunnen beginnen!

Linux, i’m starting to love it :)