I currently have a form containing an input:
<input type="text" name="score" id="score" value="" />
Criteria: I need the value in this input to be below 40 and a positive integer or zero.
Having read up on php.net about is_int() and is_numeric(). It advises using is_numeric() with form fields as these are always numeric strings.
I want to check if the value meets the above criteria but don't follow how I would do this in the above situation.
<?php
$score = $_POST['score'];
if(is_numeric($score) && $score <= 40){
// Do good stuff
} else {
// Don't do good stuff
} ?>
My issue with the above is that floats would pass this test and without using something like (int) $score I can't use is_int() which then negates the is_numeric check.
Am I missing something here?
Use ctype_digit() to make sure the string consists only of numbers, and therefore is an integer - technically, this returns true also with very large numbers that are beyond int's scope. Note that this method will not recognize negative numbers.
<?php
$score = $_POST['score'];
if(ctype_digit($score) && $score <= 40){
// Do good stuff
} else {
// Don't do good stuff
}
?>
Related
I need to find whether the given number is cube of an integer.
Question asked in college: Design a PHP page to check if entered number is a cube of an integer in PHP.
In the program below, is_float() is not working to check whether the $num2 is float or not. I don't know why.
<?php
$num=$_POST["t1"];
$num2=pow($num,1/3);
echo $num2."<br>";
$res=$num%$num2;
echo $res."<br><br>";
$test=is_float($num2);
echo "float ".$test."<br>";
var_dump(is_float($num2));
//if($num%$num2==0 || $num%$num2==1)
if (is_float($num2)==TRUE) {
echo"<font color='FF0000' size='+2'>". $num. " is not Cube of an integer</font>";
} else {
echo "<font color='FF0000' size='+2'>". $num. " is a Cube of an integer</font>";
}
?>
I hope your teacher isn't on Stack Overflow ;)
I'm only going to give you some advises, so you can find out the answer by yourself. Come on, it's not that difficult!
Anyway, I posted the solution too.
Have you tried to check which type of number is returning:
pow(27, 1/3);
My guess is PHP will always return a float when you'll ask him to calculate a number with a power less than 1, else an integer.
Solution: The best here would be to check if the result of pow() is equal to the entire part of itself. You can do that with the floor() function (See http://php.net/manual/function.floor.php) :
// ...
$num2 = pow($num, 1/3);
$test = ($num2 == floor($num2))
// ...
How can the below be possible:
$varnum = 4;
if( $varnum/4 - floor($varnum/4) !== 0){
echo 'foo';
}
This echoes 'foo' on my server running PHP 5.1.6. If i change the operator to == I get the same results.
I have no idea why, but could it possibly be because "==" is "equals" and "!==" is "Not identical"? How then would I make them identical? I guess in javaScript I would "parseInt", but there is no such thing in PHP, right?
The reason this fails is because in PHP, the floor function returns a float, despite the fact that the value is always a whole number. You can see this in the documentation here: http://php.net/manual/en/function.floor.php
You're doing a fixed type comparison of that float to an integer zero, so the result is false, regardless of whether the value is actually zero.
To fix this, either:
cast the output of floor to an integer - either intval(float(...)) or (int)float(..)
use != instead of !==.
use 0.0 instead of just 0 to compare against.
In case you're wondering why floor() would return a float rather than an integer, it's because the input is a float. The float data type has a larger possible range than integer, and thus it is possible to call floor() on a value that would be too big to hold in an integer. Therefore it would not be safe for the function to return an integer; it returns a float instead so that it can guarantee the result will be correct.
It may seem odd at first glance, but hopefully that explains the logic behind it for you.
What is it you are trying to accomplish? If you are trying to see if $varnum is divisible by four then use modulus, so...
$varnum = 4;
if ($varnum % 4 != 0) {
echo "foo - $varnum is divisible by 4";
}
You original post should use '!=' versus '!==', like this:
$varnum = 4;
if( $varnum/4 - floor($varnum/4) != 0){
echo 'foo';
}
This problem is best expressed in code:
$var1 = 286.46; // user input data
$var2 = 3646; // user input data
$var3 = 25000; // minumum amount allowed
$var4 = ($var1 * 100) - $var2; // = 250000
if ($var4 < $var3) { // if 250000 < 250000
print 'This returns!';
}
var_dump($var4) outputs: float(25000) and when cast to int, outputs: int(24999) - and thereby lies the problem.
I don't really know what to do about it though. The issue occurs upon multiplication by 100, and while there are little tricks I can do to get around that (such as *10*10) I'd like to know if there's a 'real' solution to this problem.
Thanks :)
This is a horrible hacky solution and I slightly hate myself for it, but this gives the expected behaviour:
<?php
$var1 = 286.46; // user input data
$var2 = 3646; // user input data
$var3 = 25000; // minumum amount allowed
$var4 = ($var1 * 100) - $var2; // = 250000
if ((string) $var4 < (string) $var3) { // if 250000 < 250000
print 'This returns!';
}
Cast them to strings, and they get converted back to int/float as appropriate for the comparison. I don't like it but it does work.
Really you need BC Math for precise floating point mathematics in PHP.
Its always a good idea to use ceil (or floor based on what you want) when using float number as int
In your case try ceil($var4) before comparison!
That's what floats do sometimes, it is all due to how floats are unable to precisely represent integers from time to time.
Instead of casting it to an int, you can round the number to an integer value and then cast it to an int. (possibly that cast unnecessary, but PHP isn't to clear about how such things happen internally, and even if you know how they happen right now, they may not in the future.
I think you could use bccomp for comparing floating point values but i think it's a function that's not in the PHP Core.
Otherwise i found this function here but i couldn't test it to see if it works
function Comp($Num1,$Num2,$Scale=null) {
// check if they're valid positive numbers, extract the whole numbers and decimals
if(!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num1,$Tmp1)||
!preg_match("/^\+?(\d+)(\.\d+)?$/",$Num2,$Tmp2)) return('0');
// remove leading zeroes from whole numbers
$Num1=ltrim($Tmp1[1],'0');
$Num2=ltrim($Tmp2[1],'0');
// first, we can just check the lengths of the numbers, this can help save processing time
// if $Num1 is longer than $Num2, return 1.. vice versa with the next step.
if(strlen($Num1)>strlen($Num2)) return(1);
else {
if(strlen($Num1)<strlen($Num2)) return(-1);
// if the two numbers are of equal length, we check digit-by-digit
else {
// remove ending zeroes from decimals and remove point
$Dec1=isset($Tmp1[2])?rtrim(substr($Tmp1[2],1),'0'):'';
$Dec2=isset($Tmp2[2])?rtrim(substr($Tmp2[2],1),'0'):'';
// if the user defined $Scale, then make sure we use that only
if($Scale!=null) {
$Dec1=substr($Dec1,0,$Scale);
$Dec2=substr($Dec2,0,$Scale);
}
// calculate the longest length of decimals
$DLen=max(strlen($Dec1),strlen($Dec2));
// append the padded decimals onto the end of the whole numbers
$Num1.=str_pad($Dec1,$DLen,'0');
$Num2.=str_pad($Dec2,$DLen,'0');
// check digit-by-digit, if they have a difference, return 1 or -1 (greater/lower than)
for($i=0;$i<strlen($Num1);$i++) {
if((int)$Num1{$i}>(int)$Num2{$i}) return(1);
else
if((int)$Num1{$i}<(int)$Num2{$i}) return(-1);
}
// if the two numbers have no difference (they're the same).. return 0
return(0);
}
}
}
The problem is that floats just cannot represent some numbers. Since PHP doesn't have a "decimal" (or other fixed-point) type, you can basically only hack your way around these problems.
Assuming the first number in your example $var1 = 286.46 denotes some kind of money, you could just convert that to cents directly after the user entered it (e.g. through stripping the point and reading it as an integer) and thus calculate everything using integer math.
That's not a general solution - and I doubt that one exists (short of using arbitrary precision numbers, which some PHP extensions provide - but I that smells like overkill to me).
How do I check and see if a user enters only numbers and is at least 4 numbers long using PHP?
Mark Byers' suggestion is good, but here's another way:
$valid = ctype_digit($number) && strlen($number) >= 4;
You could use a regular expression:
/^\d{4,}$/
Example usage:
$s = "7325";
if (preg_match('/^\d{4,}$/', $s)) {
echo "matches";
}
ctype_digit() && strlen() wins
<?php
function benchmark($callback){
echo sprintf('%-30s: ', $callback);
$t = microtime(true);
foreach(range(1, 10000) as $n){
call_user_func($callback);
}
echo (microtime(true)-$t)."\n";
}
function mark_byers_preg_match(){
$s = "7325";
preg_match('/^\d{4,}$/', $s);
}
function notjim_ctype_digit_strlen(){
$number = 7325;
ctype_digit($number) && strlen($number) >= 4;
}
function tomalak_intval_broken(){
$check = 7325;
intval($check) == $check && $check >= 1000 && $check <= 9999;
}
benchmark('mark_byers_preg_match');
benchmark('notjim_ctype_digit_strlen');
benchmark('tomalak_intval_broken');
?>
results
mark_byers_preg_match : 0.029040098190308
notjim_ctype_digit_strlen : 0.026585817337036
tomalak_intval_broken : 0.019872903823853
Note: #Tomalak's does not work with numbers starting with 0 so it does not qualify
Edit: #kiethjgrant's solution was removed because intval(0000) evaluates as false when it should be true.
Do you have any example code to start with?
To strictly answer your question, you could use a regex like if(preg_match('/^\d{4,}$/', $input)....
But there's a lot more to consider here: you need to consider both validation and filtering (and you're best to keep the two separate issues). If you're strictly checking for an integer, then I suppose you're safe from SQL injection, XSS, etc., but you really need to have a handle on those issues, because sooner or later you're going to need to filter & validate something other than a simple integer.
you should always use the most efficient way to do it
if ( is_numeric($imput) && isset($input[3]) )
{
// your code
}
isset() is a language construct, which is always faster than strlen().
isset($input[n-1]) tells you whether string(data which passes through form is always string) has at least n long.
is_numeric() checks it is a valid num string.
i think it is better than ctype_digit() && strlen().
I have a variable that is definited by a POST call from a form where it is inputed into a text field. Is there any way to convert this variable to an interger?
From the form:
Lenght: <input name="length" value="10" type="text" id="lenght" size="2" />
From the php code:
$length = $_POST['lenght'];
$url = substr($url, 0, $length);
This doesn't seem to work and the only reason why I think it isn't working is because $lenght is defined as text and not an interger.
Two things:
It doesn't work because you misspelled length <-> lenght
The correct way to convert a string to an integer is using the function intval.
$length = intval($_POST['length']);
$url = substr($url, 0, $length);
It likely doesn't work because you misspelled length twice, instead of zero or three times.
Seems to be a spelling error in your code: length vs. lenght - that could be your problem right there.
To do an explicit conversion, use the intval() function
$length = intval($_POST['length']);
Ignoring the misspellings of 'length' above, there are a few ways to explicitly convert a string into an integer in PHP. Usually this conversion will happen automatically. Take the following code:
$numeric_string = '42';
echo ($numeric_string * 2);
This will print out "84", as expected. See the reference on Type-Juggling.
If you KNOW that the string you have is a number (perhaps by checking is_numeric()) then you can either cast the variable to an Integer
$numeric_string = '42';
$converted_integer = (int) $numeric_string;
// or
$converted_integer = (integer) $numeric_string;
or use intval()
$numeric_string = '42';
$converted_integer = intval($numeric_string);
An important point to remember about intval() is that it will return a 0 if it can't resolve the string into an Integer. This could (potentially) give you a second way to check for errors (after is_numeric()), or it could cause unexpected results if you aren't properly insuring that the variable is numeric to begin with.
If you are sure that the value you are looking at has a correct representation for the type you want to convert to, you can also use a vanilla type cast operation:
$int = (int) "1"; // var_dump($int) => int(1)
$float = (float) "1.2345"; // var_dump($float) => float(1.2345)
Beware of incorrect representations of the variable that you are converting though, i.e casting "a random string" to a number might not yield the results you expect. If you are handling user input, you're better of using the above suggested solutions with function calls such as intval and floatval
That is because the PHP Web Server uses the name tag instead of the id tag. Even though the id is lenght, the name tag also has to be lenght, or it will malfunction.