Category Archives: Snippets

Quick PHP Hack to Tidy up Trashed HTML

I just hacked together the following quick and dirty PHP-script to use the tidy-extension from the command line. Maybe somebody else needs something like this somewhere. Check the comment for details:

<?php

//
// (a) Save this as tidy.php
// (b) Call it from commandline like this: $ php tidy.php trashed.html > tidy.html
//     to tidy the file trashed.html to a new file tidy.html.
//

// Installation and configuration see http://php.net/tidy
$config = array('indent'=> true, 'output-xhtml' => true, 'wrap'=> 200);

$tidy = new tidy;
$tidy->parseString(file_get_contents($_SERVER['argv'][1]), $config, 'utf8');
$tidy->cleanRepair();

echo $tidy;

Install PEAR on OSX

Here is how you install PEAR on Mac OSX:

sudo mkdir /usr/local/temp;
sudo chmod -R 777 /usr/local/temp;
sudo mkdir /usr/local/share/pear;
sudo chmod -R 777 /usr/local/share/pear;
curl http://pear.php.net/go-pear | sudo php;

Set /usr/local as path prefix and install.

You should then be able to use pear, e.g.: pear help.

In order to install modules you also need a temp dir:

sudo mkdir /usr/local/temp;
sudo chmod 0777 /usr/local/temp/;

You can now install PHPUnit:

sudo pear channel-discover pear.phpunit.de;
sudo pear install phpunit/PHPUnit;

Have Fun!

How to Run Your PHP4 Legacies

Every old PHP4 application faces this question: Does it also run under a newer PHP5 version? Hopefully you have migrated or deprecated all your legacy stuff already… or at least have customers that understand the value of a proper relaunch and are also willing to pay for it.

To make some customer fossils run on a PHP5 host, we did the following dirty hacks:

  • Set “AllowOverride All” in your Apache config in order to enable .htaccess files for runtime configuration.
  • Copy your legacy app on your new php5 host.
  • Place a .htaccess file in the directory containing something like this:
    php_flag register_globals on
    php_flag register_long_arrays on
    php_flag zend.ze1_compatibility_mode on
    php_flag short_open_tag on
    php_value auto_prepend_file "/home/web/my_legacy/_prepend.php"

    More info on configuration changes in php and list of ini-directives.

  • Place a file called _prepend.php in the same directory and set path info accordingly:
    <?php
    // See also .htaccess file in this dir with more directives set for this site
    
    // Php4ify error reporting
    error_reporting(E_ERROR | E_WARNING | E_PARSE);
    
    // Add required include paths to some distant libs
    $path_arr = array();
    $path_arr[] = '/home/web/blah/libs/legacy';
    $path_arr[] = '/home/web/blah/libs/whatever';
    
    $path_str = implode(PATH_SEPARATOR, $path_arr);
    set_include_path( get_include_path() . PATH_SEPARATOR . $path_str);

This is indeed very very dirty and should only be considered as last-resort to make some legacy app runnable under php5 without having to do crazy search-and-replace orgies on old stuff.

Redirect all URLs to a Maintenance Page

Once in a while every bigger website is relaunched.

In order to deploy bigger changes without bothering your visitors with strange behaviour during a data migration, updates and the like, you should use Apache2′s mod_rewrite. Just put the following lines in a .htaccess file in your webroot directory and all traffic (also deep links to subdirectories) gets diverted to the maintenance-page. The scond line sets an exception for your IP address, so you are the only visitor who is NOT redirected to the mainteance page:

RewriteEngine on
RewriteCond %{REMOTE_ADDR} !192.168.123.101
RewriteRule !maintenance/index.html /maintenance/index.html [L,NC,R=301]

Do not forget to remove the .htaccess file after you have finished your work!

Bulk Image Resize using Conditional Width

I am currently working on a project in which we have lots of images from an old CMS waiting to be migrated into a new layout. Of course there are restrictions so it should not happen that certain image types exceed a certain max. width.

OK, we have many many images… So I took a closer look at ImageMagick (also take a look at the usage examples). And I have to say: Awsome!

You can install ImageMagick on Ubuntu or Debian with a simple
# apt-get install imagemagick

In combination with a bit conditional scripting I came up with the following solution:

Console doing bulk resize.

Console doing bulk resize.

I wanted to have a shell script that, given a directory containing all our images, checks the width of each image and resizes it if it exceeded a certain width. Simple, but powerful.

Usage:

$ ./resize_image_dir.sh ../../brand_logos

And you are done with thousands of images in a minute. Do not forget to make a backup if designers change the desired width later…

You can download the shell scripts with example images ready to test:
!resize_conditional_images_bulk2

A Simple PHP Google Sitemap Generator

I just hacked together a very simple class and CLI script to help me generate Google sitemap XML on a daily basis using PHP. If you have not yet heard of it: Google sitemaps help you promote your content if you have certain deep links that only show up if a visitor for example performs a search and clicks a result.

Check the documentation of the Google Sitemap Format

Here is the code: Google Sitemap Generator

It works like this:

$ php generate_gsitemaps.php; #will generate your standard sitemap
$
php generate_gsitemaps.php -e > my_sitemap.xml; #echo sitemap xml to another file

Example: generated_example_sitemap.xml

Have fun being found!

Use of MySql Variables

Case: I was building a CLI script to aggregate data from one MySql database and write results to another MySql database using 2 open db-connections. This way the script’s execution time was in the some-minutes-range… not good! I tried a more effective attempt: I let the CLI script output all necessary statements to drop and create all needed tables and fill them with insert-statements. I called it like this from the command line and diverted output to a file:

$ php aggregatData.php > all_sql_i_need.sql

I could then import the whole thing in one go into my target database like this:

$ mysql the_dbname -h localhost -uMarco -pPass < all_sql_i_need.sql

Insight: The execution-time was way better than my first attempt and took only seconds. I could also have combined the two lines in a shell-script.

The problem with the generated SQL statements was, that the data also contained relations between primary and foreign keys of records and that these IDs were generated at import-time by auto_increment fields. I solved this issue by using MySql variables which can be set and use d again like this:

INSERT INTO gruppen (name) VALUES ('Gruppe 1');
SET @temp_gruppe_id = LAST_INSERT_ID();
INSERT INTO gruppe_eigenschaften (id_gruppe, name, wert) VALUES
     (@temp_gruppe_id, 'email1', 'email1@emailxxx.com');

The variable @temp_gruppe_id is set and can be used in the subsequent SQL statements. It also worked in MySql4.

Here is an example of SQL statements illustrating this mechanism in the above mentioned script. You can cut-and-paste it into your PhpMyAdmin.