Online .htpasswd Generator

Use the following .htpasswd generator to secure your Apache web directories.

Make sure you have a .htaccess and .htpasswd file in the directory you want to secure, then add the entries once you’ve generated your password.

Posted in .htaccess, Apache, Tools at March 7th, 2008. 2 Comments.

Online MD5 Hash Generator

Here is a simple MD5 hash generator I created quickly as part of a useful toolset I’m planning to build up.

The code to generate an MD5 hash using PHP is simple:

md5($string_to_convert);

Posted in Tools at March 7th, 2008. 12 Comments.

Top 10 .htaccess Tips and Tricks

Custom Error Documents

Creating custom documents gives your site a more professional look, as not only are you providing a ‘net’ to catch unsuspecting visitors when they follow a bad link and such like, but they also allow you to customise the style of the page so you can maintain your basic site design by adding HTML.

# custom error documents
ErrorDocument 401 /error/401.php
ErrorDocument 403 /error/403.php
ErrorDocument 404 /error/404.php
ErrorDocument 500 /error/500.php

Control Access

Being able to control access to certain areas of your server can be very useful. The following example demonstrates how to only allow access from those connecting from a 192.168.0 LAN IP pool. This could be easily modified to only allow access from a single remote IP address or addresses.

# no nasty crackers in here!
order deny,allow
deny from all
allow from 192.168.0.0/24
# this would do the same thing..
#allow from 192.168.0

Hide and Deny Files

Hiding and denying access to files is crucial to servers that have sensitive data held within files that may be accessible via the website(s) on it. The following example demonstrates how to prevent acces to any files ending with .log – and is case insensitive (i.e. .LoG / .lOG / .loG).


 Order allow,deny
 Deny from all
 Satisfy All

Basic Rewriting

I have written a mod_rewrite tutorial, but this is worth a mention as a top 10 tip for .htaccess files as it’s becoming more and more commonly used these days – primarily for SEO purposes.

This example will redirect a request for http://edrackham.com/page_one.htm to http://edrackham.com/page_one.php. The r=301 tells apache to send a proper HTTP Permanently Moved redirection (301), which will update the address bar in the browser window to show ‘page_one.php’. Without this, you’d still see ‘page_one.htm’ even though you’re seeing a PHP page. This helps SEO, as spiders and search engines will update their listings to reflect the PHP versions.

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.+)\.htm$ http://edrackham.com/$1.php [r=301,nc]

Shorter URLs

Shorter URLs are beneficial, as visitors that persist in typing full URLs won’t have to type as much, and they’re more memorable. Do they benefit SEO, even though the full URL contains the same keywords? I don’t know, maybe someone can tell me.

This example will rewrite a page requested as http://edrackham.com/files/code/apache.zip to http://edrackham.com/download.php?type=code&file=apache.

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^files/(.+)/(.+).zip download.php?type=$1&file=$2 [nc]

Prevent Hotlinking

Preventing hotlinking can reduce bandwidth, by disallowing other websites from displaying images hosted on your server. The following rule basically says that if the referer is NOT edrackham.com, run the following rule. The rule (on the next line) says that if the request is for a .gif, .jpg or.png then redirect the visitor to http://edrackham.com/img/hotlink_f_o.png. I’ll leave you to work out what the ‘f_o’ stands for.

Options +FollowSymlinks
# no hot-linking
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?edrackham\.com/ [nc]
RewriteRule .*\.(gif|jpg|png)$ http://edrackham.com/img/hotlink_f_o.png [nc]

Hiding Page Extension

Similar to the mod_rewrite code above, this will redirect a request for product-3.html to products.php?id=3. As we’re not using r=301, the requested page will remain in the browser’s address bar.

Options +FollowSymlinks
RewriteEngine on
RewriteRule ^product-([0-9]+)\.html$ products.php?id=$1

Ban Selected User Agents

In my opinion, it’d be ace to block all requests from a Microsoft user agent, but alas, that wouldn’t be too cool as some people are still hell-bent on using a non-standards compliant browser. Having said that, Microsoft is making their new IE8 release standards compliant by default.

The following provides some examples for blocking requests to your server from certain user agents.

#####################################
# Deny Useragents
#####################################

