PHP - Parsing results are not consistent - php

Parsing a string value to a float value is not consistent in my PHP project. Altough I'm not changing my code and the values to parse are always the same I sometimes get a result with a comma and sometimes with a point.
The incoming value is for example: 35,59
Before parsing this value I first replace the comma by a point.
$value = '35,59';
$value = (float)str_replace(',', '.', $value);
var_dump($value);
When I now use this value in my insert query, this sometimes results in a bug because a comma is used.
This is all a bit weird to me, has anyone experienced this before? How can I prevent this from happening?
Edit:
I indeed forgot my quotes in this example, but I did use quotes in my code

$value = 35,59;
The problem is that the parser cannot recognize "," as a decimal delimiter. Your locale may define numbers this way but programmatically you must use periods or declare the value as a string.
$value = "35,59";
// or
$value = 35.59;
If you get 35,59, that must be hard-coded since any data-source returning this value is automatically treated as a string.
See http://us2.php.net/numberformatter.parse for information on how to cast the formatted string correctly.
I.e
$fmt = new NumberFormatter( 'sv_SE', NumberFormatter::DECIMAL );
$value = "35,59";
echo $fmt->parse($value); // 35.59
Edit
Also your str_replace will fail for X number of locales since some usually use "," as a thousand separator.

Related

WooCommerce : How to convert wp_price value to a numeric value?

I'm developing a table with two columns, "State" and "Sales". To get the number in the sales column, I use the wc_price function, which works just fine to output a currency string:
CA $1,652.13
CO $515.80
...etc.
I have at least 50 rows, one for each state.
The very last row will output the total of all the dollar amounts from column 2.
I discovered that the actual result from wc_price isn't just a sting, it's a block of html:
<bdi>
<span class="woocommerce-Price-currencySymbol">$</span>
435.50
</bdi>
I tried to get to the actual number within the html, 435.50 using strip_tags:
$numeric = strip_tags(wc_price($total)); // result is a simple string, with the $ sign
echo str_replace("$","",$numeric) . "<br>"; // doesn't strip away the $ sign.
$tally = $tally + $numeric; // produces an error, non-numeric value.
The error is on the $tally = line. This doesn't work in any way. Sure, the html tags are stripped, and I'm left with a string: $435.50. In other words, I can't get rid of that danged '$' for some reason. I simply cannot parse, convert, or anything to that currency string. (int), intval($numeric), (float)$numeric, floatval($numeric), etc., none of these work. number_format doesn't work, either.
Warning: A non-numeric value encountered in C:\xampp\htdocs\mysite\wp-content\plugins\my-custom-plugin\my-custom-plugin.php on line 104
Add a floatval() around your str_replace and assign the variable.
$numeric = strip_tags($html);
$numeric = floatval(str_replace("$", "", $numeric));
See working example. It works with 5.6, 7.4 and 8.1.
I'm not sure of the result, but I think it's possible to have the price without the currecy reading from the documentation of wp_price:
$numeric = wp_price($total, array('currency'=>''));
However you can have some action that change the comportament of the wc_price function.

Stringing together variables, str_replace. Tidier way to do this?

