php - using strpos() to replace multiple comparisons in an if statement - php

Is it OK to replace multiple comparisons by using strpos()?
Example:
changing
if ( $linecounter == $extra1 || $linecounter == $extra2 || $linecounter == 5 )
{
...
}
to
$ok = ' ' . $extra1 . $extra2 . '5';
if ( strpos($ok, $linecounter) > 0 )
{
...
}

No, it's not OK because that's not what strpos is for. It's easy to find problematic examples in the general case (e.g. $linecounter == 15 and $extra2 == 1 -- the strpos check will succeed when it should not have).
If you want to lose the separate conditions so much, workable alternatives would be either a switch statement or in_array:
switch($linecounter) {
case $extra1: case $extra2: case 5:
// whatever
break;
}
if (in_array($linecounter, [$extra1, $extra2, 5])) {
// whatever
}
As an aside, using strpos with a greater-than-zero test like that is not good style. What you want to say is "if it's found in the string", so write exactly that and lose the "prefix a space" hack:
if ( strpos($extra1 . $extra2 . '5', $linecounter) !== false )

Related

PHP - How to check if string have 0 and 1 or 0 or 1

I have this function:
function return_a_number($source) {
switch ($source) {
case "0&0&0&0":
return 0;
case "0&0&1&1":
return 1;
case "1&1&1&1":
return 2;
}
}
Where $source have an ipotetic number concatenated with &.
How can i return 0 if $source have only '0' characters or 1 if have '0' and '1' characters or 2 if have only '1' characters?
// If there is a 0, ( check if there's also a one -> 1 or 0 ) : else only 1s => 2
return strpos($source, '0') !== false ? ( strpos($source, '1') !== false ? 1 : 0 ) : 2;
You could of course also write a regex, but why make it complicated if it works that simple. You might want to catch an empty string depending on your input.
Here is what the logic in your function should be, easy to understand and covers all three cases. Keep in mind that you must always check for 0 and 1 together first, then do it individually
if (strpos($source, '0') !== false && strpos($source, '1') !== false) {
return 0;
}
elseif (strpos($source, '0') !== false) {
return 1;
}
else {
return 2
}
You can put one more 'elseif' instead of the last 'else' if you might get different result than the 3 outcomes you mentioned

Read string until first comma, then evaluate value of string?

I have a string called $DiscountDescription that can sometimes be populated with data like this:
A43544675, A33540055,
Or like this:
A43544675,
Basically, I can have either one value or two values within it, separated by a comma. I really only need the first value. If there's only one value, it always has a comma and a space after it, which is why in my code below I'm removing the comma and space to evaluate the string.
My current code is below. You can see where I'm only accounting for this if there's one value in the string, but not both. So what I'd like to do is find the comma, and grab everything to the left of the comma, and make that equal to $DiscountDescriptionTrimmed.
$DiscountDescription = $_order->getDiscountDescription();
$DiscountDescriptionTrimmed = substr_replace($DiscountDescription ,"",-2);
if ($DiscountDescriptionTrimmed != '') {
if (substr($DiscountDescriptionTrimmed,0,1) === "e" && strlen($DiscountDescriptionTrimmed) === 11){
$_order->setDiscountDescription('Gift Cards ' . $DiscountDescription);
}
elseif (substr($DiscountDescriptionTrimmed,0,1) === "E" && strlen($DiscountDescriptionTrimmed) === 9){
$_order->setDiscountDescription('Gift Cards ' . $DiscountDescription);
}
elseif (substr($DiscountDescriptionTrimmed,0,1) === "A" && strlen($DiscountDescriptionTrimmed) === 9){
$_order->setDiscountDescription('Gift Cards ' . $DiscountDescription);
}
elseif (strlen($DiscountDescriptionTrimmed) === 17 && substr_count($DiscountDescriptionTrimmed,'-') === 2){
$_order->setDiscountDescription('Gift Cards ' . $DiscountDescription);
}
elseif (strlen($DiscountDescriptionTrimmed) === 8 && ctype_digit($DiscountDescriptionTrimmed)){
$_order->setDiscountDescription('Gift Cards ' . $DiscountDescription);
}
}
You can use strtok() to achieve this:
$DiscountDescriptionTrimmed = strtok($DiscountDescription, ', ');
If you ever needed the second value, you can call strtok() again:
$SecondDiscountDescriptionTrimmed = strtok(', ');
The first line gives the length of first value and second line extracts it.
$length = strpos($DiscountDescription, ',') + 1;
$DiscountDescriptionTrimmed = substr($DiscountDescription, 0, $length);
What about this with simple explode() and getting the 0 th index ?
$DiscountDescription1 = 'A43544675, A33540055,';
$DiscountDescription2 = 'A43544675,';
echo explode(',',$DiscountDescription1)[0];
echo "\n";
echo explode(',',$DiscountDescription2)[0];
Demo : https://eval.in/922189

