如何在PHP中将字符串转换为数字?

927

我想把这些值'3''2.34''0.234343'等转换成数字。在JavaScript中我们可以使用Number(),但PHP中是否有类似的方法?

Input             Output
'2'               2
'2.34'            2.34
'0.3454545'       0.3454545

99
读者请注意:这个问题并没有一个真正的答案 :( - Matthieu Napoli
1
@MatthieuNapoli 答案是通常情况下Php会为您解决这个问题 - 动态类型系统的一个好处。 - Kellen Stuart
18
面对不确定性和“通常”的种种羁绊。 - person27
我认为5年前我的意思是,没有一个单一的函数可以将字符串转换为正确的intfloat(当给定int时,通常不需要float)。 - Matthieu Napoli
4
@MatthieuNapoli很高兴你澄清了自己的观点,意思是有多种方法可以解决问题,而不是根本无法解决。例如在数据库操作中,类型转换非常重要。例如,在参数化PDO查询中,有时解析器难以识别它是数字而不是字符串,然后因为没有在参数步骤中将字符串转换为整数,所以最终会得到一个0放入整型字段中。 - stubsthewizard
顺便提一下,在JavaScript中,字面整数2被内部存储为Number:"JavaScript代码中的数字字面量(如37)是浮点值,而不是整数。在日常使用中没有单独的整数类型。(JavaScript现在有一个BigInt类型,但它并不是为了取代Number而设计的。37仍然是一个Number,而不是BigInt。)"因此,在JS中,Number(your_string)之所以能够实现你想要的功能,是因为其他地方的逻辑默认将2显示为"2"而不是"2.0" - ToolmakerSteve
35个回答

5

虽然有些晚,但这里还有另一种方法:

function cast_to_number($input) {
    if(is_float($input) || is_int($input)) {
        return $input;
    }
    if(!is_string($input)) {
        return false;
    }
    if(preg_match('/^-?\d+$/', $input)) {
        return intval($input);
    }
    if(preg_match('/^-?\d+\.\d+$/', $input)) {
        return floatval($input);
    }
    return false;
}

cast_to_number('123.45');       // (float) 123.45
cast_to_number('-123.45');      // (float) -123.45
cast_to_number('123');          // (int) 123
cast_to_number('-123');         // (int) -123
cast_to_number('foo 123 bar');  // false

注意:此代码缺少对输入如“.123”、“123。”、“1.23e6”及可能的其他输入(如“0x16”等)的处理。 - Zrin

4

现在我们处于一个严格/强类型在 PHP 中越来越重要的时代,我使用 json_decode

$num = json_decode('123');

var_dump($num); // outputs int(123)

$num = json_decode('123.45');

var_dump($num); // outputs float(123.45)

JSON不是PHP。 - TV-C-1-5
3
@TV-C-1-5 不确定您的观点是什么?当然,JSON不是PHP。PHP提供了编码和解码JSON的函数。同样,PHP也提供了编码和解码base64的函数——这并不意味着base64就是PHP。 - Andy
我需要检查POST的值是否为整数,它对此非常完美。 - lisandro

4
function convert_to_number($number) {
    return is_numeric($number) ? ($number + 0) : FALSE;
}

3

您可以使用:

((int) $var)   ( but in big number it return 2147483647 :-) )

但最好的解决方案是使用:
if (is_numeric($var))
    $var = (isset($var)) ? $var : 0;
else
    $var = 0;

或者

if (is_numeric($var))
    $var = (trim($var) == '') ? 0 : $var;
else
    $var = 0;

3
您可以简单地这样写:

就像这样:

<?php
    $data = ["1","2","3","4","5"];
    echo json_encode($data, JSON_NUMERIC_CHECK);
?>

3
虽然这段代码或许能回答问题,但是提供关于为什么和/或如何回答问题的额外背景信息可以提高其长期价值。 - Alex Riabov
1
你确定吗?这不会将字符串转换为数字,而是将数组转换为JSON字符串。 - Nico Haase
是的,@NicoHaase,如果数字以字符串格式在数组中,则会转换为数字。 - Dominic Amal Joe F

