Collaborative web page snapshots with annotation: SharedCopy

One of the biggest headaches in working remotely is not being able to see exactly what your collaborators see, and then having to interpret what may unfortunately be difficult to understand descriptions (or just plain f#*!ing nonsense as the case may be…)


SharedCopy could put an end to this. Add annotations, highlight text, draw shapes to highlight areas, take a snapshot of the page as you are seeing it and share with your team.

For developers, you can easily and visually point out areas that need tweaking.

For support providers, if you can get the client to use it, they can at last show you exactly what the hell they are banging on about! And you can send them a snapshot with that button (that they can’t seem to find with both hands) highlighted.

Watch out the demo video to get the idea:

One particularly handy way to utilise it is to make your bookmarks far more valuable – open your links and have the crucial information highlighted with your own notes or corrections.

With email, Blogger, Twitter,, Basecamp, Backpack, Trac and Bugzilla integration, auto trackbacks – all from a bookmarklet with no sign-up necessary – this is a tool with incredible potential. It’s been around for years apparently, and I had no idea. They even have Posterous integration!

I started using Diigo for similar purposes recently, but SharedCopy may well have it beat.

If this all sounds like an advert, well I guess I just write good copy. Mainly I wanted to save a note for myself in my blog, but I thought I might as well make it useful to others.

Check it out:


PHP Compression with GZip: Content Encoding Error


Site returns Content Encoding Error or similar error


Content Encoding Error

The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.
* Please contact the web site owners to inform them of this problem.


This web page is not available.

The web page at http:/domain.tld/path/to/file.ext might be temporarily down or it may have moved permanently to a new web address.

More information on this error
Below is the original error message

Error 330 (net::ERR_CONTENT_DECODING_FAILED): Unknown error.


Safari can’t open the page.

Safari can’t open the page “http://domain.tld/path/to/file.ext;. The error is: “cannot decode raw data” (CFURLErrorDomain:-1015) Please choose Help > Report Bugs to Apple, note the error number, and describe what you did before you saw this message.

Internet Explorer 7:

IE doesn not return an error that explicitly mention content encoding or compression


Opera does not return an error, instead it displays the page content, partially compressed. Error messages will be human readable. Compressed data appears as garbage.


GZip can be enabled on the server for more efficient page delivery. On occasion, PHP errors my be output that are not compressed with the rest of the page content. When this occurs, some browsers fail to identify the uncompressed error message and thus cannot output the page.


Opera can be used to view the uncompressed data and interpret the error message.

Alternatively, the linux command line

can be used to get and view the output of the file:

If the page uses basic authentication:

You can then use your preferred text editor to view the file you have just downloaded and interpret the error.

Finally you will need to resolve whatever caused the PHP error in the first place.


Opera rocks. End transmission.

(…from the one armed scissor)

Testing clones

# mysql --user="admin" --pass="$ADMINPASS"> USE mysql> INSERT INTO db VALUES('localhost','ac_testing','mauk_testuser','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');> INSERT into db_users VALUES('','macouk_testuser','29','3');> exit;# rm -rfv /var/www/vhosts/*;# cp -rfvp /var/www/vhosts/* /var/www/vhosts/;# cp -rfvp /var/www/vhosts/ /var/www/vhosts/;# cp -rfvp /var/www/vhosts/ /var/www/vhosts/;# mysqldump --add-drop-table --single-transaction -u admin --password='$ADMINPASS' macouk_live > /var/www/vhosts/$TODAY.sql;# mysql --host="localhost" --user="admin" --password='$ADMINPASS' macouk_test < macouk_database_$TODAY.sql;# mysql --user="admin" --pass="$ADMINPASS"> USE macouk_test> DROP VIEW IF EXISTS jos_users;> DROP VIEW IF EXISTS jos_session;> DROP VIEW IF EXISTS jos_stats_agents;> DROP VIEW IF EXISTS jos_core_acl_aro;> DROP VIEW IF EXISTS jos_core_acl_aro_groups;> DROP VIEW IF EXISTS jos_core_acl_aro_map;> DROP VIEW IF EXISTS jos_core_acl_aro_sections;> DROP VIEW IF EXISTS jos_core_acl_groups_aro_map;> exit;# mysqldump --add-drop-table --single-transaction -u admin --password="$ADMINPASS" clubantichrist jos_users jos_session jos_stats_agents jos_core_acl_aro jos_core_acl_aro_groups jos_core_acl_aro_map jos_core_acl_aro_sections jos_core_acl_groups_aro_map > /var/www/vhosts/$TODAY.sql;# mysql --host="localhost" --user="admin" --password='$ADMINPASS' mauk_test < /var/www/vhosts/$TODAY.sql;


52 coding tips for improved PHP performamce

An interesting collection of tips over at

Some of the best:

  • Operating on an initialized variable is 376% faster than operating on an unitialized variable.
  • Constants are 146% slower than variables
  • Local variables are 9.9% faster than global variables
  • ‘String’.$var is 28% faster than “String$var”
  • isset($array[$key]) is 230% faster than array_key_exists()
  • file_get_contents() is 52% faster than fopen(), fread(), fclose()
  • @Error supression is 235% slower than without
  • require_once() is 24% faster than include()
  • include(relative path) is 37% faster than include(full path)

Learning to use these tips could significantly speed your code.

52 PHP Programming Tips


Death to spec work. Period.

Frankly, I’m sick and tired of people asking for spec work. I sometimes engage in pro bono work, or work at a discounted rate for a particular client, but this is solely at my discretion and on my terms. Trying to get people to work for free or cheap by dangling vague, unspecified future rewards is frankly insulting, devalues both myself and my professional peers, and is bad for the industry – in fact any industry that indulges such behaviour.

I bring this up as I was reminded of the subect by the fantastic 27b/6 post Simon’s Pie Charts, which I was in turn reminded of by a friend.

Image stolen without permission, but used for the express purposes of promoting 27b/6. I think that’s fair enough.

So, I possibly shouldn’t be advertising my penchant for precisely this kind of bitterly sardonic humour, but there is a very serious point behind it.

One that is illustrated perfectly well by the NO!SPEC campaign, so I shall let them get on with it.

I also sometimes get annoyed with people asking me to do them ‘little’ favours with no ideal what the favour entails , particularly those to whom I owe no favours in return. “Oh it will only take you five minutes…” Really? And you know this how? It being an area of such expertise for you, I wonder why you ask me to do it.

27b/6 again illustrates rather well just how this can make me feel, in the post Missing Missy

Check out the rest of 27b/6, and see if you don’t wet yourself at least a little.

Oh, and one last thing, while we are on the topic:
Stop asking me questions for which, in order to answer, I’m only going to use Google. GIYF.

Best Open Source eCommerce platforms

15 Best Free Open Source Ecommerce Platforms | Web Appers

15 Open Source Ecommerce Platforms | Tripwire Magazine

Do take the time to read the user comments – the insights can be very useful – for example:

Magneto is the slowest shopping cart I have ever tested, it’s also almost impossible to upgrade without crashing your site. Only Magneto’s pay version will be PCI compliant which means if you use credit cards you will either have to buy their $500 version or pay higher credit card fees. Avoid this crap at all costs.

Useful to know…

Vampire PHP! Suck code from another site…

This is a potentially abusive script, but I hope you will show restraint and be good.

I am running multiple, related Joomla sites on a single server. We needed to take some content from one site and show it on another – installing all the components and modules to replicate the behaviour on the second site was not the desired way to go about things.

As GET vars are required to make Joomla generate the desired content, writing a script to access a file elsewhere on the server was not the way to go either, so I wrote these functions to grab content from a URL, and extract the inner HTML of any given tag based on its ID attribute. The nice thing about this code is making use of the XPath PHP class to handle traversing and manipulating the DOM.

I put all of this into a rather nifty vampire module, which is simple enough to do. I then modded this module and the module on the target site so I can control the content displayed with the parameters of the module on the second site. This also proved to be fairly easy and the boss is rather chuffed with the results. And I’m rather chuffed with myself, as it all went very smoothly – although it did take place during a serious all night coding session that resulted in sleep dep and hallucinations.

I’m not going to go into the details of the modules here – you can contact me if you are interested, but I am going to share the core functions in a simple PHP page that displays the result.

[update 20101216-1136]The scrape function has been updated to use fsockopen() instead of fopen() – this enables us to set a timeout with get out clause and error handling. Otherwise, you run the risk of hitting a dead site and ending up with a process that doesn’t time out, meaning the user waits forever for the page to load, and the server fills up with endless processes.

Also updated to allow selection by any html attribute/value pair with error handling if the element is not found.[/update]

Plesk/Postfix Forwarders: Some mail does not get forwarded


Emails are not forwarded and postmaster receives messages like:

Subject: Postfix SMTP server: errors from unknown[]


If you create a mail account without a mailbox and only a forwarder, it seems unnecessary to create a password for the account. Sadly this is not the case!


Set a password for the account under Plesk > Domain > {domain} > Mail Accounts > {mail account} > Preferences

*nix – Read .db files

Incredibly simple tip.

Convert the file with makemap then view with your preferred text editor:

# makemap hash access.db < access# vi access 

To rehash the file after editing:

# postmap virtual

If you are making major changes to the file and aren’t 100% sure of what you are doing, BACK UP THE ORIGINAL FIRST!