php - check if a string contains a float - php

What is the easiest way to check if a string contains a valid float?
For example
is_string_float("1") = true
is_string_float("1.234") = true
is_string_float("1.2e3") = true
is_string_float("1b2") = false
is_string_float("aldhjsfb") = false

The easiest way would be to use built in function is_float(). To test if a variable is a number or a numeric string you must use is_numeric().

If you really want to know if a string contains a float and ONLY a float you cannot use is_float() (wrong type) or is_numeric() (returns true for a string like "1" too) only. I'd use
<?php
function foo(string $string) : bool {
return is_numeric($string) && strpos($string, '.') !== false;
}
?>
instead.

maybe you can use a couple of functions
out of the box
function is_string_float($string) {
if(is_numeric($string)) {
$val = $string+0;
return is_float($val);
}
return false;
}

This can easily be achieved by double casting.
/**
* #param string $text
* #return bool
*/
function is_string_float(string $text): bool
{
return $text === (string) (float) $text;
}

Related

What's the best annotation to describe a simulation overload function?

I am using Visual Studio Code(VS Code), it can display the annotation of functios.
I am try to improve write a PHPDoc standard.
Can any suggestions to me? Thank you.
Here have 3 functions, but they are not the focal point .
I just want to know how to write a PHPDoc standard describe the function 2 and simulation overload function 3.
Ref:
https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#54-examples
<?php
// Function 1:
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string A
* #param string B
*
* #return bool
*/
function checkAandB_1($a, $b){
if($a === $b)
return true;
return false;
}
// Function 2:
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string Input x,y (<=here, I need to known how to write a right note to describe this function can support input a string combin x and y with a comma in one line)
*
* #return bool
*/
function checkAandB_2($str){
if( substr_count($str, ",") === 1 ) {
$strArr = explode(",",$str);
if($strArr[0] === $strArr[1])
return true;
}
return false;
}
// Function 3: Simulation a overload function
/**
* Check if A is equal to B.(Just a sample note, not important)
*
* #param string (What's the best annotation to describe this function?)
*
* #return bool
*/
function checkAandB_overload($str, $b = null){
if(isset($b) && $str === $b){
return true;
}elseif( substr_count($str, ",") === 1 ) {
$strArr = explode(",",$str);
if($strArr[0] === $strArr[1])
return true;
}
return false;
}
var_dump(checkAandB_1("1","2")); // false
var_dump(checkAandB_1("2","2")); // true
var_dump(checkAandB_2("1,2")); // false
var_dump(checkAandB_2("2,2")); // true
var_dump(checkAandB_overload("1","2")); // false
var_dump(checkAandB_overload("2","2")); // true
var_dump(checkAandB_overload("1,2")); // false
var_dump(checkAandB_overload("2,2")); // true

PHP preg_match return false even if condition match

I am using preg_match to verify an input :
$string = 'test';
if (preg_match ('/[^-a-z\d]/i', $string))
{
return true;
}
else
{
return false;
}
Well I can not understand why it return false here !
Am I missing something ?
Shouldn't it return true ?
The solution :
(preg_match ('/^[-a-z\d]*$/i', $string))
Tyr this
(preg_match ('/^[-A-Za-z\d]*$/', $string))
So preg_match() can return 0, 1, or false it is probably safer to do a strict check that the result equals 1, i.e.
abstract class Pattern
{
/** #const int */
const TEXT_MATCH = 1;
/**
* #param string $pattern regex pattern to match against
* #param string $string the text string to search
*
* #return bool
*/
public static function match(string $pattern, string $string): bool
{
return preg_match($pattern, $string) === self::TEXT_MATCH;
}
}
Primarily the bit you're interested in is this
preg_match($pattern, $string) === 1;
If you then use it:
$result = Pattern::match('/[^-a-z\d]/i', 'test');
var_dump($result); // false
The string doesn't pass the check. If that doesn't resolve your issue we're going to need to see a few examples of strings you are passing through that are always passing. It's probably also worth explaining what you want the regex to match against, because that could be part of the issue also.

