将字符串转换为十进制php

时间:2013-11-26 16:37:50

标签: php

我正在根据两个值获取数据。产品的价格和产品的折扣。我想计算差异。问题是这些值来自数据库,例如:22,50€。我抓住这个值,我删除了“€”并用“。”替换“,”。 。但问题是,在减去值时,不会占用帐户。

数据库来自变量$ discount和$ price

 $price2 = trim($price,'€'); 
 $price2 = str_replace(",",".",$price2);
 $price2 = floatval($price2);

 $discount2 = str_replace(array('€'), '',$discount); 
 $discount2 = str_replace(",",".",$discount2);
 $discount2 = floatval($ver_preco2);


 $result = ($price2 - $discount2);

变量$ discount未转换为float而不知道原因。变量有什么问题?

1 个答案:

答案 0 :(得分:0)

由于这个问题已经被查看了很多次了,所以我整理了一个函数,该函数可能对发现该问题的其他人有用。以下是一个脚本,其中包含一些测试值,函数currencyToDecimal(),以及一些用于运行和显示测试的代码。您只需要功能本身。

如果您还有其他未通过的测试用例,请告诉我,以便我们进行调整。

<?php

    $testValues = [
        '22,50 €',
        '22 €',
        '22€',
        '$22.50',
        '$22',
        '$0.50¢',
        '$22 000 000.50',
        '22 000 000,50 €',
        '22.000.000,50 €',
    ];

    /**
     * Convert Currency String to Decimal
     * 
     * Attempts to support international currency formats by first converting them
     * to a standardized format PHP can process consistently. 
     * 
     * First, per the SI/ISO 31-0 standard, there are several delimiting options
     * for the integer portion (before the radix) that allow for easier reading. We need
     * to convert this portion to an integer without readability delimiters.
     * 
     * Second, we need to convert the radix (decimal separator) to a "point" or 
     * "period" symbol.
     * 
     * Finally, we strip unwanted characters and convert to float.
     * 
     * @see https://en.wikipedia.org/wiki/Decimal_separator
     * @see https://en.wikipedia.org/wiki/ISO_31-0
     * @see https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html
     */
    function currencyToDecimal($value) {

        // Ensure string does not have leading/trailing spaces
        $value = trim($value);

        /**
         * Standardize readability delimiters
         *****************************************************/

            // Space used as thousands separator between digits
            $value = preg_replace('/(\d)(\s)(\d)/', '$1$3', $value); 

            // Decimal used as delimiter when comma used as radix
            if (stristr($value, '.') && stristr($value, ',')) {
                // Ensure last period is BEFORE first comma
                if (strrpos($value, '.') < strpos($value, ',')) {
                    $value = str_replace('.', '', $value);
                }
            }

            // Comma used as delimiter when decimal used as radix
            if (stristr($value, ',') && stristr($value, '.')) {
                // Ensure last period is BEFORE first comma
                if (strrpos($value, ',') < strpos($value, '.')) {
                    $value = str_replace(',', '', $value);
                }
            }

        /**
         * Standardize radix (decimal separator)
         *****************************************************/

            // Possible radix options
            $radixOptions = [',', ' '];

            // Convert comma radix to "point" or "period"
            $value = str_replace(',', '.', $value);

        /**
         * Strip non-numeric and non-radix characters
         *****************************************************/

            // Remove other symbols like currency characters
            $value = preg_replace('/[^\d\.]/', '', $value);

        /**
         * Convert to float value
         *****************************************************/

            // String to float first before formatting
            $value = floatval($value);

        /**
         * Give final value 
         *****************************************************/

            return $value;

    }

    // Run tests through function
    echo("ORIGINAL => DECIMAL => DATA TYPE\n");
    echo("*********************************************\n");
    foreach ($testValues as $value) {

        // Run function on test value
        $result = currencyToDecimal($value);

        // Determine data type. NOTE: Per docs, "double" will be 
        // returned for a "float" value.
        $type = gettype($result);
        if ($type === "double") {
            $type = "float";
        }

        // Output [Original] => [Decimal] => [Data Type]
        echo("$value => $result => $type\n");
    }

输出如下:

Test Output

ORIGINAL => DECIMAL => DATA TYPE
*********************************************
22,50 € => 22.5 => float
22 € => 22 => float
22€ => 22 => float
$22.50 => 22.5 => float
$22 => 22 => float
$0.50¢ => 0.5 => float
$22 000 000.50 => 22000000.5 => float
22 000 000,50 € => 22000000.5 => float
22.000.000,50 € => 22000000.5 => float

参考文献:
https://en.wikipedia.org/wiki/Decimal_separator
https://en.wikipedia.org/wiki/ISO_31-0
https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html