Turn zero filled numbers into whole numbers - php

I have a selection of nubmers which are prefixed with zeros to give them a set length.
0001,0230,1000,0007,0300
How could I make these whole number? So that the resulting numbers are
1,230,1000,7,300
I was using sprintf("%04d", $input); to generate the numbers, is there a reverse of this?
Thanks

If you feel safe that you have numbers and not another kind of string, you can just cast to integer:
(int) $num;
Demo: http://codepad.org/VQrA50fK
Just be aware that a non-integer (like a string with letters) will cast to 0.

Check out the intval function. Just pass them in and they'll be converted to ints. You can then append them to a sting to make them strings again.

Related

PHP formatting of positive and negative floating point numbers with leading zeros

Scenario:
To trim leading zeros from positive and negative floating point numbers
Input:
000.123
00.123
01.123
-001.123
-00.123
-040.123
Desired output:
0.123
0.123
1.123
-1.123
-0.123
-40.123
Question:
Is there an inbuilt function which will make this specific formatting easier and more efficient than running each number through combinations of substr(), strpos(), explode() and if statements?
I guess your numbers are saved as a string, so in order to get your output you just simple cast them to a float or double like this:
echo (float) $number;
For more information about casting see the manual: http://php.net/manual/en/language.types.type-juggling.php#language.types.typecasting
Just cast it as float
Like this example:
<?php
$number = '-000.220';
echo (float)$number;
This way you remove all leading zeros, either being a positive or negative number

Trim zeros to the right of a decimal place and decimal point often

I have been handling long numbers in PHP. Like the following examples.
12.020000
12.000000
To get rid of trailing zeros and the decimal point I have been using the following inside a function.
return rtrim(rtrim($str, "0"),".");
So the above turns out like.
12.02
12
It was a bit short sighted as when 1000 gets entered it gets turned into 1.
Can someone please help me with the code to remove trailing zeros after the decimal point only?
Bonus points if the code removes the decimal place but I can always feed it into rtim($str,".").
EDIT: To be clear, I am stripping the decimal place and zeros only when displaying to the screen. Also casting to float is not an option as I also handle numbers like 0.00000001 which come out like 1.0e-9 sort of thing.
Why are you using string to hold numbers? Cast it to float and it'll solve your problem.
$string = '12.020000';
$number = (float) $string; // will be 12.02
Then, if you want to use it as string (but why?)
$string = (string) $number;
The thing that perplexes me about your question is that extra zeros won't be included in a number variable without intentionally adding them with number_format. (This may be why someone down-voted it).
Normally you don't want to use string functions (meant for text) on variables that hold numbers. If you want to round off a number, use a function like round.
http://php.net/manual/en/function.round.php
There's also number_format, which can format numbers by adding zero padding: (it doesn't actuall round, just trims off excess numbers).
http://php.net/manual/en/function.number-format.php
Since your zeros are appearing, it's likely that you simply need to multiple the variable by 1, which will essentially convert a string to a number.
Good luck!

PHP is_numeric or preg_match 0-9 validation

