blog’s amazing Rotating Header Image

A desktop application with Adobe AIR for scanning documents on Mac OS X

Even though we’re specialized in web development, we like new challenges.

One of our client asked if we could build a desktop application for sales agents. Agents need to scan images, also add several information using a form and submit the data when Internet connection is available. Even though it sounds easy, it can be a hard task without specific OSX experience – so why not?

Fortunately we don’t need to learn how to create native desktop applications as there’s Adobe AIR too: we can take a simpler approach and make an application which relies on existing software instead of learning through many OS-level SDKs and APIs.

As the Mac computers and scanners will be bought for this purpose, we can influence the configuration and deployment.

Well, let’s see what we need:

  • Work under OSX. The Unix based fundamentals make things easy, and Adobe AIR is multiplatform!
  • Scanning. The SANE project saves the day: there’s a command line utility called scanimage that makes scanning a breeze. There’s also twain-sane on top of that!
  • Work offline.
    • We need to work offline and upload stuff when the computer is online again: the standard *NIX ifconfig and ipconfig commands do help!
    • While we’re offline, we can store information in SQLite database and upload information when we’re online again.
  • Easy deployment. As the application will be installed to 50+ computers, installing updates must be easy: Adobe AIR helps here too.
  • Server side. Our beloved PHP, nothing else.

As you can see, such an application could be tricky even for experienced Mac OSX developers: but the combination of these technologies make it easier for others too!

Bookmark and Share

MySQL – limitations you never heard of

We all know MySQL has its limits – it works fine in general, but has its weaknesses too. The authors of MySQL Performance blog started a miniseries about such limitations for experienced users. Okay, I guess you know there’s no way to create fulltext index on InnoDB tables – but bid you know, that MySQL may rewrite your subqueries to do full table scans instead? If not, make sure to follow the series:

Bookmark and Share

Ask git to check if your code is error free!

How about syntax checking your work before issuing a commit? I’m sure you know how it feels when those tiny last minute changes - hey it needs no testing! – just break your app after deployment.

If git is your version control system of choice, make sure you don’t miss the pre-commit hook feature, which was designed to run (tada!) pre-commit tasks: typically for syntax checks to avoid such errors leaking into the repository.

We also use this method to syntax check our PHP scripts both under Windows and Linux using this hook script:

$files = array();
exec('git diff-index --cached --name-only HEAD', $files );

// dont redirect stderr to stdin, we will get the errors twice, redirect it to dev/null
if ( PHP_OS == 'WINNT' )
  $redirect = ' 2> NUL';
  $redirect = ' 2> /dev/null';
$exitcode = 0;

