Page 1 of 1

Using preg_match in my script

Posted: Thu Dec 21, 2006 8:03 pm
by ironzero
Below is a script that passes data to a from with a URL, using for example: http://www,site,com/index.php?price=500&title=computer

Code: Select all

<?php
function getIt($value){
  if($_GET[$value]){
    return $_GET[$value];
  }else{
    return "";
  }
}?>

<input type="text" name="price" value="<?php echo getIt("price")?>">
<input type="text" name="title" value="<?php echo getIt("title")?>">
I'm still learning PHP, so my question is this...

I want to validate my input using preg_match, (I'm assuming this would be the easiest and most secure method).

How can I modify my script so that preg_match:

ONLY accepts numbers, dollar signs and periods from:

<input type="text" name="price" value="<?php echo getIt("price")?>">

and ONLY accepts values containing letters and numbers from:

<input type="text" name="title" value="<?php echo getIt("title")?>">


I want to use somthing like this:

if (preg_match('/^\d{5}(-\d{4})?$/',$_GET['zip'])) {
$zip = $_GET['zip'];
} else {
die('Invalid ZIP Code format');
}


Thanks!

Posted: Thu Dec 21, 2006 11:42 pm
by Kieran Huggins
You can do better than restrict the character types, you can enforce good form:

Code: Select all

$price = '$25.00'; //all these work
$price = '25.00';
$price = '$25';
$price = '25.00';
$price = '$2,500.00';
$price = '2,500.00';
$price = '$2,500';
$price = '2,500';

echo preg_replace('/^\$?([\d,]+)(\.\d{2})?$/',"$1$2",$price);

// and will output a decimal number, with no dollar sign and with or without a period and 2 decimal places, depending on whether or not they were present.
Want to give the 'title' one a try? I'll be here to help you fix it if it's broken.

Cheers,
Kieran

Posted: Fri Dec 22, 2006 12:12 am
by ironzero
Kieran Huggins wrote:You can do better than restrict the character types, you can enforce good form:

Code: Select all

$price = '$25.00'; //all these work
$price = '25.00';
$price = '$25';
$price = '25.00';
$price = '$2,500.00';
$price = '2,500.00';
$price = '$2,500';
$price = '2,500';

echo preg_replace('/^\$?([\d,]+)(\.\d{2})?$/',"$1$2",$price);

// and will output a decimal number, with no dollar sign and with or without a period and 2 decimal places, depending on whether or not they were present.
Want to give the 'title' one a try? I'll be here to help you fix it if it's broken.

Cheers,
Kieran
Thanks, Kieran. :)

Is preg_replace better than preg_match, in terms of security?

Thanks!

Posted: Fri Dec 22, 2006 1:19 am
by matthijs
I don't think there's any difference in terms of security between them. It all depends on how you use them. What you are doing is using those functions to validate/filter the input. You want to make sure only data you want is allowed as valid and used in the script.

You might also take a look at htmlentities(), a function used to escape data when you output the data to html.

Posted: Fri Dec 22, 2006 2:40 am
by Kieran Huggins
This preg_replace function was designed to return a valid string, if possible. Otherwise, it will return the original string :-(

I should have used the extra parameter so you have a method by which to test the validity:

Code: Select all

$price = preg_replace('/^\$?([\d,]+)(\.\d{2})?$/',"$1$2",$price,'-1',$count);
if($count!=0) // price is valid.. do whatever you want here
Cheers,
Kieran

Posted: Fri Dec 22, 2006 10:42 am
by John Cartwright
Kieran Huggins wrote:This preg_replace function was designed to return a valid string, if possible. Otherwise, it will return the original string :-(

I should have used the extra parameter so you have a method by which to test the validity:

Code: Select all

$price = preg_replace('/^\$?([\d,]+)(\.\d{2})?$/',"$1$2",$price,'-1',$count);
if($count!=0) // price is valid.. do whatever you want here
Cheers,
Kieran
And why can't preg_match() do this? Kind of what it was intended for isn't it?

Posted: Fri Dec 22, 2006 11:01 am
by Kieran Huggins
I figured this would save a little overhead, as the PCRE functions are somewhat costly.