Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Just a slug generator. I'm wondering if this can be simplified any further.

Many thanks.

<?php
function slug($string) {

    // Replace all non letters, numbers, spaces or hypens
    $string = preg_replace('/[^\-\sa-zA-Z0-9]+/', '', mb_strtolower($string));

    // Replace spaces and duplicate hyphens with a single hypen
    $string = preg_replace('/[\-\s]+/', '-', $string);

    // Trim off left and right hypens
    $string = trim($string, '-');

    return $string;
}

echo slug('-- This is an example     of an ------ article   - @@@ ..,.:~&**%$£%$^*'); // outputs "this-is-an-example-of-an-article"

Updated version based on feedback:

<?php
function createSlug($slug) {

    $lettersNumbersSpacesHyphens = '/[^\-\s\pN\pL]+/u';
    $spacesDuplicateHypens = '/[\-\s]+/';

    $slug = preg_replace($lettersNumbersSpacesHyphens, '', $slug);
    $slug = preg_replace($spacesDuplicateHypens, '-', $slug);

    $slug = trim($slug, '-');

    return mb_strtolower($slug, 'UTF-8');
}

echo createSlug('-- This is an example ű of an ------ article   - @@@ ..,.%&*£%$&*(*');
?>
share|improve this question
1  
I've removed the "thanks" because it can be considered noise in posts. I've also mentioned in the edit description that upvotes are always the best way to show thanks on Stack Exchange. See this post for some info behind it. –  Jamal Mar 14 at 15:36
add comment

2 Answers 2

up vote 5 down vote accepted
  1. You could create a few explanatory local variables:

    $lettersNumbersSpacesHypens = '/[^\-\sa-zA-Z0-9]+/';
    $spacesAndDuplicateHyphens = '/[\-\s]+/';
    

    Usage:

    $lettersNumbersSpacesHypens = '/[^\-\sa-zA-Z0-9]+/';
    $slug = preg_replace($lettersNumbersSpacesHypens, '', mb_strtolower($slug));
    
    $spacesAndDuplicateHyphens = '/[\-\s]+/';
    $slug = preg_replace($spacesAndDuplicateHyphens, '-', $slug);
    

    These would eliminate the comments. (I haven't checked the regexps, other names might be more appropriate.)

    Reference: Chapter 6. Composing Methods, Introduce Explaining Variable in Refactoring: Improving the Design of Existing Code by Martin Fowler:

    Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.

    And Clean Code by Robert C. Martin, G19: Use Explanatory Variables.

  2. slug could be renamed to cleanSlug (contains a verb) to describe what the function does.

  3. I'd rename the $string variable to $slug It would be more descriptive, it would express the intent of the variable.

  4. I'd use a whitelist instead of the blacklist. Defining the allowed characters (A-Z, 0-9 etc) would create proper URLs from URLs which contain special characters like é or ű.

share|improve this answer
    
Thanks. I've updated my original question with some changes. Didn't notice the problem with different characters before, this has now been fixed. –  Alex Garrett Mar 14 at 15:28
    
@AlexGarrett: You're welcome. I've updated the answer a little bit. –  palacsint Mar 14 at 15:38
    
Great, I've updated this once again so hopefully it reads a lot better now! –  Alex Garrett Mar 14 at 15:49
add comment

Just a small extension to what has been written. If your slug generator is not for an assignment but for actual deployment a lot of frameworks use slug helpers already. I use Laravel, however Laravel has an entire class so that might be messy.

Before Laravel, Codeigniter was the rapid deploy system and their slug system is pretty robust.

Take a look at the slug file. Now mind you they have formatted it into a class with a lot of comments - but if you omit everything you can compare their's and yours and see where the middle ground can be.

Codeigniter Slug Class

Note - I'm adding this extra bit because as always you shouldn't re-engineer code if its been done and done well.

share|improve this answer
    
Great, thanks for the advice. I actually adapted this code from the Laravel framework. It's for education purposes, so wanted to simplify it so it's easier for beginners to grasp. But I completely agree, good hardened code shouldn't be rewritten if not necessary. –  Alex Garrett Mar 14 at 15:30
    
I recommend the codeigniter's version instead because i had to reverse engineer it for legacy non MVC code and it works better as as stand-alone function rather than a class (once you take out the clutter) –  azngunit81 Mar 14 at 15:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.