Generate Slugs from Strings with PHP

In these days of Web 2.0, no site can survive for long without pretty, mod_rewrite-modified permanent links. Everyone uses it. If you look at the URL for this post, for example, it is timjoh.com/generate-slugs-from-strings-with-php. As you might have guessed, I never typed that hyphenated string–WordPress did it all for me. If your PHP script is fed a string that you want a similar slug from, you can use this handy one-liner, with $string being the string that you want to slug.

1
$slug = str_replace( ' ', '-', preg_replace( '/[^a-z0-9- ]/', '', strtolower( $string ) ) );

Or you could use the neater version:

1
2
3
$slug = strtolower( $string ); // lower-case the string
$slug = preg_replace( '/[^a-z0-9- ]/', '', $slug ); // remove all non-alphanumeric characters except for spaces and hyphens
$slug = str_replace( ' ', '-', $slug ); // substitute the spaces with hyphens

This turns the string I'm an U_G_L_Y string! into the slug im-an-ugly-string. Note that it is often useful to shorten the slug; no-one wants a metre-wide URL. It is also important to check so that the slug doesn’t already exist. We can add to the code a loop that appends an ID number to the slug in case it already exists, making it unique.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$slug = strtolower( $string ); // lower-case the string
$slug = preg_replace( '/[^a-z0-9- ]/', '', $slug ); // remove all non-alphanumeric characters except for spaces and hyphens
$slug = str_replace( ' ', '-', $slug ); // substitute the spaces with hyphens
$i = ''; // start with no appended value
while ( slugExists( $slug . $i ) ) { // if the slug already exists..
    $i++; // increment the appended value
    # it is bad practice to increment a string
    # but in this case, it simplifies the code
}
$slug .= $i; // append the value to the real slug
 
function slugExists( $slug ) {
    # this is just an example function;
    # the real function depends on the layout of your script
    $query = sprintf( 'SELECT post_id FROM posts WHERE post_slug = \'%s\'', // write the MySQL query
        mysql_real_escape_string( $slug ) // escape the string correctly (make sure that magic_quotes_gpc is turned off)
    );
    $result = mysql_query( $query ); // assuming that we are connected to MySQL
    if ( mysql_num_rows( $result ) ) { // if a post with this slug was found..
        return TRUE; // ..this slug exists
    } else { // if not..
        return FALSE; // ..this slug does not exist
    }
}

Now you can slug whatever you want, without fearing collisions. This means that you can even use the slug column as an ID instead of post_id in this example.

Maybe Related?

3 Comments »

  1. I believe you wanted
    $slug = str_replace( ‘ ‘, ‘-’, $slug ); // substitute the spaces with hyphens
    for line 3, you had a period in the place of a comma.

    Comment by Joe — June 25, 2007 @ 2:10 am

  2. Joe: Of course you’re right. It’s fixed now–thank you.

    Comment by Tim — June 25, 2007 @ 12:22 pm

  3. [...] Generate Slugs from Strings with PHP — Timblog If your PHP script is fed a string that you want a similar slug from, you can use this handy one-liner, with $string being the string that you want to slug. (tags: php utils) [...]

    Pingback by Grant Watson’s links for 2008-09-24 — September 24, 2008 @ 10:02 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment

FireStats iconAnvänder FireStats