PHP中字符串的最大长度是多少?


69

那么$variablePHP中的大小可以达到多少呢?我已经尝试过测试,但是我不确定我是否有足够的系统内存(〜2gb)。我认为必须有某种限制。字符串太大时会发生什么?它是串联的,还是PHP抛出异常?


5
您到底想做什么?
Sarfraz

@sAc我想更多地了解PHP。我知道由于严重的内存泄漏,我无法使用php进行大量的内存操作。
菜鸟

1
在php7中,他们正在消除此限制:stackoverflow.com/a/31085071/1090562
Salvador Dali


我会更改标题,因为不是OP还是没有答案回答了关于长度的主要问题,他们都在谈论大小
jave.web

Answers:


101

http://php.net/manual/en/language.types.string.php说:

注意:从PHP 7.0.0开始,对于64位版本的字符串的长度没有特别的限制。在32位版本和较早版本中,字符串最大可以为2GB(最大2147483647字节)

在PHP 5.x中,字符串被限制为2 31 -1个字节,因为内部代码以带符号的32位整数记录了长度。


您可以输入整个文件的内容,例如使用 file_get_contents()

但是,PHP脚本在给定脚本执行中可以为所有变量分配的总内存中有限制,因此,这实际上也限制了单个字符串变量的长度。

此限制是memory_limitphp.ini配置文件中的指令。内存限制在PHP 5.2中默认为128MB,在早期版本中为8MB。

如果您未在php.ini文件中指定内存限制,它将使用默认值,该默认值将编译到PHP二进制文件中。从理论上讲,您可以修改源代码并重建PHP以更改此默认值。

如果您-1在php.ini文件中指定作为内存限制,它将停止检查并允许脚本使用操作系统分配的内存。这仍然是实际的限制,但是取决于系统资源和体系结构。


来自@ c2的评论:

这是一个测试:

<?php

// limit memory usage to 1MB 
ini_set('memory_limit', 1024*1024);

// initially, PHP seems to allocate 768KB for basic operation
printf("memory: %d\n",  memory_get_usage(true));

$str = str_repeat('a',  255*1024);
echo "Allocated string of 255KB\n";

// now we have allocated all of the 1MB of memory allowed
printf("memory: %d\n",  memory_get_usage(true));

// going over the limit causes a fatal error, so no output follows
$str = str_repeat('a',  256*1024);
echo "Allocated string of 256KB\n";
printf("memory: %d\n",  memory_get_usage(true));

那么,如果我们真的需要长字符串,那么在内存限制内工作的最佳方法是什么?
Pacerier 2013年

当PHP.net声明“注释字符串可以最大为2GB”时。php.net/manual/en/language.types.string.php是否表示它可以超过2GB?
Pacerier 2013年

@Pacerier,好收获!当我在2010年首次回答此问题时,该注释不在手册页中。我将在上面编辑答案。
Bill Karwin

1
请在下面查看我的回复,限制是由PHP中的字符串表示方式决定的,而不是由内存限制决定的。
c

@ c2,+ 1用于转到源代码,但请参阅上面的内存限制演示。
Bill Karwin 2014年


4

PHP的字符串长度受PHP中字符串表示方式的限制。内存与它无关。

根据phpinternalsbook.com,字符串存储在struct {char * val;中。英伦 由于C中int的最大大小为4个字节,因此有效地将最大字符串大小限制为2GB。


1
..为什么f在这里不使用unsigned int?不像一个字符串可以永远
少于

1
并不完全正确。2GB是31位。使用签名的数据类型会浪费一些时间。也许这是为了简化诸如溢出检查之类的事情,而不需要更大的值或指定值(concat A + B,uint total = A.len + B.len,如果total> TYPE_MAX / 2则报错),我不认为C允许进行溢出检查而不会掉入装配体。
jgmjgm 2015年

@jgmjgm 2GB(31位)是因为第32位用于符号。如果它是“ unsinged int len”,那么您将拥有32位和4GB
杰克

2

在即将发布的新的php7和其他许多功能中,他们添加了对大于2 ^ 31字节的字符串的支持:

在64位版本中支持长度> = 2 ^ 31字节的字符串。

可悲的是,他们没有指定可以扩大多少。


也许2 ^ 63-1?我什至不知道某处是否有那么多RAM。
hakre

从理论上讲,它可以允许2 ^ 32或2 ^ 64。无论出于何种原因,都使用带符号的整数或长整数。因为在极少数情况下,这会在很多地方破坏代码(如果len <something),则字符串长度确实会溢出。
jgmjgm

我打赌它的0x7FFFFFFFFFFFFFFFFF或9223372036854775807字节(或9.2 exabyts),减去PHP已经使用的内容,减去ASLR浪费的内容,因为您知道64位虚拟内存空间将被用尽:D
hanshenrik

2

字符串变量的最大长度仅为2GiB-(2 ^(32-1)位)。可以按字符(8位/ 1字节)对变量进行寻址,并且寻址是通过有符号整数完成的,这就是为什么限制如此的原因。数组可以包含多个变量,每个变量都遵循先前的限制,但总累加大小最大为memory_limit,字符串变量也应受此限制。


0

为了正确回答这个问题,您需要考虑PHP内部或PHP构建的目标。

要从x86的典型Linux角度回答这个问题...

C中类型的大小:https//usrmisc.wordpress.com/2012/12/27/integer-sizes-in-c-on-32-bit-and-64-bit-linux/

PHP中用于变量的类型:http : //php.net/manual/zh/internals2.variables.intro.php

字符串始终为2GB,长度始终为32位,并且由于使用int而不是uint而浪费了一点时间。int对于超过2GB的长度是不切实际的,因为它需要强制转换以避免破坏算术或“ than”比较。多余的位可能用于溢出检查。

奇怪的是,使用uint时,哈希键可能在内部支持4GB,尽管我从未进行过测试。PHP哈希键的长度为+1,而尾随的空字节被忽略,据我所知,因此在这种情况下可能需要将其取消签名,而不是允许使用更长的键。

32位系统可能会施加更多的外部限制。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.