foreach( $files as $file ) {

  if ( !preg_match('/\.php$/i', $file ) )

  exec('php -l ' . escapeshellarg( $file ) . $redirect, $output, $return );
  if ( !$return ) // php -l gives a 0 error code if everything went well

  $exitcode = 1; // abort the commit
  array_shift( $output ); // first line is always blank
  array_pop( $output ); // the last line is always "Errors parsing httpdocs/test.php"

  echo implode("\n", $output ), "\n"; // an extra newline to make it look good

exit( $exitcode );


Actually that’s not rocket science: we’re simply invoking the PHP CLI here to lint (syntax check) the affected scripts.

Installing the pre-commit hook script

It’s also a no-brainer: just paste this script into a file named .git/hooks/pre-commit, and adjust PHP path in the first line after the #! characters.

There’s no global hooks directory for Git, so you’ll need to copy this script into all projects to enjoy the comfort all the time. However, there’s a directory holding entire Git repository templates under /usr/share/git-core/templates/hooks or \Program Files\Git\share\git-core\templates\hooks if you’re on Windows.

We’ve found that on Windows (mSysGit) there’s no support for directory names with a space (neither entire path in quotes), so you may need to use the short format for the path at the top like:


(should you use x64 Windows and x86 PHP, you may need to use #!/progra~2/php/php.exe instead).


A bonus tip for you patient readers: if you want to keep your repos clean, just setup a post-commit hook including git gc – this way the cleanup and optimization processes will run after every single commit. That’s as easy as:

git gc

(The above actually works under Windows too without any changes thanks to mSysGit).

By now I’m sure you already know where to put it: .git/hooks/post-commit :)

You can even fork the script on github at:!

Bookmark and Share

HipHop for PHP – the buzz summary you should really read

HipHop for PHP from Facebook hit the streets several days ago resulting in dozens of posts about the technology. Let’s see what the PHP community says:

  • Marco Tabini enlists the HipHop features and encourages using it
  • the echolibre blog talks about possible security/buffer overflow implications, and mentions similar available solutions
  • Ilia Alshanetsky provides an excellent and thorough overview: he goes into technical details and also practical usage. Though 99.9% of PHP deployments out there do not share the same challenges as Facebook (massive, continually evolving code base and equally massive traffic), [HipHop is also] an incredibly impressive technical achievement, [...] a very helpful development for PHP community in general.
  • Brandon Savage: benefits are large for producers of large-scale web applications written in PHP and who distribute PHP code to clients directly - but HipHop is not the choice of the every day developer.
  • Christian Stocker/LIIP: for most websites (and more so for small ones), PHP’s speed isn’t really the bottleneck, it’s the database or some other external dependency. And for these cases HipHop isn’t the holy grail.
  • Vid Luther/ThirdPartyCode: It’s not for you. The number of servers arguments comes into play when you can eliminate > 100 servers. If you’re going from 4 servers to 2, I guarantee you that you’re doing it wrong.
  • Sebastian Bergmann: As there is a real build — including a real compilation — with HipHop, best practices such as coding standards and continuous integration will be even more important. [...] Yes, it is not a solution for a problem faced by 99.9% of the PHP deployments out there. But this does not make it less interesting in any way.
  • Stuart Herbert “Can HipHop Help The Planet?”: [...] you might not be aware that the power required by each server in a rack is often a major factor in the overall cost of running the servers. [...] Until we can play with HipHop ourselves, it’s impossible to say whether it saves enough CPU cycles to allow us to use less CPUs and therefore less servers. [...] But it sure is nice to hope, isn’t it?
  • Lukas Kahwe Smith/Poo-tee-weetI do not expect that anyone can really get a meaningful return on investment who makes this their business anytime soon. [...] Wouldn’t we expect at least a 2 fold .. or more increase if we could transform our PHP code into a C extension? This approach seems a lot more feasible for the masses. Like we could just drop in a ext/symfony or ext/ZF and thanks to autoloading magic our setup would continue to run unchanged. [...] To me this solution will only matter for the ultra large companies where every single percent of saved CPU cycles matter. For the rest of us I think we need to rely on APC for a bit longer. But maybe with this transformator out there, other people will start working on the much more feasible approach of writing a PHP Code to C extension transformator.
  • Stas/PHP 10.0 blogthere are some serious challenges to consider: plugins, modularity, portability, thread-safety, debugging. [...] Danger primary being that the performance is very important in the web world, and it can give an incentive to the PHP community to change PHP in ways that may be better for performance, but would make PHP into being an entirely different language.
  • Stefan Priebsch wrote another excellent summary about what to expect: as there’s a functional gap between PHP and HipHop, HipHop will always lag a little behind. You’ll need to adapt strict coding guidelines and more automated tests to make sure your HipHop’d code work as expected. On the server side you may need to compile code for different processor architectures or unify your servers, and also take care of web server features currently handled by Apache or LightTPD (URL rewriting, load balancing, proxying, etc.). You also need to scale your infrastructure together with HipHop to keep up with the increased throughput.
Bookmark and Share

Rock Solid HTML Emails

“At some stage in your career, it’s likely you’ll be asked by a client to design a HTML email. [...] Building an email is not like building for the web. While web browsers continue their onward march towards standards, many email clients have stubbornly stayed put. Some have even gone backwards.”

Rock Solid HTML Emails is a really useful article from David Greiner, co-founder of Campaign Monitor, aimed to help with HTML and CSS while creating rich e-mail content.

The article is part of the “24 ways to impress your friends” series, which is an advent calendar blog for web professionals. If you like the advent article idea, be sure to check out Performance Advent and PHP Advent too!

Bookmark and Share

Why You Should Replace ENUM With Something Else

There are many developers who prefer using ENUM in MySQL, which seems to be a viable choice many times. However it’s important to take care as…

  • ENUM requires a rebuild of the table when adding a value to the middle of the set.
  • ENUM values are ordered in the order they’re added to the database
  • ENUM values do in the database what should be done in the model.

ENUM could be useful for columns that had data that would always fit into one particular set of values. For example gender would be one such field that might be served well with an ENUM.

As Brandon says: “The bottom line is that ENUM has its place, but should be used sparingly. The model should enforce the constraints, not the database; the model should handle interpreting raw data into useful information for your views, not the database.”

via Why You Should Replace ENUM With Something Else – Brandon Savage

Bookmark and Share

Google Closure: How not to write JavaScript

Dmitry Baranovskiy, the creator of the Raphaël and gRaphaël JavaScript libraries has serious criticism against the Google Closure JS library.

According to Dmitry:

  • “It’s a JavaScript library written by Java developers who clearly don’t get JavaScript.”
  • poorly optimized loops and unoptimized switch statements
  • memory caching with unlimited size: “I’m not sure what this pattern is called in Java, but in JavaScript it’s called a ‘memory leak’.”
  • Closure Library cannot coexist with any JavaScript code that adds features to Object.prototype.
  • Java-inspired type confusions
  • Closure’s graphics classes are modeled around the HTML5 canvas API, which is about what you’d expect from a JavaScript API designed by an HTML standards body. In short, it’s repetitive, inefficient, and downright unpleasant to code against.

The truth is, developers will switch to Closure because it bears the Google name, and that’s the real tragedy here. Like it or not, Google is a trusted name in the development community, and it has a responsibility to that community to do a little homework before deciding a library like Closure deserves public exposure.

via SitePoint Blogs: Google Closure: How not to write JavaScript.

Bookmark and Share

Active Desktop replacement with Adobe AIR

Interested in simulating XP’s Active Desktop without Active Desktop? We’ve had taken the challenge!


One of our clients wanted a central web application running on the desktop which provides nearly realtime business information for more than a hundred users in a company. After some discussion with the company’s IT staff we’ve chosen Active Desktop as all the PCs run Windows XP which supports this technology. Desktop locking also helps preventing users from disabling the application (you wouldn’t how users stick to their favourite background images! :) Continue reading →

Bookmark and Share

Five Tips To Make Good Object-Oriented Code Better – Brandon Savage

Brandon Savage has some great tips regarding coding OOP:

  1. “Use Objects. Lots of Objects”
  2. “Use Interfaces To Make APIs Predictable”
  3. Use Dependency Injection”
  4. “Composition Over Inheritance”
  5. “Create Loosely Coupled Classes”

As you can see it’s absolutely not rocket science nor these are new invetions: these rules simply help to avoid typical OOP pitfalls and keep your applications well structured.

Bookmark and Share

Google releases Closure, the tools behind the JS geniuses

Google released Closure, the library and toolset that powers Docs and other Google products.

Closure includes:

  • Closure Compiler - removes dead code and rewrites and minimizes what’s left, checks syntax, variable references and types, and warns about common JavaScript pitfalls.
  • Closure Library - a JS library with widgets, controls, lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.
  • Closure Templates - a templating system

via Ajaxian

Bookmark and Share