RewriteCond %{HTTP_USER_AGENT} ^FrontPage [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Java.* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Microsoft.URL [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^MSFrontPage [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Offline.Explorer [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^[Ww]eb[Bb]andit [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus [NC]
RewriteRule ^.*$ - [F]

Making Other Filetypes Executable

Ever wanted to make your site look like it runs off a new language such as .w00t files? Well you can with .htaccess! Adding this neat one-liner, you can request .w00t files, which will be served and interpreted as .php type files.

AddType application/x-httpd-php .w00t

Force Media Downloads

Sometimes, when clicking on media files, the browser wants to play or stream it directly from itself. Using the following rules, media files (.avi/.mpg/.wmv/.mp3 in this example) will provide a download dialog box instead.

# instruct browser to download multimedia files
AddType application/octet-stream .avi
AddType application/octet-stream .mpg
AddType application/octet-stream .wmv
AddType application/octet-stream .mp3

Require SSL

Sometimes you will require an SSL connection. This following snippet will do just that!

# require SSL
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "domain.tld"
ErrorDocument 403 https://domain.tld

# require SSL without mod_ssl
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Sources:

http://corz.org/serv/tricks/htaccess.php

http://roshanbh.com.np/2008/02/hide-php-url-rewriting-htaccess.html

http://expressproducts.net/htaccess.htm

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/#usa4

http://phpsecurity.wordpress.com/2007/12/22/htaccess-tips-and-tricks/

Posted in .htaccess, Apache at March 6th, 2008. 11 Comments.

Get Random Row with MySQL Without ORDER BY RAND()

This is an update to a previous post of mine which uses the RAND() method. Using the following code, you can retrieve a random row much, much faster (MySQL 4.1.x/5.0.x), with thanks to Jan Kneschke:

SELECT FROM

AS r1
JOIN (SELECT ROUND(
RAND( ) * (
SELECT MAX( id ) FROM
)
) AS id
) AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1;

Replace:

  • <COLUMN> with the name of the column(s) you wish to retrieve
  • <TABLE> with the name of the table you wish to retrieve the data from

I've tested this with a table with over 660,000 records, and got a response in 0.0200 seconds, whereas with ORDER BY RAND() i got a response in 2.1599 seconds.

Total Number of Rows:

Cardinality

Old Method:

Old Method

New Method:

New Method

Posted in Featured, MySQL at March 5th, 2008. 14 Comments.

Standards Compliant Internet Explorer (IE8)

We’ve decided that IE8 will, by default, interpret web content in the most standards compliant way it can. This decision is a change from what we’ve posted previously.

Don your glad rags and party hats, it’s time to celebrate! Microsoft have announced that their new interoperable release of Internet Explorer (IE8) will be standards compliant by default.

Their explaination for change still hints at their stubborness though: “While we do not believe any current legal requirements would dictate which rendering mode a browser must use, this step clearly removes this question as a potential legal and regulatory issue.”.

So what does this mean for us as designers?

Don’t misconceive me – I’m not primarily a designer, but I do design all sites I build …in pure CSS. This change will mean that we should know that our designs will render the same in all mainstream browsers such as FireFox, Opera, Safari and of course IE8 (provided we use valid CSS1, 2 or 3 [when fully supported] code). The days of running both FireFox and IE6/7, uploading your new CSS file and hitting F5 to find that the bug you just fixed in IE6/7 has now broken something else layout-wise should now be gone.

IE8 will support standards compliant mode as default, but will be backward compatible with our already ‘IE Bug-Fixed’ CSS files. So, to save us backtracking to make our previously written CSS files – which have no doubt taken us hours upon hours to write thanks to IE7- rendering modes – we can insert a meta tag into IE8 to set it to “Quirks Mode” for this exact purpose.

A final note

All in all, I don’t have much confidence in Microsoft and the web. This confidence decreases even more after hearing any one of Steve Ballmer’s semitars, especially the one about Microsoft winning the web. In my opinion, they never will, but this is a fantastic step in the right direction which leads me to say two things; Well done Microsoft, and two, Let’s get used to the days of IE7-.

Posted in Web Standards at March 4th, 2008. No Comments.

Guilt Trip Album Release Gig

Guilt Trip's Album Release Gig
Wow. This was definately a gig to remember! I’ve seen these guys a few times, but the amount of effort they’ve put into the release of their album has been phenomenal. The energy on stage was amazing, the music was spot on and everyone in the venue were on their feet.

I really hope these guys make it. They deserve it.

Posted in Asides, Music at February 11th, 2008. No Comments.

Get Random Row with MySQL

UPDATE: Please see my newer atricle on how to retrieve a random row, faster, without RAND().

This post assumes you know how to create and use a connection to a MySQL database in PHP and have a table named ‘quotes’ as shown below. In this post, I will aim to teach you how to use PHP to pull random quotes from a MYSQL table of quotes. This can be easily extended to pull a random banner as will be explained at the end of the post.

Let’s firstly assume we have a MySQL table similar to the following:

+----+------------------------------------------------+
| id | quote                                          |
+----+------------------------------------------------+
| 1  | I know Karate... and many other Chinese words! |
+----+------------------------------------------------+
| 2  | w00t this is geeky                             |
+----+------------------------------------------------+
| 3  | You're CLINICALLY MENTAL!                      |
+----+------------------------------------------------+

Now, in your PHP code, we need to:

  1. Build a suitable MySQL query to obtain a random result from the ‘quotes’ table.
  2. Store the result of the query to be used in the HTML somewhere.
  3. Output the result in the HTML somewhere.

So, for step one we’d use something like the following:

$sSQLQuery = "SELECT quote FROM quotes ORDER BY RAND() LIMIT 1";
$aResult = mysql_query($sSQLQuery);
$aRow = mysql_fetch_array($aResult, MYSQL_ASSOC);
$sQuoteOfTheDay = $aRow['quote'];

There, the variable ‘$sQuoteOfTheDay’ now has the value of our randomly pulled quote. Let’s just analyse each line of the code above to see what it does.

$sSQLQuery = "SELECT quote FROM quotes ORDER BY RAND() LIMIT 1";

This line stores the MySQL query we’re going to use against the database. It says, in laymans terms, “Select just one random value of the quote field from the table named quotes”. All this line does though is store the query into the variable ‘$sSQLQuery’.

$aResult = mysql_query($sSQLQuery);

This line runs the MySQL query, storing the result of running the query in the variable ‘$aResult’. It’s important that we store the result of the mysql_query in a variable, as the result of running a successful MySQL query using PHP’s function ‘mysql_query’ doesn’t return a nicely formatted array that we can necessarily use.

$aRow = mysql_fetch_assoc($aResult);

This is probably the hardest line for me to explain. Firstly, many of you may have seen a similar line like this used in a ‘while’ loop. However, our MySQL query used the ‘LIMIT 1′ string, so we know we’re only going to get ONE result, hence no need for a loop. The function ‘mysql_fetch_assoc’ takes one parameter: the result of the successful ‘mysql_query’ which as we know is ‘$aResult’. My biggest tip here is to use the ‘assoc’ method wherever possible, as it creates the array in such a way that we can reference each element by the column name, not a number. This is particularly useful if you ever update the MySQL table to have more columns.

Anyway, this line basically says ‘Fill the variable ‘$aRow’ with the CURRENT row of the returned query’. We know that the CURRENT row of the returned query is the ONLY row, hence (again) the lack of a loop. As the result of our query would return something like:

+-----------------------------------------------+
| quote                                         |
+-----------------------------------------------+
| You're CLINICALLY MENTAL!                     |
+-----------------------------------------------+

Our variable (or array) would literally look something like:

Array ( "quote" = "You're CLINICALLY MENTAL!" )

Which leads us on to our last line:

$sQuoteOfTheDay = $aRow['quote'];

Which just assigns the value of ‘$aRow['quote']‘ to the variable ‘$sQuoteOfTheDay’. In other words, ‘$sQuoteOfTheDay’ now has the value of a random quote pulled from the database of quotes.

To use this in an HTML page, we would simply just use this (AFTER the above code has grabbed the random quote from the DB for us):

echo $sQuoteOfTheDay;

Which will output the quote of the day somewhere in the HTML code.

As I said at the beginning, this can be extended easily to pull an image for a banner by simply changing the quotes table to store image paths such as ‘images/my_image.png’ which can then be pulled in the same way, and then output similar to the following:

My Image

Obviously we changed the variable name here to $sImageOfTheDay just to keep things constant.

Hope this has helped someone!

Posted in MySQL, PHP at February 9th, 2008. 3 Comments.

PHP Class Tutorial

Easy to follow PHP class tutorial (which is Object Orientated Programming – OOP). I’m not sure how to start this one… It can be quite difficult to understand PHP classes at first, but hopefully I’ll make everything seem easy! Let’s just get stuck in shall we…

Read More…

Posted in PHP at February 9th, 2008. 27 Comments.

Moving House!

Wooo! Well I’ll be moving house on Tues 12th Feb, right before my birthday too!

Not that there have been lots of posts recently, but just so you know that there won’t be many over the next week or so.

Posted in Asides at February 8th, 2008. No Comments.

What Beautiful PHP & AJAX Looks Like

I recently saw an image demonstrating What Beautiful HTML Looks Like. I’ve decided to do my own What Beautiful PHP and AJAX Looks Like image. You can also play with the actual application that this image demonstrates if you so wish!

The Source

This example makes use of the Prototype JavaScript library. I’m using this, as it simplifies AJAX calls, and keeps this tutorial simple. You can view the full source here, which you can view, copy and include in your AJAX applications. It contains suffice comments which should help you understand how everything works.

Credit for the email validation goes to ILoveJackDaniels. It’s not bullet-proof, but suffice for this example.

Comments would be much appreciated on this blog entry. Positive and constructive only.

Posted in AJAX, PHP at November 13th, 2007. 9 Comments.