I have a bunch of variables that I want to string together. They all need to be tidied up by removing spaces and commas, and converting to dashes (I'm constructing a URL).
I have a very basic understanding of PHP, but I feel my code below could be tidier and more efficient. Could you point me to some resources or make some suggestions please?
Here's what I have:
$propNum = $prop->Address->Number;
$propStreet = $prop->Address->Street;
$propTown = $prop->Address->Town;
$propPost = $prop->Address->Postcode;
$propFullAdd = array($propNum, $propStreet, $propTown, $propPost);
$propFullAddImp = implode(" ",$propFullAdd);
$propFullAddTidy = str_replace(str_split(' ,'),'-', strtolower($propFullAddImp));
echo $propFullAddTidy;
From the output of your existing code, it seems like you may want an output that looks something like:
12345-example-street-address-example-town-example-postcode
In this case, you could use this solution:
//loop through all the values of $prop->Address
foreach($prop->Address as $value) {
//for each value, replace commas & space with dash
//store altered value in new array `$final_prop`
$final_prop[] = str_replace([' ', ','], '-', $value);
/*
Removing `str_split(' ,')` and subbing an array makes the loop "cheaper" to do,
Because the loop doesn't have to call the `str_split()` function on every iteration.
*/
}
//implode `$final_prop` array to dash separated string
//also lowercase entire string at once (cheaper than doing it in the loop)
$final_prop = strtolower(implode('-', $final_prop));
echo $final_prop;
if you remove the comments, this solution is only 4 lines (instead of 7), and is completely dynamic. This means if you add more values to $prop->Address, you don't have to change anything in this code.
A different method
I feel like this would usually be handled by using http_build_query(), which converts an array into a proper URL-encoded query string. This means that each value in the array would be passed as it's own variable in the URL query.
First, $propFullAdd is not necessary (in fact, it may be detrimental), $prop->Address already contains the exact same array. Recreating the array like this completely removes the ability to tell which value goes to which key, which could be problematic.
This means that you can simplify your entire code by replacing it with this:
echo http_build_query($prop->Address);
Which outputs something like this:
Number=12345&Street=Example+Street+Address&Town=Example+Town&Postcode=Example+Postcode

How to get CSV integers read as integers from a string variable

I have a string that I get from sanitizing some values from an xml file.
$resolutions=strip_tags($resolutions,allow); // gives me '75 75 300 300 600 600'
Then I change the spaces to commas:
$resolutions = preg_replace('#\s+#',',',trim($resolutions)); // gives me '75,75,300,300,600,600'
Then I take that and want to extract min and max values like this
$resolution_min = min($resolutions);
on the page for display
echo $resolution_min; // still gives me '75,75,300,300,600,600'
However when I change the code where I want it displayed on the page
echo min(75,75,300,300,600,600); // it displays '75' as it should
I think, the issue is that the CSV values are being interpreted as a single text string and I need them read as CSV integer values.
Is there some way to force these to be read as numeric values by min and max?
I think part of my problem comes from this line or a line like it, jus befor an "explode" command
$list = "" . substr($scansupportedresolutions, $start,$length) . "";
I have never seen this kind of double double quote dot and dot double double quote and have no idea what it means
Is it simply saying the entire string in $list will be
".<CONTENT HERE>."
but specifically in double quotes? Whatever it is i seems crucial to the explode command.
From min:
If the first and only parameter is an array, min() returns the lowest value in that array. If at least two parameters are provided, min() returns the smallest of these values.
You are passing one parameter and it's a string. Pass an array:
$resolutions = explode(',', $resolutions);
$resolution_min = min($resolutions);
AbraCadaver is correct in his answer.
I have tried to improve your code. Take a look
<?php
// After Stripping tag
$resolutions = "75 75 300 300 600 600";
// No need to conver to Space to comma
$resolutionsArray = explode(" ", $resolutions);
$resolutionMin = min($resolutionsArray);
print($resolutionMin);
There is no gain by converting the "white Space" to "Comma". You can explode the string into array by setting "white Space" as delimiter.
Hope it helps you.

PHP format number before insert into database

i'm using $_POSTto send form values to PHP and then insert into database, i have some inputs for prices values that looks like this:
1.000.000,00 (1 million in BRL "Brazilian Real")
I need to convert it to 1000000.00 (DECIMAL(10,2) to insert into database)
How can i do that using PHP number_format()?
Thanks!
EDIT
If number_format() is not the function i'm looking for, what's best to be using in this case?
Also, i need help finding a solution, even if the user value is 100.000,00
You can not do that with number format, it works other way around.
The thing that you do is bad practice, View layer should send primitive data to Controller - if you are using some advanced javascript component to represent to the user formatted number, that is fine, but underlaying form control should send primitive data, i.e. 10000000.00
Now, if nothing that I have stated to you is not applicable at this particular moment, and having in mind that this format that you have send is fixed (dot for thousand separator, coma for decimal separator), you can clean the value by using simple str_replace.
But, the trick is to replace first dot with empty string, then coma with dot.
str_replace(',', '.',str_replace('.', '', $number));
Got it?
But know that what you are doing is bad approach and wrong implementation, eventually, it will bite you in the a**.
<?php
$number = '1.000.000,00';
$replaced_number = str_replace(array('.',','), array('',''), $number);
echo number_format($replaced_number,2,'.','');
?>
The easiest way is to use str_replace() function:
<?php
$p = '1.000.000,00';
$p = str_replace('.', '', $p);
$p = str_replace(',', '.', $p);
echo $p;
At first replace the (.) and (,) with str_replace by '' and then use t the following function
number_format($replaced_number,$decimal)
If you have a look at php.net you will easily see the right syntax for your goal:
number_format($number,2,'.','')
The first parameter is the number of decimal places that in your case is 2.
The second is the symbol to use for decimal separator and the third is the one to be used for thousands that in your case will be nothing .

Update a string to follow a specific format

I have a column in my database that stores a string of numbers, separated by commas.
,,133,,,,444,,,,555,,,,6,
Rules:
The first number in the string is always preceded by 2 commas
There are always 4 commas between the middle numbers
The last number only has 1 comma after it
The example above is how I always want the string to look..
What happens is when some of these numbers are removed the updated string looks like this:
,,31,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,998,,,,476,,,,,
Making it look messy in the database and sometimes causing trouble with the extra commas when I try to output each number
I've been manually updating each value to follow the format I want but I'd like to make a script that runs each night and takes each of these strings and updates them with the correct format following the rules I listed above.
What can I use to format the string to follow the rules above?
You could create a php script that loads the values from the database, manipulate the rows, and store the manipulated values back to the database. I don't know what database and table structure you use, but the manipulation part is simple:
// load the string from the database into the $value variable
$numbers= preg_split("/,+/", $value); // split the string
$numbers= array_filter( $numbers); // remove empty array elements
$newvalue = implode(',,,,', $numbers); // join the array elements to a string separated by ,,,,
$newvalue = ',,' . $newvalue . ','; // add ,, at the beginning and , at the end of the new value
// store $newvalue in the database

Categories