Archive for the 'Web Development' Category

A new job! – but no Symfony

Note: We are actively seeking to hire exceptional PHP programmers. More on the job offering at the bottom of this posts.

Zero BubbleAfter one of my posts got featured on Ajaxian many interesting offers hit my mailbox. One of them was actually from a startup right here in Rotterdam called ZeroBubble. I was happily surprised to find an IT startup in Rotterdam. Especially since after talking to them it became clear that they operate at the highest level of technical possibilities and have an absolutely amazing team. Two months ago I happily joined their ranks.

YouTellMe

The project we are working on is called YouTellMe. I don’t want to share too much about it right now, but surely I will have plenty of exciting blog posts coming up in the next months.
Currently we are working with some of the nicest tech on the net. To give some examples: our admin interface is written entirely in ExtJs, the site’s search is powered by Lucene, we use prototype 1.6 for great object extending, for ajax functionality we use yahoo history manager to keep it bookmarkable, the entire site has been optimized according to the Yslow principles and we are doing some interesting things with openSocial. Given all these you can’t help but wonder why we aren’t using Symfony.

Why no Symfony?

Personally I am a huge fan of the Symfony framework. The team at Sensio has done an absolutely amazing job. My opinion on the framework is best described by these blog posts Part1, Part2. However the current project we are working on has some special requirements. First of all the application’s calculations are very harsh on the servers. Combine this with a large amount of AJAX and you have some serious performance issues. The calculation speed has been pretty optimized by a colleague of mine, who wrote a python daemon for the task. Still it is essential to keep the PHP framework’s overhead to a minimum. Prior to my employment at this company it was decided that Symfony would be too slow to handle the task. This is a topic which often nags Symfony.

I am curious how fast Symfony can be. For the YouTellMe site I need a bootstrapped and blazingly fast framework. In the coming weeks I’ll be setting up some tests too see how Symfony compares to our home build framework. As a starters I’ll definitely relieve Symfony from the ORM and fancy routing. From there on I will need to test to see which components are slow and can be removed. The clean and flexible programming in Symfony should make this easy to do.

Our current framework is very lightweight. It even does not do auto loading. I for one have no clue what the speed gain is from not using auto loading and it would also be interesting to test it. The MVC structure is entirely home build, but the rest of the features use Zend.

If there are readers of this blog, which have gone through the process of stripping Symfony, be sure to leave some tips in the comments!

Jobs at ZeroBubble

ZeroBubble is currently recruiting talented PHP programmers in the Rotterdam area. We are located in the Beurs World Trade center. If you are into the latest technology and like to work with great people, software and hardware be sure to email me at thierry [at] zerobubble [dot] nl or my boss at joost [at] zerobubble [dot] nl. As mentioned we work with fun software such as Ext Js, Lucene, Zend, object oriented js with Prototype 1.6, yahoo history, Yslow principles and openSocial.
We are looking for both full and partime PHP programmers. Python, ExtJs, prototype, server admin, subversion and memcached knowledge are all nice extras. As a main quality though, you have to be excited about building a unique and amazing web application.

Business &Javascript &PHP &Symfony &Web Development tschellenbach 20 Jan 2008 201 Comments

Is the php native json_encode really broken?

It sure seems so:

The php:
var_dump(array('mynumber'=>42.2));
var_dump(json_encode(array('mynumber'=>42.2)));

The result:
array(1) {
["mynumber"]=>
float(42,2)
}
string(17) "{"mynumber":42,2}"

Notice the 42,2.
‘42,2’ or “42.2” or 42.2 would have all been fine, but 42,2 obviously invalidates your json object.

The problem seems to arise from my ‘nl’ internationalization setting in php. I’m guessing the same problem will occur with any language which uses the comma for decimal separations.

Currently I am solving this problem by typecasting my number to a string, but there has to be a better approach.

Javascript &PHP &Web Development tschellenbach 20 Dec 2007 Comments Off on Is the php native json_encode really broken?

Pake: propel-build-all-save-mysql

I tended to use fixtures in order to save my data before propel-build-all commands. In a discussion on syncing development database structure with production, Mike mentioned he uses mysqldumps. This is actually not a bad idea, given that it is faster and less error prone (propel will never bug you). The downside is off course that it only works for mysql.

