Fixing strtotime -1 month

There is a bug for strtotime() when you are on the last day of a month that has 31 days in it. The function, strotime(‘-1 month’) will return the beginning of the current month, or put another way, 30 days prior. Needless to say, this is annoying. However, it doesn’t come up very often, and there is a way to fix things: by rolling back the clock 3 extra days. I ran into this problem on a different personal project, and wrote the following function to address the issue. Whenever using strtotime() and negative months, switch in strtotimefix() instead:

function strtotimefix($val,$timestamp=0){
	if ($timestamp==0){ $timestamp = time(); }
	if (date('m') == date('m',strtotime('-1 month'))){
		$timestamp = strtotime('-3 days',$timestamp);
	}else{
		if($timestamp==0){$timestamp = time();}
	}
	$strtotime = strtotime($val,$timestamp);
	return $strtotime;
}

So what’s happening? Basically, the function will check if the numeric month is the same between the current month and the month through ‘-1 month’. If so, it subtracts 3 days from the current timestamp, then runs through the strtotime function using the new timestamp. If everything is fine, nothing is altered, so you don’t have to worry that using the strtotimefix() function will break a perfectly normal strtotime(‘-1 month’) call. Be advised that if you are not doing a call with ‘-x month’, the function will return an incorrect timestamp by 3 days (I hope to update it to be self-aware and only ‘fix’ when the bug would be introduced).

Updated on March 30, 2010:
Changed it to -3 days to deal with February/March.

Common Regular Expressions

I’ve gotten better and more comfortable with regular expressions as time has passed, and sometimes I spend timing wading through google for some common regular expressions I want to put into use, because I’m sure someone has already created it. Well, this isn’t always true (or easy to find), so I decided to collect some common Regular Expressions that may benefit readers. It’s a good idea to keep two things handy if you want to play with Regular Expressions yourself:

Common Regular Expressions:

Date and Time RegEx

Time format (no seconds):
HH:MM am/pm

^([1-9]|1[012]):(0[0-9]|[1-5][0-9])\s?(am|AM|pm|PM)$

Date in mm/dd/yyyy format, with an option for m/d/yyyy (exclude zero’s)

^(0?[1-9]|1[012])[ \/.-](0?[1-9]|[12][0-9]|3[01])[ \/.-](19|20)\d\d$

Date in dd/mm/yyyy format, with an option for d/m/yyyy (exclude zero’s)

^(0?[1-9]|[12][0-9]|3[01])[ \/.-](0?[1-9]|1[012])[ \/.-](19|20)\d\d$

Demographics RegEx

Age in years – max 122

^([0-9]|[1-9][0-9]|[1-9][0-1][0-9]|[1-9]2[0-2])$

Height in Feet and Inches:
6’3″

^([1-8]')?\s?([1-9]|1[01])$

Contact Information RegEx

U.S. Phone Number – parenthesis, periods, dashes, underscore, and spaces are allowed:
(123)456-7890
(123) 456 – 7890
( 123 )456-7890
1234567890
123.456.7890
123-456-7890
123 456 7890

^[\(\s\._-]*\d{3}[\)\s\._-]*\d{3}[\s\._-]*\d{4}$

U.S. Zip Code – 5 or 9 digit with dash

^\d{5}([\-]\d{4}){0,1}$

Email Address – (use preg_match) credit goes to fightingforalostcause.net

/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD

Currency RegEx

Currency – U.S. Dollars and Cents with commas for multiple’s of 1000 and a period for the decimal:
$12,000.23

^\$?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,} (\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$

Currency – British Pounds with commas for multiple’s of 1000 and a period for the decimal:
£12,000.23

^\u00A3?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,} (\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$

Currency – Euros with periods for multiple’s of 1000 and a comma for the decimal:
€12.000,23

^\u20AC?([1-9]{1}[0-9]{0,2}(\.[0-9]{3})*(\,[0-9]{0,2})?|[1-9]{1}[0-9]{0,} (\,[0-9]{0,2})?|0(\,[0-9]{0,2})?|(\,[0-9]{1,2})?)$

Currency – Euros, French style, with spaces for multiple’s of 1000 and a comma for the decimal:
€12 000,23

^\u20AC?([1-9]{1}[0-9]{0,2}(\s[0-9]{3})*(\,[0-9]{0,2})?|[1-9]{1}[0-9]{0,} (\,[0-9]{0,2})?|0(\,[0-9]{0,2})?|(\,[0-9]{1,2})?)$

Testing Regular Expressions with Color Highlighting

Discovered a great website today while working on a complex Regular Expression: RegExPal.com. The site provides color code highlighting for RegEx syntax, including real-time evaluation of test data. If you, for instance, forget to include a closing or opening parenthesis for a group inside the regular expression, the orphaned parenthesis will be highlighted in red for easy identification of the error.

Here is a quick screenshot of some of the highlighting in action:
RegExPal Screenshot

Be advised that this is based on JavaScript regular expressions, which are comparable to the PERL compatible RegEx functions, such as preg_replace() and preg_match(). It’s a good idea to get familiar with this syntax, as ereg() and eregi() style functions will be removed from PHP6 when it is released, sometime in the future. Make sure to also checkout the Regular Expressions Cookbook contributed to by the author of RegExPal.com.

Use isset() Instead of strlen()

This tip is courtesy of a great article, 10 Advanced PHP Tips Revisited

When referencing an array’s value via a numeric key, you follow the variable name ($variable) with the numeric index, enclosed by square brackets [5]. e.g. $variable[5] = ‘value’
However, when $variable represents a string, using the same syntax will return a string with the character at the position specified by the numeric index (0 marks the first character in the $variable string). An example:

$string = 'abcdefg';
var_dump($string[2]);

Output: string(1) “c”

Where this comes into play is when using isset() rather than strlen(). Consider the following example:

$string = 'abcdefg';
if (isset($string[5])){
  echo $string[5].' found!';
}

Output: f found!

$string = 'abcdefg';
if (isset($string[7])){
     echo $string[7].' found!';
  }else{
     echo 'No character found at position 7!';
}

Output: No character found at position 7!

This is faster than using strlen() because, “… calling a function is more expensive than using a language construct.” It’s little tricks like this that will keep your code lean and efficient. Thanks to Chris Shiflett and Sean Coates for their contributions to the referenced article.

Display a Query String Value on a Web Page

It seems simple, almost basic, but many people want to display the contents of a query string on a page for the user or just for troubleshooting purposes. Everyone does it, everyone needs to do it, and there are a few different options I’m going to introduce below. First, our sample URL:

https://www.phpreferencebook.com/?variable=value&name=Mario%20Lurig&gender=male%21

or

https://www.phpreferencebook.com/?variable=value&name=Mario Lurig&gender=male!
  1. Display the whole string (everything after the question mark)
    • <?php echo $_SERVER['QUERY_STRING']; ?>
      • variable=value&name=Mario%20Lurig&gender=male
  2. Display the whole string decoded (convert %## to original characters)
    • <?php echo urldecode($_SERVER['QUERY_STRING']); ?>
      • variable=value&name=Mario Lurig&gender=male!
  3. Show each variable and value as an array (already decoded)
    • <?php print_r($_GET); ?>
      • Array ( [variable] => value [name] => Mario Lurig [gender] => male!
    • <?php echo '<pre>'; print_r($_GET); echo '< /pre>'; ?>
      • Array
        (
            [variable] => value
            [name] => Mario Lurig
            [gender] => male!
        )
        

There are lots of options from there, so don’t let this be the end of your exploration of how to display a query string value on a page. If you have any great tricks, feel free to share them in the comments below!