Validate terminal command in PHP

Testing if a function exists in PHP is easy. Testing if a command exists on the system is also easy.

I’ve never really run into the problem of having to create a compatibility suite script to make sure my PHP script will run without trouble. Simple things like checking the version of PHP installed or the version of MySQL are straightforward. This time though, I needed to make sure a command line program existed on the system which I invoke using exec().

First and foremost, we need to check that exec() exists and we can use it. If it does, we then need to use it to execute a command on the server which will output the path to our command. I will be testing for tar in the example.

if( function_exists('exec') )
{
    // send test command to system
    exec('command -v tar >& /dev/null && echo "Found" || echo "Not Found"', $output);

    if( $output[0] == "Found" )
    {
        // command is available
        return TRUE;
    }
    else
    {
        // command is unavailable
        return FALSE;
    }
}

Our focus will be this line:

exec('command -v tar >& /dev/null && echo "Found" || echo "Not Found"', $output);

In the first part of the command we will run command with the -v option. The -v option causes the output of the command to be displayed or return zero if the command is not found. Here’s a short description of the command:

SYNTAX
    command [-pVv] command [arguments ...]
OPTIONS
    -P  Use a default path
    -v  Verbose
    -V  More verbose

The next part of the command we use >& which is a metacharacter in Unix which tells the command to redirect the standard output and standard error. Which in this case, we redirect the output to a file /dev/null. We do this because we want to handle the response of the command with the last part.

The last part of the command we use && which is another metacharacter which tells Unix to execute the following command only if the preceding command succeeds. We also use the || metacharacter which tells Unix to execute the following command if the preceding command fails. To understand it better, it’s just like writing an if-then-else statement:

If( command -v tar >& /dev/null ) Then
    echo "Found"
Else
    echo "Not Found"
End If

Now we need to bring the response back to PHP. We do that with the second parameter of exec(); $output. Every line of output from the command will be returned in $output as an array which we can then run our conditional against.

Short, simple, easy little command. Just replace tar with the command you’d like to check for. You could even take the code and place it into a function to make it easily reusable.

Don’t Hard Code Your Age!

Even though this is not at all as important as not hardcoding copyright years. It can still a time saver if you happen to hard code your age into a biography on a website.

Lets make those ages DYNAMIC!

I wrote a little code snippet which updates your age automatically. All you do is enter your birth date and php does the rest! I will use my birthday in the example:

$birth_date = getdate(strtotime("August 1st 1988")); $current_date = getdate(time()); echo ($current_date['mday'] >= $birth_date['mday'] AND $current_date['mmonth'] >= $birth_date['mmonth']) ? ($current_date['year'] - $birth_date['year']) : (($current_date['year'] - $birth_date['year']) - 1);

This would return 21, which is how old I am currently. If the current time was July 31st 2009, it would return 20. I made sure it checked both the day and month, not just subtract the years, to figure out the date. Just replace “August 1st 1988″ with your birth date.

It’s that Simple.

CodeIgniter’s alternator() function


It’s surprising to me how often I find little functions for tedious tasks, that CodeIgniter already has built in. One of these functions is the alternator() function in the String Helper.

To begin using this function, make sure you have loaded the String Helper with the following code:

$this->load->helper('string');

What the alternator() function does is allow two or more items to be alternated between when iterating through a loop. Example from the CodeIgniter User Guide:

for($i = 0; $i < 10; $i++)
{
	echo alternator('string one', 'string two');
}

There is also no limit to how many parameters you can have:

...
echo alternator('one', 'two', 'three', 'four', 'five');
...

Put it to Use

What would you ever need that for? Well, what about if you are creating a list of items and every other needs class="alt" attached to it for styling differences? I run into this issue all the time.

This is how I used to do it:

<ul>
	<?php $count = 1; ?>
	<?php foreach($list as $item) : ?>
		<?php (empty($count)) ? $count = 1 : $count = 0; ?>
		<li <?=($count == 1) ? 'class="alt"' : ''?>>
			<?=$item?>
		</li>
	<?php endforeach; ?>
</ul>

And this is with the alternator() function:

<ul>
	<?php foreach($list as $item) : ?>
		<li <?=alternator('class="alt"', '')?>>
			<?=$item?>
		</li>
	<?php endforeach; ?>
</ul>

The alternator() function makes the ability to do this, much easier and cleaner than my original way. Hopefully I’ve helped someone out who had no idea this function was available.

Validate a Credit Card Number

This code snippet is a regular expression which checks or validates a credit card number.

The Expression

^([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{2,4})$

This regular expression will match any of the following credit card number formats:

  • 0000-0000-0000-0000
  • 0000-0000-0000-000
  • 0000-0000-0000-00
  • 0000 0000 0000 0000
  • 0000 0000 0000 000
  • 0000 0000 0000 00
  • 0000000000000000
  • 000000000000000
  • 00000000000000

Validate Function

Here is a quick and simple validation function for a credit card number using the regular expression above and PHP’s preg_match() function:

function validate_credit_card_number($string)
{
	if(preg_match('/^([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{2,4})$/', $string))
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

Modify the Data

$string = "1234123412341234";
preg_match('/^([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{4})[-|s]*([0-9]{2,4})$/', $string, $matches);
$new_string = $matches[1] . '-' . $matches[2] . '-' . $matches[3] . '-' . $matches[4];

// New String:
// 1234-1234-1234-1234

There you go! If you find you need another format or you’d like a different type of string to validate, please send me an email and I will respond as quickly as I can.

Validate a Phone Number

This code snippet is a regular expression which checks or validates a phone number.

The Expression

^[+]?([0-9]?)[(|s|-|.]?([0-9]{3})[)|s|-|.]*([0-9]{3})[s|-|.]*([0-9]{4})$

This regular expression will match any of the following U.S. numbers:

  • 555 555 5555
  • (555) 555-5555
  • (555)555-5555
  • 555-555-5555
  • 555.555.5555
  • 5555555555
  • 0-000-000-0000
  • 0.000.000.0000
  • 0 000 000 0000
  • 00000000000
  • +0-000-000-0000
  • +0.000.000.0000
  • +0 000 000 0000
  • +00000000000

Why so many matches? I think it’s better, and easier to take a users input and alter it to our specifications, rather than make the user follow our guidelines.

Validate Function

Here is a quick and simple validation function for a phone number using the regular expression above and PHP’s preg_match() function:

function validate_phone_number($string)
{
	if(preg_match('/^[+]?([0-9]?)[(|s|-|.]?([0-9]{3})[)|s|-|.]*([0-9]{3})[s|-|.]*([0-9]{4})$/', $string))
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

Modify the Data

After checking to see if the data is correct, we need to format it the way we need/want it. It’s always good to keep everything consistent.

To re-write the data, pass a third parameter to the preg_match() function, I will be using $matches. PHP will save the captures (anything wrapped in parenthesis inside the regex) to that variable, as an array.

$string = "(555) 555-5555";
preg_match('/^[+]?([0-9]?)[(|s|-|.]?([0-9]{3})[)|s|-|.]*([0-9]{3})[s|-|.]*([0-9]{4})$/', $string, $matches);
$new_string = $matches[2] . '-' . $matches[3] . '-' . $matches[4];

// New String:
// 555-555-5555

There you go! If you find you need another format or you’d like a different type of string to validate, please send me an email and I will respond as quickly as I can.