Symfony2: New generation PHP autoloading

There is an article on the state of autoloading in PHP frameworks which says that in new frameworks the use of namespaces is a step backwards to the days of require_once littering the top of files. I disagree with this for the following reasons.

IDE handling

After giving some advantages, the article then says that the overriding disadvantage is the maintenance of the use statements as the top of the file, claiming that this will require finding the class in the directory structure and copying and pasting the namespace.

I have found that Eclipse’s autocomplete will find the class for me and automatically insert the use statement if needed so this is just not an issue if you are using Eclipse. I’m sure it will be similar for Netbeans and other proper IDEs. If some editors do not not support this then it is surely an issue with that editor rather than a reason why namespacing should not be being used effectively in PHP frameworks.

It’s only shorthand

You do not need the use statements at all if you do not want them, just use the full namespaced version. Other then syntax this is no different to the previous generation of autoloading with long class names that effectively contained the path. So PathToClassClassName rather than PathToClass_ClassName

Use Dependency Injection anyway

The article single Symfony2 as a new generation framework in which this is an issue. In Symfony2 there is an excellent Dependency Injection container. If you use this there is no need to be autoloading classes in your code anyway, use DI to pass them in and then the only need for the class paths and use statements will be for type hinting the injection point, which is optional anyway.

Symfony2: Getting Started

A quick post on a couple of issues I had getting started with learning Symfony2.

I have started by downloading the Preview Release 8 Symfony Standard edition from http://symfony.com/download. My intention is to start working through the book. My first hurdle was working out what to set the document root in the vhost file to in order to just get it started as this does not seem to to be clearly documented. After looking in the downloaded files it looks as though it needs to point to /path/to/app/AppName/Symfony/web which means I now get the welcome page at /app_dev.php

I had some issues getting started with the very basic application – on the Page Creation page it says to delete the demo bundle if you downloaded the standard application. I did this, it then broke so that I cannot recreate it using the CLI tool. As advised I tried to run:

but was getting the following error:

Commenting this out:

in the file in the error message got around this error. I now instead was getting this PHP Fatal error

It was much less obvious how to fix this one. I had to comment out all of these lines

in /path/to/app/AppName/Symfony/app/config/config.yml

The command would then run and the demo bundle was created and I could continue working through the book. I think this is an issue with the documentation but since Symfony2 is only at PR8 then the documentation is a work in progress and will no doubt be improved by the time there is a stable release.

Symfony2: First Site

As per my last post I am going to have a look at Symfony2. I intend to recreate a non production version of the new Lime Thinking site.

This means recreating the following features of the Lime Thinking site:

  • Static content for many pages but with common overall view.
  • CMS pages for testimonials and projects, needs an admin section, with publishing articles rather than live editing.
  • Plugin views for testimonials, projects and right hand side view to come from the CMS content.
  • Search including indexing, retrieval and auto search, which requires generating JSON responses.
  • Collecting messages and sending them as emails via the database.
  • Error page on exception for user but with exception logged and a notification emailled.
  • Custom 404 page with search
  • Management of CSS and JavaScript files – combining and minifying/packing mutliple files, as well as dealing with versioning for caching purposes.

This is not a very complicated project and doesn’t try and test Symfony2 to its limits or try and use everything it can do, but it is a real world project, none of these features are artificial. My intention is to start looking at the Symfony 2 “book” and to get going and to the try to recreate the Lime Thinking site. I am going to post on my way on any interesting features, gotchas and anything else I think may be useful as I go. This series of posts is not intended to be a guide to getting started with Symfony2 since I am only just doing that myself but hopefully it will prove useful to anyone else in a similar position.

Symfony2: A First Look

I am going to take a look at the Symfony framework and write up my experiences as blog posts. Specifically I am going to look at Symfony2 which is a major rewrite from Symfony. At Lime Thinking we currently use our own framework LimePickle with some use of elements of Zend Framework.

We started developing our own framework out of out libraries of reusable code back before the emergence of the now ubiquitous PHP frameworks. Despite the arguments for using these over rolling your own, many of them are only applicable if you are starting from scratch. We have been reluctant do jump ship to one of the available frameworks when he have developed a lot of tools for working with our framework. Many of the other frameworks do not meet some of the requirements we place on our own code when it comes to development best practices such as unit testing, dependency injection, minimal usage of static methods and classes such as singletons. Especially whilst we have been able to leverage use of individual Zend Framework components without fully committing to using its controllers, views and models.

So why am I looking at Symfony2? Of interest with Symfony2 is its use of dependency injection, as converts to the benefits of this and having implemented it ourselves we would not want to lose this. Also is its use of Doctrine2 as its Object relational mapper (ORM), Doctrine2 uses a Data Mapper approach to this rather than the typical PHP Framework use of Active Record which is a great step forward. Whilst we have implemented a similar approach with LimePickle, Doctrine2 implements more of the excellent ideas of PoEAA then we currently do. I would like to implement Doctrine2 as the ORM for LimePickle but think the learning curve will probably be shallower if I learn to use it as intended with a Symfony2 project than working out how to integrate with LimePickle

