How to validate and sanitize a URL in symfony

This validator works for symfony 1.4 and is not necessarily backward compatible.

If you’d like to both validate and sanitize a URL in symfony, it’s pretty easy. First, put the following code in lib/myValidatorUrl.class.php:

<?php
 
/**
 * myValidatorUrl validates and sanitizes a URL.
 *
 * @author Jason Swett (http://jasonswett.net/how-to-validate-and-sanitize-a-url-in-symfony)
 */
class myValidatorUrl extends sfValidatorUrl
{
  protected function doClean($value)
  {
    $clean = (string) $value;
 
    // If the URL doesn't start with "http", add "http://".
    if (!preg_match('/https?:\/\/.+/', $clean))
    {
      $clean = 'http://'.$clean;
    }
 
    // Add a trailing slash if the URL doesn't have one.
    if (!preg_match('/https?:\/\/.+\//', $clean))
    {
      $clean .= '/';
    }
 
    // If the URL still isn't valid after that, it probably wasn't close enough to begin with.
    if (!preg_match($this->generateRegex(), $clean))
    {
      throw new sfValidatorError($this, 'invalid', array('value' => $value));
    }
 
    return $clean;
  }
}

Then, in the form where you have your URL field, add the following line to your configure() method:

$this->validatorSchema['url'] = new myValidatorUrl(array('required' => false));

That’s all! Now, if someone enters a URL like “example.com”, it will get saved as “http://example.com/”.

6 Responses to “How to validate and sanitize a URL in symfony”

  1. davide says:

    Why would you want to add a trailing slash?

    This way the url http://www.example.com/foo.html will become http://www.example.com/foo.html/, which is not the a good behavior…

  2. jason says:

    I want to add a trailing slash because I’m trying to normalize the URL. You’re right, though; it shouldn’t just blindly add a trailing slash.

    I think maybe this is what I want to do: if the URL doesn’t match the following regular expression, a slash needs to be added.

    https?://.+/
  3. jason says:

    Update: I’ve edited the post to use the above regex instead of the method I was using before.

  4. Mohammad says:

    I think there is a small mistake above…

    $this->validatorSchema['url'] = new myValidatorPhone(array(‘required’ => false));

    should be:

    $this->validatorSchema['url'] = new myValidatorUrl(array(‘required’ => false));

  5. jason says:

    Woops! Thanks for pointing that out, Mohammad. I fixed it.

  6. Ankit says:

    Thanks Jason.

    One small improvement to check the max length and min length of the Urls. We can add

    $clean = sfValidatorString::doClean($value); instead of $clean = (string) $value;

    Cheers,
    Ankit