This isn't a big issue for me (as far as I'm aware), it's more of something that's interested me. But what is the main difference, if any, of using is_numeric over preg_match (or vice versa) to validate user input values.
Example One:
<?php
$id = $_GET['id'];
if (!preg_match('/^[0-9]*$/', $id)) {
// Error
} else {
// Continue
}
?>
Example Two:
<?php
$id = $_GET['id'];
if (!is_numeric($id)) {
// Error
} else {
// Continue
}
?>
I assume both do exactly the same but is there any specific differences which could cause problems later somehow? Is there a "best way" or something I'm not seeing which makes them different.
is_numeric() tests whether a value is a number. It doesn't necessarily have to be an integer though - it could a decimal number or a number in scientific notation.
The preg_match() example you've given only checks that a value contains the digits zero to nine; any number of them, and in any sequence.
Note that the regular expression you've given also isn't a perfect integer checker, the way you've written it. It doesn't allow for negatives; it does allow for a zero-length string (ie with no digits at all, which presumably shouldn't be valid?), and it allows the number to have any number of leading zeros, which again may not be the intended.
[EDIT]
As per your comment, a better regular expression might look like this:
/^[1-9][0-9]*$/
This forces the first digit to only be between 1 and 9, so you can't have leading zeros. It also forces it to be at least one digit long, so solves the zero-length string issue.
You're not worried about negatives, so that's not an issue.
You might want to restrict the number of digits, because as things stand, it will allow strings that are too big to be stored as integers. To restrict this, you would change the star into a length restriction like so:
/^[1-9][0-9]{0,15}$/
This would allow the string to be between 1 and 16 digits long (ie the first digit plus 0-15 further digits). Feel free to adjust the numbers in the curly braces to suit your own needs. If you want a fixed length string, then you only need to specify one number in the braces.
According to http://www.php.net/manual/en/function.is-numeric.php, is_numeric alows something like "+0123.45e6" or "0xFF". I think this not what you expect.
preg_match can be slow, and you can have something like 0000 or 0051.
I prefer using ctype_digit (works only with strings, it's ok with $_GET).
<?php
$id = $_GET['id'];
if (ctype_digit($id)) {
echo 'ok';
} else {
echo 'nok';
}
?>
is_numeric() allows any form of number. so 1, 3.14159265, 2.71828e10 are all "numeric", while your regex boils down to the equivalent of is_int()
is_numeric would accept "-0.5e+12" as a valid ID.
Not exactly the same.
From the PHP docs of is_numeric:
'42' is numeric
'1337' is numeric
'1e4' is numeric
'not numeric' is NOT numeric
'Array' is NOT numeric
'9.1' is numeric
With your regex you only check for 'basic' numeric values.
Also is_numeric() should be faster.
is_numeric checks whether it is any sort of number, while your regex checks whether it is an integer, possibly with leading 0s. For an id, stored as an integer, it is quite likely that we will want to not have leading 0s. Following Spudley's answer, we can do:
/^[1-9][0-9]*$/
However, as Spudley notes, the resulting string may be too large to be stored as a 32-bit or 64-bit integer value. The maximum value of an signed 32-bit integer is 2,147,483,647 (10 digits), and the maximum value of an signed 64-bit integer is 9,223,372,036,854,775,807 (19 digits). However, many 10 and 19 digit integers are larger than the maximum 32-bit and 64-bit integers respectively. A simple regex-only solution would be:
/^[1-9][0-9]{0-8}$/
or
/^[1-9][0-9]{0-17}$/
respectively, but these "solutions" unhappily restrict each to 9 and 19 digit integers; hardly a satisfying result. A better solution might be something like:
$expr = '/^[1-9][0-9]*$/';
if (preg_match($expr, $id) && filter_var($id, FILTER_VALIDATE_INT)) {
echo 'ok';
} else {
echo 'nok';
}
is_numeric checks more:
Finds whether the given variable is numeric. Numeric strings consist
of optional sign, any number of digits, optional decimal part and
optional exponential part. Thus +0123.45e6 is a valid numeric value.
Hexadecimal notation (0xFF) is allowed too but only without sign,
decimal and exponential part.
You can use this code for number validation:
if (!preg_match("/^[0-9]+$/i", $phone)) {
$errorMSG = 'Invalid Number!';
$error = 1;
}
If you're only checking if it's a number, is_numeric() is much much better here. It's more readable and a bit quicker than regex.
The issue with your regex here is that it won't allow decimal values, so essentially you've just written is_int() in regex. Regular expressions should only be used when there is a non-standard data format in your input; PHP has plenty of built in validation functions, even an email validator without regex.
PHP's is_numeric function allows for floats as well as integers. At the same time, the is_int function is too strict if you want to validate form data (strings only). Therefore, you had usually best use regular expressions for this.
Strictly speaking, integers are whole numbers positive and negative, and also including zero. Here is a regular expression for this:
/^0$|^[-]?[1-9][0-9]*$/
OR, if you want to allow leading zeros:
/^[-]?[0]|[1-9][0-9]$/
Note that this will allow for values such as -0000, which does not cause problems in PHP, however. (MySQL will also cast such values as 0.)
You may also want to confine the length of your integer for considerations of 32/64-bit PHP platform features and/or database compatibility. For instance, to limit the length of your integer to 9 digits (excluding the optional - sign), you could use:
/^0$|^[-]?[1-9][0-9]{0,8}$/
Meanwhile, all the values above will only restrict the values to integer,
so i use
/^[1-9][0-9\.]{0,15}$/
to allow float values too.
You can use filter_var() to check for integers in strings
<?php
$intnum = "1000022";
if (filter_var($intnum, FILTER_VALIDATE_INT) !== false){
echo $intnum.' is an int now';
}else{
echo "$intnum is not an int.";
}
// will output 1000022 is an int now

PHP comparison '==' problem

Why is the output 'in'?
<?php
if (1=='1, 3')
{
echo "in";
}
?>
The == operator does type conversion on the two values to try to get them to be the same type. In your example it will convert the second value from a string into an integer, which will be equal to 1. This is then obviously equal to the value you're matching.
If your first value had been a string - ie '1' in quotes, rather than an integer, then the match would have failed because both sides are strings, so it would have done a string comparison, and they're different strings.
If you need an exact match operator that doesn't do type conversion, PHP also offers a tripple-equal operator, ===, which may be what you're looking for instead.
Hope that helps.
Because PHP is doing type conversion, it's turning a string into an integer, and it's methods of doing so work such that it counts all numbers up until a non-numeric value. In your case that's the substring ('1') (because , is the first non-numeric character). If you string started with anything but a number, you'd get 0.
You are comparing a string and an integer. The string must be converted to an integer first, and PHP converts numeric strings to integers. Since the start of that string is '1', it compares the number one, with the number one, these are equal.
What functionality did you intend?
If you're trying to check if 1 is equal to 1 or 3, then I would definitely do it this way:
if (1 == 1 || 1 == 3)
Please refer to the PHP documentation:
http://php.net/manual/en/language.operators.comparison.php
The output should be:
in
From PHP's documentation:
When converting from a string to an
integer, PHP analyzes the string one
character at a time until it finds a
non-digit character. (The number may,
optionally, start with a + or - sign.)
The resulting number is parsed as a
decimal number (base-10). A failure to
parse a valid decimal number returns
the value 0.
I'm guessing you want to know whether a variable is in a range of values.
You can use in_array:
if (in_array(1, array(1, 3, 5, 6)))
echo "in";
if(in_array(1, array(1,3)) {
echo "in";
}

is_numeric or a numeric preg_match?

I read on a forum that you can't completely trust is_numeric(). It lets through "0xFF" for example which is an allowed hexadecimal...
So my question is can you trick is_numeric? Will I need to use a regex to do it correctly?
Here is what is_numeric() considers to be a numeric string:
Numeric strings consist of optional sign, any number of digits, optional decimal part and optional exponential part. Thus +0123.45e6 is a valid numeric value. Hexadecimal notation (0xFF) is allowed too but only without sign, decimal and exponential part.
If you only want to check if a string consists of decimal digits 0-9, you could use ctype_digit().
One can also check using ctype_digit() to check if its a true number.
Regex would obviously be your better option, however it does come with an overhead. So it really depends on your situation and what you want to do.
Is it for validating user input? Then the overhead of using a regexp or asserting it doesn't contain an "x" and is_numeric() wouldn't be too much overhead.
If you just want to check that something is an integer, try this:
function isInteger($value){
return (is_numeric($value) ? intval($value) == $value : false);
}
If you want to check for floats too then this won't work obviously :)

Categories