php in_array multibyte equivalent

Is in_array() function in php multibyte safe?
If not ,how can i make it so?
The php.net multibyte reference lists mb_stristr() but it accepts a string , not an array as haystack .
My haystack = array of strings and needle = string.
Since I could not find any built in PHP solution, I did as #FirstOne suggested.
/**
* #return bool true if needle is found in haystack, false otherwise
*/
public function custom_mb_in_array($_needle, array $_hayStack) {
foreach ($_hayStack as $value) {
if (mb_strtolower($value) === mb_strtolower($_needle)) {
return true;
}
}
return false;
}

How to pass type into a function in PHP

I have the following function to safely get a cookie:
public static function get_cookie($parameter, $default)
{
return isset($_COOKIE[$parameter]) ? $_COOKIE[$parameter] : $default;
}
When I try to read false then use it in ternary operator, I see the value is treated as string (which is casted to true).
I want to pass a type into this function and cast the value, but have no ideas how.
UPDATE
As Niko pointed, casting 'false' to boolean doesn't work: http://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting
I guess, I have to store strings in cookies always. (For instance, 'yes' and 'no' instead of 'false' and 'true' for my case).
There is absolutely no need to do the casting inside the function (especially since PHP is loosely typed).
Consider the following use-case:
$booleanValue = ClassName::get_cookie('foo', true, 'bool');
You end up with the same amount of code (but much more readable!) when you do the casting outside of get_cookie():
$booleanValue = (bool) ClassName::get_cookie('foo', true);
However, you can still implement a simple switch for 'false' and 'true' strings, respectively:
public static function get_cookie($parameter, $default, $isPseudoBool = false) {
$value = isset($_COOKIE[$parameter]) ? $_COOKIE[$parameter] : $default;
if ($isPseudoBool) {
$value = ($value === true || strcasecmp($value, 'true') === 0);
}
return $value;
}
If you still prefer to move the type conversion into the function, settype() is what you need for this:
public static function get_cookie($parameter, $default, $type) {
$value = isset($_COOKIE[$parameter]) ? $_COOKIE[$parameter] : $default;
settype($value, $type);
return $value;
}
But please note that this won't convert a string "false" to the boolean value false, if you specify $type = 'bool' - the conversion rules are the same as when an implicit conversion is done by the interpreter.
Try this
public static function get_cookie($parameter, $default)
{
if( empty($parameter) ) return $default;
return isset($_COOKIE[$parameter]) ? $_COOKIE[$parameter] : $default;
}

How to get the real type of a value inside string?