Here 3 Pake tasks to automate your mysql dumping:

  1. mysql-dump-data
  2. mysql-load-data
  3. propel-build-all-save-mysql

Download all three pake tasks. To install them simply copy the file to myproject/data/tasks/

You will have to edit the file to configure your database settings.

Note that this is only a temporary solution. I personally would be very happy to see Propel making database structure changes.

I didn’t see any manual on creating Pake tasks. Improvements and suggestions are more than welcome.

PHP &Symfony &Web Development tschellenbach 11 Nov 2007 3 Comments

CSS Vista is great

For those trying to debug their CSS in Internet Explorer (if you still support that browser)

Have a look at CSS vista, it is free and helped me a great deal.

Css &Web Development tschellenbach 10 Nov 2007 Comments Off on CSS Vista is great

CommentHub.com – Developed with Symfony

CommentHubCommentHub.com has been developed with Symfony and is currently in Alpha testing. Needless to say it is a great pleasure to use Symfony and new features are being added effortlessly.

CommentHub.com aims to raise the standard in online commenting and make it more social. Commenting has become an important aspect of the internet, however a central system has not been available so far. CommentHub offers a plug and play comment system for your website. Whether it is your blog or any other page, you can add an advanced comment system in a minute. Currently it supports the following features:

  • Fast Ajax commenting
  • Threaded comments
  • Voting on comments
  • Gravatar images
  • Edit capabilities
  • Spam prevention and protection
  • Distinct look for admin comments
  • New comment notification emails for admins
  • Comment RSS Feed
  • Login (to remember email, name and site across websites)

Stronger email integration, personal RSS feeds and social features are all under development. Furthermore the system is already supporting templates. An interface to upload CSS templates will be available soon.

To see the comments in action just scroll down to the bottom of this page. Another example (with more comments) may be found by looking at my previous post.

Currently it is rather bootstrapped and in Alpha testing. To try it out for your website you can register for a webmaster account here (Enter mellow as your invitation code). The product is still under heavy development. Feature request, bug reports and comments are more than welcome.

To have a sneak peak at how easy the implementation actually is, view getting started with CommentHub. Plugins for major blogging systems will soon be available. (If anyone feels like contributing some plugins, it would be greatly appreciated.)

Thanks to Symfony for making the development such a pleasure.

Business &PHP &Symfony &Web Development tschellenbach 08 Nov 2007 1 Comment

Updated cross site ajax plugin for Prototype

The first post on my cross site ajax plugin for Prototype (1.5.0) was received with great enthusiasm. It was very nice to see my own work on the great Ajaxian website and the delicious front page. Since that post the quality of the plug-in has improved quite a bit. Especially cross browser compatibility improved. I made a test page to evaluate this; have a look to test your own browser. Furthermore some 14 screen shots show that the compatibility is good.

Here the new version: Download the cross site ajax plugin.

The syntax remains exactly the same:

new Ajax.Request(url, {
method: 'GET',
crossSite: true,
onLoading: function() {
//things to do at the start
},
onSuccess: function(transport) {
//things to do when everything goes well
},
onFailure: function(transport) {
//things to do when we encounter a failure
}
});

Cross Browser Compatibility

First of all thanks to Kris Kowal and Gary Gurevich for spotting the problems with Safari. Prior to the changes the plugin used three different methods to detect the loading of the script element. For Safari and Konqueror a sequential script technique was used. This technique has now been replaced with the polling technique, like in COWS. So the following three solutions are used.

1.) For IE it used its proprietary onreadystatechange event
2.) For Safari and Konqueror it uses the polling technique
3.) For Firefox and Opera it uses the standard onload event

Timing problems

In addition to the cross browser compatibility problems I noticed another complication. In Prototype 1.5.0 the onLoading, onSuccess etc., are generally fired by running the onreadystatechange function. However this is not the case for a transport status below 2. Actually the onLoading event is triggered by a delayed function after the open command. I didn’t realize this initially. However if you have a script which loads rather fast it will result in onSuccess executing before onLoading. This issue was fixed by calling respondToReadyState directly.