3

有一种方法:

$value = json_decode(json_encode($value, JSON_NUMERIC_CHECK|JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_SLASHES), true);

使用 is_* 是不可行的,因为 variable 是一个: string

使用 json_encode()json_decode() 的组合,它将被转换为其“真实”形式。如果它是一个真正的 string ,那么它将输出错误。

$num = "Me";
$int = (int)$num;
$float = (float)$num;

var_dump($num, $int, $float);

将输出:string(2) "Me" int(0) float(0)


毫无疑问是正确的。但这种方法过于复杂,因为多年前已经提供了简单的解决方案。(只要庆幸你没有早些时候写它-参见相同方法的极度被踩下的回答)。 - ToolmakerSteve

2
您可以按照以下方式更改数据类型。
$number = "1.234";

echo gettype ($number) . "\n"; //Returns string

settype($number , "float");

echo gettype ($number) . "\n"; //Returns float

由于历史原因,在浮点数的情况下返回“double”。 PHP文档

2

如果您事先不知道一个字符串是浮点数还是整数,
并且该字符串可能包含特殊字符(如空格、€等),
并且它可能包含多个点或逗号,
那么您可以使用此函数:

// This function strip spaces and other characters from a string and return a number.
// It works for integer and float.
// It expect decimal delimiter to be either a '.' or ','
// Note: everything after an eventual 2nd decimal delimiter will be removed.
function stringToNumber($string) {
    // return 0 if the string contains no number at all or is not a string:
    if (!is_string($string) || !preg_match('/\d/', $string)) {
        return 0;
    } 

    // Replace all ',' with '.':
    $workingString = str_replace(',', '.', $string);

    // Keep only number and '.':
    $workingString = preg_replace("/[^0-9.]+/", "", $workingString);

    // Split the integer part and the decimal part,
    // (and eventually a third part if there are more 
    //     than 1 decimal delimiter in the string):
    $explodedString = explode('.', $workingString, 3);

    if ($explodedString[0] === '') {
        // No number was present before the first decimal delimiter, 
        // so we assume it was meant to be a 0:
        $explodedString[0] = '0';
    } 

    if (sizeof($explodedString) === 1) {
        // No decimal delimiter was present in the string,
        // create a string representing an integer:
        $workingString = $explodedString[0];
    } else {
        // A decimal delimiter was present,
        // create a string representing a float:
        $workingString = $explodedString[0] . '.' .  $explodedString[1];
    }

    // Create a number from this now non-ambiguous string:
    $number = $workingString * 1;

    return $number;
}

就我个人而言,我认为这是可疑的。在任意的垃圾字符串中查找数字几乎肯定是不可取的。更好的方法是像PHP默认情况下所做的那样,将(大多数)垃圾字符串转换为“0”。原因是:如果意外的字符串到达您的方法,发生了什么更加明显 - 您只需获得0(除非字符串以有效数字开头)。 - ToolmakerSteve
1
@ToolmakerSteve 是的,这确实是个问题,但至少有这种情况:我不得不显示包含在(不可修改的)工作表中的字符串“原样”,包括符号等,并同时使用其中包含的数字。 - user1657853
好的,那很有道理。如果字符串中散布着多个数字,你的答案会怎么做呢?这种方法对于将电话号码转换为仅包含数字的代码有用吗?例如,用户输入(123)456-7890,你想从中提取1234567890吗?还是说它只找到第一个数字,所以在我的例子中会得到123的结果? - ToolmakerSteve
1
它返回完整的数字。 - user1657853

1
//Get Only number from string
$string = "123 Hello Zahid";
$res = preg_replace("/[^0-9]/", "", $string);
echo $res."<br>";
//Result 123

1

所有建议都不带有数字类型。

这对我来说似乎是最佳实践:

function str2num($s){
// Returns a num or FALSE
    $return_value =  !is_numeric($s) ? false :               (intval($s)==floatval($s)) ? intval($s) :floatval($s);
    print "\nret=$return_value type=".gettype($return_value)."\n";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接