Converting some PHP code to javascript (foreach equivalent) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
For each in a array. How to do that in javascript?
Hey I was needing some help with finding a good for each equivalent from PHP to javascript. I've tried using jQuery.each() but I'm not sure I've done it correctly.
Here is the code I've been needing to convert. I need to fix each foreach to javascript.
if(calculate){
// got complete, calculate possible solution
// use decimals? Does this work in the form?
foreach(values as valName1 => val1){
foreach(operands as op1){
foreach(values as valName2 => val2){
if(valName2 == valName1)
continue;
foreach(operands as op2){
foreach(values as valName3 => val3){
if(valName3 == valName1 ||
valName3 == valName2)
continue;
foreach(operands as op3){
foreach(values as valName4 => val4){
if(valName4 == valName1 ||
valName4 == valName2 ||
valName4 == valName3)
continue;
foreach(operands as op4){
foreach(values as valName5 => val5){
if(valName5 == valName1 ||
valName5 == valName2 ||
valName5 == valName3 ||
valName5 == valName4)
continue;
parentheses = -1;
if(solve(val5, op4, val4, op3, val3, op2,
val2, op1, val1, solution, parentheses)){
count++;
// Note that since solve() just returns the first result, we won't
// display all possible parentheses ordering when there are multiple
// solutions
if(find_all){
document.write(Solution(val5, op4, val4, op3, val3, op2,
val2, op1, val1, solution, parentheses, find_all);
}
else{
document.write(Solution(val5, op4, val4, op3, val3, op2,
val2, op1, val1, solution, parentheses, find_all);
break;
}
}
parentheses = -1;
}
parentheses = -1;
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!find_all && count) break;
}
if(!count || find_all){
document.write( "Found " . count . " solutions.";
}
}
If you are looking for functions (eg. foreach) dealing with data-sets the underscore.js is a good choice.

PHP Elseif Ternary Operators

I am trying to convert the following code into a Ternary Operator, but it is not working and I am unsure why. I think my problem is that I do not know how to express the elseif operation in ternary format. From my understanding and elseif is performed the same way as an if operation by using the format : (condition) ? 'result'.
if ($i == 0) {
$top = '<div class="active item">';
} elseif ($i % 5 == 0) {
$top = '<div class="item">';
} else {
$top = '';
}
$top = ($i == 0) ? '<div class="active item">' : ($i % 5 == 0) ? '<div class="item">' : '';
$top = ($i == 0) ? '<div class="active item">' : (($i % 5 == 0) ? '<div class="item">' : '');
you need to add parenthesis' around the entire else block
The Ternary Operator doesn't support a true if... else if... else... operation; however, you can simulate the behavior by using the following technique
var name = (variable === 1) ? 'foo' : ((variable === 2) ? 'bar' : 'baz');
I personally don't care for this as I don't find it more readable or elegant. I typically prefer the switch statement.
switch (variable) {
case 1 : name = 'foo'; break;
case 2 : name = 'bar'; break;
default : name = 'bas'; break;
}
Too late probably to share some views, but nevertheless :)
Use if - else if - else for a limited number of evaluations. Personally I prefer to use if - else if - else when number of comparisons are less than 5.
Use switch-case where number of evaluations are more. Personally I prefer switch-case where cases are more than 5.
Use ternary where a single comparison is under consideration (or a single comparison when looping), or when a if-else compare is needed inside the "case" clause of a switch structure.
Using ternary is faster when comparing while looping over a very large data set.
IMHO Its finally the developer who decides the trade off equation between code readability and performance and that in turn decides what out of, ternary vs. if else-if else vs. switch-case, can be used in any particular situation.
//Use this format before reducing the expression to one liner
$var=4; //Change value to test
echo "Format result: ";
echo($var === 1) ? 'one' : //if NB.=> $varname = || echo || print || var_dump(ternary statement inside); can only be (placed at the start/wrapping) of the statement.
(($var === 2) ? 'two' : //elseif
(($var === 3) ? 'three' : //elseif
(($var === 4) ? 'four' : //elseif
'false' //else
))); //extra tip: closing brackets = totalnumber of conditions - 1
// Then echo($var === 1)?'one':(($var === 2)?'two':(($var === 3)?'three':(($var === 4)?'four':'false')));
echo "<br/>";
var_dump("Short result: ", ($var === 1)?'one':(($var === 2)?'two':(($var === 3)?'three':(($var === 4)?'four':'false'))) );

Best way to check for positive integer (PHP)?

I need to check for a form input value to be a positive integer (not just an integer), and I noticed another snippet using the code below:
$i = $user_input_value;
if (!is_numeric($i) || $i < 1 || $i != round($i)) {
return TRUE;
}
I was wondering if there's any advantage to using the three checks above, instead of just doing something like so:
$i = $user_input_value;
if (!is_int($i) && $i < 1) {
return TRUE;
}
Not sure why there's no suggestion to use filter_var on this. I know it's an old thread, but maybe it will help someone out (after all, I ended up here, right?).
$filter_options = array(
'options' => array( 'min_range' => 0)
);
if( filter_var( $i, FILTER_VALIDATE_INT, $filter_options ) !== FALSE) {
...
}
You could also add a maximum value as well.
$filter_options = array(
'options' => array( 'min_range' => 0,
'max_range' => 100 )
);
Learn more about filters.
the difference between your two code snippets is that is_numeric($i) also returns true if $i is a numeric string, but is_int($i) only returns true if $i is an integer and not if $i is an integer string. That is why you should use the first code snippet if you also want to return true if $i is an integer string (e.g. if $i == "19" and not $i == 19).
See these references for more information:
php is_numeric function
php is_int function
The best way for checking for positive integers when the variable can be INTEGER or STRING representing the integer:
if ((is_int($value) || ctype_digit($value)) && (int)$value > 0 ) { // int }
is_int() will return true if the value type is integer. ctype_digit() will return true if the type is string but the value of the string is an integer.
The difference between this check and is_numeric() is that is_numeric() will return true even for the values that represent numbers that are not integers (e.g. "+0.123").
It's definitely heading towards the land of micro-optimisation, but hey: the code I'm working on chews through millions of items every day and it's Friday. So I did a little bit of experimenting...
for ($i = 0; $i < 1000000; $i++) {
// Option 1: simple casting/equivalence testing
if ((int) $value == $value && $value > 0) { ... }
// Option 2: using is_int() and ctype_digit(). Note that ctype_digit implicitly rejects negative values!
if ((is_int($value) && $value > 0) || ctype_digit($value)) { ... }
// Option 3: regular expressions
if (preg_match('/^\d+$/', $value)) { ... }
}
I then ran the above tests for both integer and string values
Option 1: simple casting/equivalence testing
Integer: 0.3s
String: 0.4s
Option 2: using is_int() and ctype_digit()
Integer: 0.9s
String: 1.45s
Option 3: regular expressions
Integer: 1.83s
String: 1.60s
Perhaps unsurprisingly, option 1 is by far the quickest, since there's no function calls, just casting. It's also worth noting that unlike the other methods, option 1 treats the string-float-integer value "5.0" as an integer:
$valList = array(5, '5', '5.0', -5, '-5', 'fred');
foreach ($valList as $value) {
if ((int) $value == $value && $value > 0) {
print "Yes: " . var_export($value, true) . " is a positive integer\n";
} else {
print "No: " . var_export($value, true) . " is not a positive integer\n";
}
}
Yes: 5 is a positive integer
Yes: '5' is a positive integer
Yes: '5.0' is a positive integer
No: -5 is not a positive integer
No: '-5' is not a positive integer
No: 'fred' is not a positive integer
Whether or not that's a good thing for your particular use-case is left as an exercise for the reader...
The other best way to check a Integer number is using regular expression. You can use the following code to check Integer value. It will false for float values.
if(preg_match('/^\d+$/',$i)) {
// valid input.
} else {
// invalid input.
}
It's better if you can check whether $i > 0 too.
preg_match('{^[0-9]*$}',$string))
and if you want to limit the length:
preg_match('{^[0-9]{1,3}$}',$string)) //minimum of 1 max of 3
So pisitive int with a max length of 6:
if(preg_match('{^[0-9]{1,6}$}',$string)) && $string >= 0)
You don't really need to use all three check and if you want a positive integer you might want to do the opposite of what is in your code:
if(is_numeric($i) && $i >= 0) { return true; }
Check Sören's answer for more information concerning the difference between is_int() and is_numeric()
if(preg_match('/^[1-9]\d*$/',$i)) {
//Positive and > 0
}
Rather than checking for int OR string with multiple conditions like:
if ( ctype_digit($i) || ( is_int($i) && $i > 0 ) )
{
return TRUE;
}
you can simplify this by just casting the input to (string) so that the one ctype_digit call will check both string and int inputs:
if( ctype_digit( (string)$i ) )
{
return TRUE;
}
In addition to all the other answers: You are probably looking for ctype_digit. It looks for a string containing only digits.
Definition:
!A = !is_numeric($i)
B = $i < 1
!C = $i != round($i)
Then...
!is_numeric($i) || $i < 1 || $i != round($i) is equal to
!A || B || !C
So:
!A || B || !C = !A || !C || B
Now, using the deMorgan theorem, i.e. (!A || !C) = (A && C), then:
!A || !C || B = (A && C) || B
Now, note that A && C = is_numeric($i) && $i == round($i), but if $i == round($i) is TRUE, then is_numeric($i) is TRUE as well, so we can simplify A && C = C so,
(A && C) || B = C || B =
$i == round($i) || $i < 1
So you just need to use:
$i = $user_input_value;
if ($i == round($i) || $i < 1) {
return TRUE;
}
Laravel 4.2 Validation rule for positive number
It takes only positive numbers including float values.
public static $rules = array(
'field_name' => 'required|regex:/^\d*\.?\d*$/'
);
e.g:20,2.6,06
The first example is using round to verify that the input is an integer, and not a different numeric value (ie: a decimal).
is_int will return false if passed a string. See the PHP manual examples for is_int
To check for positive integer use:
$i = $user_input_value;
if (is_int($i) && $i > 0) {
return true; //or any other instructions
}
OR
$i = $user_input_value;
if (!is_int($i) || $i < 1) {
return false; //or any other instructions
}
Use the one that fits your purpose as they are the same. The following examples demonstrate the difference between is_numeric() and is_int():
is_numeric(0); // returns true
is_numeric(7); // returns true
is_numeric(-7); // returns true
is_numeric(7.2); // returns true
is_numeric("7"); // returns true
is_numeric("-7"); // returns true
is_numeric("7.2"); // returns true
is_numeric("abc"); // returns false
is_int(0); // returns true
is_int(7); // returns true
is_int(-7); // returns true
is_int(7.2); // returns false
is_int("7"); // returns false
is_int("-7"); // returns false
is_int("7.2"); // returns false
is_int("abc"); // returns false
All these answers overlook the fact that the requestor may checking form input.
The is_int() will fail because the form input is a string.
is_numeric() will be true also for float numbers.
That is why the $i == round($i) comes in as it checks for the input being a whole number.
Ok, I know this thread is really old but I share #Jeffrey Vdovjak's opinion: since I was able to find it, it might still help someone else out there.
php's gmp_sign() might be another easy way to check. It works for integer and numeric strings, and returns 1 if a is positive, -1 if a is negative, and 0 if a is zero.
So:
// positive
echo gmp_sign("500") . "\n";
// negative
echo gmp_sign("-500") . "\n";
// zero
echo gmp_sign("0") . "\n";
will output:
1
-1
0
See function manual at http://php.net/manual/en/function.gmp-sign.php
P.S. You'll need to have php_gmp.dll enabled in your .ini file.
This's my solution, hope helpful :
if (is_numeric($i) && (intval($i) == floatval($i)) && intval($i) > 0)
echo "positive integer";
i check if string is numeric, second check to sure it's integer and third to sure it positive
If you use "is_int" the variable must be integer, so it can't be a float value. (no round needed).
if(isset($i) && is_int($i) && $i >= 0){ //0 is technically a postive integer I suppose
return TRUE; //or FALSE I think in your case.
}
I would do something like this:
if ((int) $i > 0) {
// this number is positive
}
The number gets typecast to a positive or negative number depending on the minus sign being at the front. Then compares the typecast number to being greater than 0 to determine if the number is positive.

Categories