I was searching here on StackOverflow about converting string to the real value and i didn't found.
I need a function like "gettype" that does something like the result above, but i can't do it all :s
gettypefromstring("1.234"); //returns (doble)1,234;
gettypefromstring("1234"); //returns (int)1234;
gettypefromstring("a"); //returns (char)a;
gettypefromstring("true"); //returns (bool)true;
gettypefromstring("khtdf"); //returns (string)"khtdf";
Thanks to all :)
1+ for Svisstack! ;)
Here is the function if someone want it:
function gettype_fromstring($string){
// (c) José Moreira - Microdual (www.microdual.com)
return gettype(getcorrectvariable($string));
}
function getcorrectvariable($string){
// (c) José Moreira - Microdual (www.microdual.com)
// With the help of Svisstack (http://stackoverflow.com/users/283564/svisstack)
/* FUNCTION FLOW */
// *1. Remove unused spaces
// *2. Check if it is empty, if yes, return blank string
// *3. Check if it is numeric
// *4. If numeric, this may be a integer or double, must compare this values.
// *5. If string, try parse to bool.
// *6. If not, this is string.
$string=trim($string);
if(empty($string)) return "";
if(!preg_match("/[^0-9.]+/",$string)){
if(preg_match("/[.]+/",$string)){
return (double)$string;
}else{
return (int)$string;
}
}
if($string=="true") return true;
if($string=="false") return false;
return (string)$string;
}
I used this function to know if the number X is multiple of Y.
Example:
$number=6;
$multipleof=2;
if(gettype($number/$multipleof)=="integer") echo "The number ".$number." is multiple of ".$multipleoff.".";
But the framework that i work returns always the input vars as strings.
You must try to convert it in specified order:
Check is double
If double, this may be a integer, you must convert and compare this values.
If not, this is char if lenght is == 1.
If not, this is string.
If string, try parse to bool.
You can't use gettype because you may get string type of decimal writed in string.
Here is an updated version of this 9 year old function:
/**
* Converts a form input request field's type to its proper type after values are received stringified.
*
* Function flow:
* 1. Check if it is an array, if yes, return array
* 2. Remove unused spaces
* 3. Check if it is '0', if yes, return 0
* 4. Check if it is empty, if yes, return blank string
* 5. Check if it is 'null', if yes, return null
* 6. Check if it is 'undefined', if yes, return null
* 7. Check if it is '1', if yes, return 1
* 8. Check if it is numeric
* 9. If numeric, this may be a integer or double, must compare this values
* 10. If string, try parse to bool
* 11. If not, this is string
*
* (c) José Moreira - Microdual (www.microdual.com)
* With the help of Svisstack (http://stackoverflow.com/users/283564/svisstack)
*
* Found at: https://stackoverflow.com/questions/2690654/how-to-get-the-real-type-of-a-value-inside-string
*
* #param string $string
* #return mixed
*/
function typeCorrected($string) {
if (gettype($string) === 'array') {
return (array)$string;
}
$string = trim($string);
if ($string === '0') { // we must check this before empty because zero is empty
return 0;
}
if (empty($string)) {
return '';
}
if ($string === 'null') {
return null;
}
if ($string === 'undefined') {
return null;
}
if ($string === '1') {
return 1;
}
if (!preg_match('/[^0-9.]+/', $string)) {
if(preg_match('/[.]+/', $string)) {
return (double)$string;
}else{
return (int)$string;
}
}
if ($string == 'true') {
return true;
}
if ($string == 'false') {
return false;
}
return (string)$string;
}
I am using it in a Laravel middleware to transform form values that were stringified by browser JavaScript's FormData.append() back into their correct PHP types:
public function handle($request, Closure $next)
{
$input = $request->all();
foreach($input as $key => $value) {
$input[$key] = $this->typeCorrected($value);
}
$request->replace($input);
return $next($request);
}
To create that, type in your CLI php artisan make:middleware TransformPayloadTypes.
Then paste in the above handle function.
Don't forget to paste in the typeCorrected function also. I currently recommend making it a private function in your middleware class, but I don't claim to be a super-expert.
You can imagine that $request->all() is an array of key/value pairs, and it comes in with all values stringified, so the goal is to convert them back to their true type. The typeCorrected function does this. I've been running it in an application for a few weeks now, so edge cases could remain, but in practice, it is working as intended.
If you get the above working, you should be able to do something like this in Axios:
// note: `route()` is from Tightenco Ziggy composer package
const post = await axios.post(route('admin.examples.create', {
...this.example,
category: undefined,
category_id: this.example.category.id,
}));
Then, in your Laravel controller, you can do \Log::debug($request->all()); and see something like this:
[2020-10-12 17:52:43] local.DEBUG: array (
'status' => 1,
'slug' => 'asdf',
'name' => 'asdf',
'category_id' => 2,
)
With the key fact being that you see 'status' => 1, and not 'status' => '1',
All of this will allow you to submit JSON payloads via Axios and receive non-nested values in your FormRequest classes and controllers as the actual payload types are mutated. I found other solutions to be too complex. This above solution allows you to submit flat JSON payloads from pure JavaScript easily (so far, haha).

Categories