Will
Will

Reputation: 295

PHP - Checking Character Type and Length and Trimming Leading Zeros

I have this code that works well, just inquiring to see if there is a better, shorter way to do it:

$sString = $_GET["s"];

if (ctype_digit($sString) == true) {
    if (strlen($sString) == 5){
        $sString = ltrim($sString, '0');
    }
}

The purpose of this code is to remove the leading zeros from a search query before passing it to a search engine if it is 5 digits and. The exact scenario is A) All digits, B) Length equals 5, and C) It has leading zeros.

Better/Shorter means in execution time...

Upvotes: 0

Views: 77

Answers (2)

RobIII
RobIII

Reputation: 8821

$sString = $_GET["s"];

if (preg_match('/^\d{5}$/', $sString)) {
    $sString = ltrim($sString, '0');
}

This is shorter (and makes some assumptions you're not clear about in your question). However, shorter is not always better. Readability is sacrificed here, as well as some performance I guess (which will be negligable in a single execution, could be "costly" when run in tight loops though) etc. You ask for a "better, shorter way to do it"; then you need to define "better" and "shorter". Shorter in terms of lines/characters of code? Shorter in execution time? Better as in more readable? Better as in "most best practices" applied?

Edit:

So you've added the following:

The purpose of this code is to remove the leading zeros from a search query before passing it to a search engine if it is 5 digits and. The exact scenario is A) All digits, B) Length equals 5, and C) It has leading zeros.

A) Ok, that clears things up (You sure characters like '+' or '-' won't be required? I assume these 'inputs' will be things like (5 digit) invoicenumbers, productnumbers etc.?)

B) What to do on inputs of length 1, 2, 3, 4, 6, 7, ... 28? 97? Nothing? Keep input intact?

Better/Shorter means in execution time...

Could you explain why you'd want to "optimize" this tiny piece of code? Unless you run this thousands of times in a tight loop the effects of optimizing this will be negligible. (Mumbles something about premature, optimization, root, evil). What is it that you're hoping to "gain" in "optimizing" this piece of code?

I haven't profiled/measured it yet, but my (educated) guess is that my preg_match is more 'expensive' in terms of execution time than your original code. It is "shorter" in terms of code though (but see above about sacrificing readability etc.).

Long story short: this code is not worth optimizing*; any I/O, database queries etc. will "cost" a hundred, maybe even thousands of times more. Go optimize that first

* Unless you have "optimized" everything else as far as possible (and even then, a database query might be more efficient when written in another way so the execution plan is mor eefficient or I/O might be saved using (more) caching etc. etc.). The fraftion of a millisecond (at best) you're about to save optimizing this code better be worth it! And even then you'd probably need to consider switching to better hardware, another platform or other programming language for example.

Edit 2:

I have quick'n'dirty "profiled" your code:

$start = microtime(true);

for ($i=0; $i<1000000;$i++) {
  $sString = '01234';
  if (ctype_digit($sString) == true) {
    if (strlen($sString) == 5){
      $sString = ltrim($sString, '0');
    }
  }
}

echo microtime(true) - $start;

Output: 0.806390047073 So, that's 0.8 seconds for 1 million(!) iterations. My code, "profiled" the same way:

$start = microtime(true);

for ($i=0; $i<1000000;$i++) {
  $sString = '01234';
  if (preg_match('/^\d{5}$/', $sString)) {
    $sString = ltrim($sString, '0');
  }
}

echo microtime(true) - $start;

Output: 1.09024000168 So, it's slower. As I guessed/predicted.

Note my explicitly mentioning "quick'n'dirty": for good/accurate profiling you need better tools and if you do use a poor-man's profiling method like I demonstrated above then at least make sure you average your numbers over a few dozen runs etc. to make sure your numbers are consistent and reliable.

But, either solution takes, worst case, less than 0,0000011 to run. If this code runs "Tens of Thousands of times a day" (assuming 100.000 times) you'll save exactly 0.11 seconds over an entire day IF you got it down to 0! If this 0.11 seconds is a problem you have a bigger problem at hand, not these few lines of code. It's just not worth "optimizing" (hell, it's not even worth discussing; the time you and I have taken going back-and-forth over this will not be "earned back" in at least 50 years).

Lesson learned here: Measure / Profile before optimizing!

Upvotes: 2

AbraCadaver
AbraCadaver

Reputation: 78994

A little shorter:

if (ctype_digit($sString) && strlen($sString) == 5) {
        $sString = ltrim($sString, '0');
}

It also matters if you want "digits" 0-9 or a "numeric value", which may be -1, +0123.45e6, 0xf4c3b00c, 0b10100111001 etc.. in which case use is_numeric.

I guess you could also just do this to remove 0s:

$sString = (int)$sString;

Upvotes: 0

Related Questions