PHP preg_filter returns unexpected long value

2019-05-27 05:06发布

Trying to strip tags and filter value in Woocommerce but can't manage o get it in the correct format. Something is fishy..

Am using WC()->cart->get_cart_subtotal(); to retrieve the value. In this example my value is 2,429kr and the raw returned value is <span class="amount">2,429kr</span>

$cart_total = WC()->cart->get_cart_subtotal();
$cart_total_format = strip_tags($cart_total);
$cart_value = preg_filter("/[^0-9,.]/", "", $cart_total_format);

echo $cart_value;

Result = 2,429107114
Expected = 2,429

Am not a PHP wizard so i thought i was doing something wrong and did try several diffren't approches and methods without getting the correct result.

Then i did try to run the raw out output from WC()->cart->get_cart_subtotal(); as a $string

$string_total = '<span class="amount">2,429kr</span>';
$string_total_format = strip_tags($string_total);
$string_value = preg_filter("/[^0-9,.]/", "", $string_total_format);

echo $string_value;

Result = 2,429
Expected = 2,429

Why? :(

Update

Found this when digging around in Woocommerce @Github

case 'SEK' : $currency_symbol = '&#107;&#114;'; break;

So the real value is:

<span class="amount">2,429&#107;&#114;</span>

Question now is what the best approach to filter this out ? My quick fix approach is this, it's not beautiful but fix the issue.

$cart_total = WC()->cart->get_cart_subtotal();
$cart_total_format = strip_tags($cart_total);
$cart_value = preg_filter("/[^0-9,.]/","", $cart_total_format);
$cart_value_new = preg_filter("/107114/",".", $cart_value);

echo $cart_value_new;

Result = 2,429
Expected = 2,429

2条回答
Viruses.
2楼-- · 2019-05-27 05:38

Ok, so this is what is happening. get_cart_subtotal() returns an HTML-encoded string. Because you are not looking at the actual source, but rather var_dump-ing it and looking at the HTML you are seeing <span class="amount">2,429kr</span>, when in fact the "k" and "r" are encoded into their equivalent HTML entities (based on their ASCII codes), &#107; and &#114.

That is also why var_dump shows string(45) "2,429kr" when it should in fact return string(7) "2,429kr" if the currency weren't encoded (and the <span> tags weren't interpreted by the browser).

Then, when you apply the preg_filter, it also includes the numbers from the HTML entities, of course, because they match the regular expression.

So the easiest solution is to decode all HTML entities before filtering:

$cart_total = html_entity_decode($cart_total, ENT_QUOTES, 'UTF-8');

so your code becomes:

$cart_total = WC()->cart->get_cart_subtotal();
$cart_total = html_entity_decode($cart_total, ENT_QUOTES, 'UTF-8');
// rest of your code
查看更多
Melony?
3楼-- · 2019-05-27 05:44

Just a guess:

Maybe WC()->cart->get_cart_subtotal() return '<span class="amount">2,429107114kr</span>', but when you display it you see <span class="amount">2,429kr</span> because of some javascript that round it.

查看更多
登录 后发表回答