PHP 中是否有类似于 substr() 的用于整数的函数?

4

我有一个电话号码,它将被记录为整数(例如1234512312345)在我的数据库中,但我想在网页上表示为(12345)123-12345。如果它是一个字符串,我会使用substr,但似乎将其转换为strval不太优雅。

虽然我知道整数和字符串在分类上是不同的,但是否有一种方法可以做到这样的效果,而不编写一个效率低下的函数?


7
松散类型的乐趣... substr() 是你要找的函数... 为什么认为将其转换为字符串是不优雅的呢?特别是当你甚至不需要使用 strval() 的时候。 - Mark Baker
1
为什么不直接使用substr,而不需要所有这些沉思呢?即使它需要您进行“不优雅”的手动类型转换。这是一个毫无意义的问题示例。 - Your Common Sense
http://php.net/manual/en/function.strval.php - MakuraYami
我个人建议将它们存储为字符串,这样可以避免加号或数字前导0的问题。由于您不需要执行算术运算或比较操作来确定哪个电话号码更高级,因此也不需要使用int字段。是的,您会节省一些空间,但真的那么多吗? - aleation
如果一个电话号码以0开头,如果您将其存储为整数,第一位数字会丢失吗? - Pedro del Sol
@PedrodelSol 首位数字确实会“丢失”,但在打印时,您可以使用格式化将其放回。 - CSᵠ
6个回答

11

你可以尝试使用vprintfvsprintfsscanf一起使用。

$data = 1234512312345;
vprintf("(%d)-%d-%d",sscanf($data, "%5d%3d%5d"));

输出

(12345)-123-12345

多版本PHP测试

*注意

如果您想要返回它具有一个值,则应该是

$var = vsprintf("(%d)-%d-%d",sscanf($data, "%5d%3d%5d"));
        ^
        |---- Note the `s`

1
+1 阅读问题并看到 OP 明显不想将其转换为字符串 - Jimbo

7

注意:因为标题而回答,将电话号码视为整数并不是一个好主意

你应该利用PHP的类型强制转换能力,使用字符串函数处理你的电话号码,但如果你想要以C语言的方式继续使用整数,则有以下选项:

  • /运算符用于除法,可用于获取前几位数字(将123除以100可以得到第一个数字,但不能直接得出,因为123/100=1.23,使用floor()函数将得到floor(123/100)=1,但这里可能会有问题,因为floor()函数的结果是float类型而不是integer类型)
  • %运算符用于取模,可用于获取最后几位数字(12310取模将立即给出最后一位数字,并且是integer类型,例如,123%10=3
所以您可以这样从电话号码中提取所需的部分(使用整数方式):
$last=$no%100000; // get last 5 digits (modulo by 1 followed by 5 zeroes)

$no=$no-$last; // subtract the last digits from original number

$no=$no/100000; // divide to shorten the number, end up with a natural number

$area=$no%1000; // get last 3 again

$prefix=($no-$area)/1000; //remainder is the first digits of the original number

或者(使用float/double/real方式)- 只是更易读:
$last=$no%1e5; // scientific notation 1e5 = 10000 (1 followed by 5 zeroes)

$no=($no-$last)/1e5;

$area=$no%1e3;

$prefix=($no-$area)/1e3;

实时代码: http://codepad.viper-7.com/tVRjXC

注意:科学计数法e使用类型float

您还应该记住,32位平台上的最大整数是2^31 = 2.147.483.648


现在,如果您使用类似0077705501234的“电话号码”,将会让您头疼!

所以它来自数据库,但如果出现真正的int,PHP将会将任何前导数字为八进制基数0内部转换为十进制,因此您最终会得到完全不同的“电话号码”,确切地说是垃圾。

如果PHP将其作为字符串接收,而您确实希望使用整数进行操作,则可以使用(int) $no 进行type-cast,或者使用$no+0 进行转换等。

总之,对于整数来说,前导零并不重要,但对于字符串来说却很重要,因此您可能会得到 77705501234 这样的结果,您可能需要进行长度检查(采用整数 浮点方式):

我选择浮点数方法进行计算,因为有太多的零需要计算...

我们知道该数字必须有 13 位数,因此我们可以检查 if ( $no > 1e12 ) 并且可能还要检查 if ( $no < 1e14 ) 以进行验证。

如果您还想知道数字的“长度”(您需要了解 pow() ):

for ($i=1;$i<13;$i++) { //count from 1 to 12
    //stop when $no modulo 10^$i is the number
    if ( $no % pow(10,$i) == $no ) break; 
}
// number of digits of $no are stored in $i - equivalent to strlen()

最后,为了正确打印您的数字,即使整数前导零缺失: printf('Your number: (%05u) %03u - %05u',$prefix,$area,$last); 实时代码:http://codepad.viper-7.com/Xgr8RQ 侧面说明:对于大数字,您还可以使用BCMath函数,但它们使用字符串。

1
最好不要将电话号码存储和处理为整数,而是简单地将其作为字符串处理。
因此,使用strval()将您的数字转换为字符串,然后可以在其上使用substr()和所有其他字符串函数。

5
不确定为什么这个回答被踩了,但把电话号码存储为字符串是明智的建议,因为它们通常包含前导零,如果将其作为数值类型存储,这些前导零可能会丢失。 - Mark Baker

1
请尝试这段代码。
<?php
   $data = 1234512312345;
   echo "(".substr($data, 0, 5).") ".substr($data, 5, 3)."-".substr($data,8);
?>

0

0

试试这个...

<?php
$phone = "1234512312345";
//(12345) 123 - 12345

$array = str_split($phone,5);
$array1 = substr($phone,5, 3);
$array2 = substr($phone,8, 5);

echo "(".$array[0].") ".$array1."-".$array2;
?>

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