So I intend to create a non production project using Symfony2 and see how it compares to using LimePickle to do so. I may repeat the process with other frameworks as well. Does this mean we plan to move away from LimePickle? We are not ruling out the possibility if Symfony2 proves itself to be excellent. I think at least it will be a good experience in implementing a project in a different way from usual and I will learn some new techniques that can be used to improve LimePickle.

CSS Organisation – Variables

In the previous post in this series I wrote about organising rule sets in CSS and came to the conclusion that it would be best not to try and avoid all repetition. This means that there is some additional maintenance to be done when changing values that appear in several places. In this post I will look at at the unsophisticated method I use to make this easier as well as a brief mention of some of the other more heavy duty solutions available.

My Solution

In the first post in this series, I discussed having a “table of contents” at the top of the CSS file. Below this I place a list of values used in multiple places in the document, which look something like this:

This provides an easy reference point when adding a new rule which needs to use these values. This also allows for easy find and replace if a value needs to be changed.

Next Step

At Lime Thinking already do some PHP processing of CSS before serving it, for example running it through a minimiser, combining multiple file into one file to reduce HTTP requests. Since we are doing this, we could also use PHP to do some basic variable replacement, the above list could be made to look more like the following:

If the “variables” such as $backgroundGreen are then used in place of the variables in the CSS file, then PHP can be used to find and replace them with the relevant value. This would further reduce the maintenance of the CSS file, although at the step of moving away from having a CSS file that only uses CSS syntax and which can just be applied to a page without the processing.

Heavy Duty Solutions

A similar but more fully featured approach is already available in various CSS frameworks, which amongst other things provide support for CSS variables. These include

These CSS frameworks provide more than just variables, with features such as nesting selectors, mixins, selector inheritance. Whilst these may solve the issue at hand along with several others, there is a learning curve involved with any new tool like these. Much of what they provide appeals to me as a programmer but I can’t help feeling that they seem like overkill. I have not fully investigated using one so far but may do at some pint in the future. Personally I have never thought that it was worthwhile learning a completely new syntax to solve some of the annoyances of CSS but then I am not writing CSS all day every day.

Real CSS Variables

There has been discussion over the years about introducing variables directly into CSS, there are many opponents to this though, citing the difficulties of doing so, e.g. dealing with multiple decelerations of the same variable in different files that are all included or imported. Additionally the fact that CSS does not contain variables and other programming devices such as if, then branching, is seen by many as a positive thing which allows easy adoption by non-programmer designers and moving away from this would be to its detriment.

Even if there was agreement on the issue, the speed at which new CSS specifications arrive and at which browser developers implement them mean it would be a long wait before they were available in practice.

Conclusion

In the cases of PHP and JavaScript I think the use of frameworks is beneficial in removing a lot of hard work, I am not going to enter into the arguments here though, apart form to say that many of the arguments that apply to them are just not true of CSS. Learning a framework for JavaScript or PHP does not require writing using a new syntax as it does with many CSS frameworks. It feels that whilst it has its annoyances CSS is just not doing something complicated enough to require this additional level of complexity. The simple method I suggested first seems more in keeping with the simplicity of CSS than some of these other solutions.

CSS Organisation – Grouping Selectors

In the previous post in this short series on CSS I wrote about splitting CSS files into sections. Whilst this is a simple technique, the choice of how to group is more difficult though, sometimes the most obvious groupings into different areas of the page will lead to duplicating rule sets where the selectors could have been combined. For example you may end up with the following:

We could of course combine these as this:

This definitely appears to be better as we are no longer repeating ourselves and means that should we want to change the colour of these headings then it only needs changing in one place. This no longer fits into either of our sections above but we could just introduce a HEADINGS section.

Whether this is more or less important than the clear grouping is really a matter of personal preference and some pragmatism. It makes sense to avoid repeating yourself but ending up with a lot of single rule declarations with a lot of selectors for each can be much less readable than grouping all the rules for each selector together. This shows rules for three different selectors grouped by the selector.

There is however some repetition of rules so you may feel that this not the optimum way to write these rules. Trying to eliminate this altogether is not the best policy though, in my opinion, as it would leave you with this:

Whilst the repetition is removed it is now, I think, less readable. Admittedly if you want to change the text colour for #intro and #footer then it only needs doing it one place, however, if you need to change only the colour for #intro then quite a few changes are needed.

The main disadvantage to this approach though is that it makes difficult to group the rule sets into effective sections making the overall file more difficult to organise. In the example I have had to group them altogether as rules for paragraphs, this means that these rules have been separated away from the others for that section of the page e.g. the footer paragraph rules are no longer with the footer headings rules.