Points of Improvement

Firstly the current implementation detects browsers, not capabilities. This might create problems with future or buggy versions of browsers.
Secondly the usage of a global variable to indicate transport status makes it impossible to handle simultaneous requests nicely.
Thirdly the script currently does not clean up the script nodes.

If these points turn out to be troublesome, I will use a modified version of COWS for the transport aspects.

Conclusion

The new version of this plug-in is widely cross browser compatible. Currently it is suitable for a large variety of applications. It is however not yet ready to deal with simultaneous requests.

Javascript &Prototype &Web Development tschellenbach 07 Nov 2007 2 Comments

Using php to dynamically generate conflict free css

This little blog has been getting a lot of coverage lately thanks to a write up by Ajaxian. Developing with Symfony is great and always gives you a lot to think and write about.

For my new product I was having a CSS conflict. This tends to happen when you include your own html and css into someone else’s website. For instance if you have a widget as such:

html

<div id="mywidget">
<h1>My hello world widget</h1>
</div>

css

H1 {
color:green;
font-size:20px;
}

The solution to this problem is quite straightforward, you simply specify your css selector as div#mywidget H1. However, what if you want to allow people to customize the looks of your widget. Now you could off course ask them to include the div#mywidget part, but chances are this will give problems.

Since I was already using the great sfCombineFilterPlugin an easy solution was available. (If you didn’t use the sfCombineFilterPlugin yet, go check it out immediately. Also have a look at Yahoo’s Yslow)

The sfCombineFilterPlugin uses php to gzip, minify and cache your css and javascript. Here is how to extend that behavior to include the #mywidget specification. (Assuming you have sfCombineFilter installed)

Step 1: open your .htaccess

Just below the RewriteBase instruction add:
# if we are retrieving javascript or css
RewriteRule ^css/packed/prepend/(.*\.css) /sfCombineFilterPlugin/combine.php?type=css&prepend=1&files=$1
RewriteRule ^css/packed/(.*\.css) /sfCombineFilterPlugin/combine.php?type=css&files=$1
RewriteRule ^js/packed/(.*\.js) /sfCombineFilterPlugin/combine.php?type=javascript&files=$1

Step 2: add this class to the top of web/sfCombineFilter/combine.php

Partly based on CSS parser class.

class prependCss
{

    public static function prependCssString($str) {
        // Remove comments
        $str = preg_replace("//*(.*)?*//Usi", "", $str);

        $parts = explode("}",$str);
        if(count($parts) > 0) {
            foreach($parts as $part) {
                list($keystr,$codestr) = explode("{",$part);
                $keys = explode(",",trim($keystr));
                $newkeys = array();
                if(count($keys) > 0) {
                    foreach($keys as $key) {
                        if(strlen($key) > 0) {
                            $key = (!strstr($key, '#mywidget')) ? '#mywidget'.$key : $key;
                            $newkeys[] = $key;
                        }
                    }
                    $keystr = implode(', ',$newkeys);
                }
                if(!empty($keystr)) //needed for spaces behind last }
                $rules[] = $keystr . " {" . $codestr . "}";
            }
            $prependedCss = implode("n", $rules);
        }
        //
        return $prependedCss;
    }

    public static function prependCssFile($filename) {
        if(file_exists($filename)) {
            return self::prependCssString(file_get_contents($filename));
        } else {
            return false;
        }
    }
}

Step 3: hack around in combine.php

below $minify_js add:
if($_GET['prepend']==1)
$prepend = true;

change the stuff below this comment to:
// Get contents of the files
$contents = '';
reset($elements);
foreach ($files as $path) {
if($prepend && $_GET['type'] == 'css') {
$contents .= "\n\n" . prependCss::prependCssFile($path);
} else {
$contents .= "\n\n" . file_get_contents($path);
}
}

And finally just change your urls to css/packed/prepend/yourcss.css (if you are using relative paths in your css you might need to add an ../)

Conclusion

Using this technique your css will load without any problems in third party sites. This comes in very useful when creating widgets or greasemonkey scripts.

Css &PHP &Symfony &Web Development tschellenbach 29 Oct 2007 13 Comments

« Previous PageNext Page »