My personal preference I think would be to pull out the rule for the width only as this appears for all of the selectors is most likely for the value to be changed for all of the selectors if it is changed. This would leave you with the following:

This is a good compromise between the two previous examples. Whilst there may be some additional steps when changes are needed compared to the second example, the increased readability outweighs this.

jQuery: IE8 bug when adding a Form

Quick version

I found a bug in IE8 when adding a form to the DOM using jQuery, fortunately there is a simple solution, unfortunately it took a while to stumble upon it.

Background

Whilst implementing a new in-page contact form for limethinking.co.uk I ran into a bug with Internet Explorer 8. Unexpectedly though it worked absolutely fine in IE 6 and 7, which does not happen very often so not working in 8 came as a rather unpleasant surprise.

The background is that the HTML for the new in-page contact form is fetched using Ajax so that a security token can be generated for it rather than it being part of the static HTML, it is not wanted for non-JavaScript users either who get the normal contact page. I was using jQuery to make the Ajax request and to append the returned HTML to the document using code similar to this simplified version:

The form was being added fine and its submit action called fine in Firefox, so I tested in the IEs, against expectations it was fine in 6 and 7 but in IE 8 the form was not displaying correctly, this appeared to be a quickly remedied CSS bug, but then rather less easy to fix the submit action would not work. After a few puzzling attempts at trying to work out why not I discovered that the HTML inserted in IE8 looked like this simplified version:

When it should have looked like this (and did in other browsers):

The problem

So in IE8 the form was self closing. So why was this happening? By asking for the actual HTML being inserted I found the following in IE:

The above is the output using jQuery’s html() function which whilst more than just a wrapper for innerHTML does use innerHTML. So the problem is IE8’s innerHTML function’s mangling of the HTML. Specifically the quotes around the form’s action attribute are being removed, because the action URL ends with a forward slash IE is then confusing action=/url/> with action=/url /> and closing the form prematurely. Whilst IE8 changing the HTML for internal use with the innerHTML function is not in itself a bug, the ambiguity created and its inability to handle it surely is.

There is no direct way of controlling IE’s removal of the attribute quotes, it does not happen for all attributes though, non-standard attributes retain theirs, as do attributes values containing whitespace. Of most note here is that this is not an issue for href attributes so the same problem does not arise when adding a elements, which suggests that the IE developers were aware of the potential problem.

I can see some logic to this, URLs ending with forward slashes are traditionally directories which you may well link to but would not submit a form to but the standard practice of omitting file extensions and using directory like structures for all pages pre-dates IE8 quite considerably and this was not an issue with earlier IE incarnations.

Possible Solutions

Rearrange the attribute order

As it happened the action attribute was the last listed in the source HTML, my immediate thought was just to move it before the others and sidestep the issue. This did not work as the order was just rearranged so that it came last. A little bit of experimentation confirmed that whilst the reordering was consistently the same it was not in an obvious order such as alphabetical or reverse alphabetical, the only attribute I could find which would come after the action attribute were non-standard attributes which were always placed last.

Introducing a non-standard, otherwise useless, attribute did not seem like an ideal solution and anyway Microsoft themselves point out that the ordering cannot be relied on to stay consistent throughout the lifetime of IE8.

Change the URL

A very simple solution is of course just to change the URL the form is submitted to to not have a forward slash at the end. This is of course perfectly fine in this case but I did not want to be changing the URL structure on any site that has a large number of forms added this way so wanted to find a more suitable solution.

Use an innerHTML replacement

There are a number of userland innerHTML replacements which would avoid this issue. I want to continue to use jQuery though and it uses innerHTML for quite a lot of DOM manipulation functions.

Just insert the jQuery object into the DOM

It turns out that just passing the jQuery object without calling html() on it will give the required results, the HTML is inserted into the DOM without the problem occurring. Unfortunately for me I only realised this when I was creating a function to strip out add trailing forward slashes from action attributes and add them back in after inserting the form into the DOM. I decided to store the original actions using jQuery’s data() function, in order to retain this info I switched from inserting the results of $(data).html() to just $(data) so that the stored data would be retained at which point it turned out that this change alone was enough to fix it.

jQuery: Manipulating an Ajax response before inserting it into the DOM

Quick gotcha – well it got me anyway. I was manipulating an HTML response from an Ajax request with jQuery before inserting it into the DOM but my changes were not making it into the DOM. My code looked something like this simplified example:

The problem is is that whilst the jQuery object is manipulated the data variable itself is not, so when inserting $(data) into the DOM the changes were lost as a fresh jQuery object created with the unmodified variable was inserted. The following preserves the changes:

This works as it is the same jQuery that is modified and inserted into the DOM.