情况如下:我有一个名为myDB.sql的2Gb转储文件。它是一个删除现有数据库并创建新数据库的转储文件,带有视图和触发器。因此,我将字符串myDB_OLD
扩展为代码的许多行。我想将这些字符串的出现次数更改为myDB_NEW
。我可以使用notePad++轻松地完成这项工作。但是记事本无法打开2Gb的文件。我所做的是一个PHP代码,它逐行读取并查找和替换我想要的字符串。
这是代码:
$myfile2 = fopen("myDB.sql", "r") or die("Unable to open file!");//Reads the file
while (!feof($myfile2)) {//Pass trough each line
$str=fgets($myfile2);//Store the line inside a variable
if (preg_match("/myDB_OLD/",$str)) {//If the string I want to change exists - replace it and conacatenate
$newStr .= str_replace("myDB_OLD","myDB_NEW",$str);
}
else {//If not concatenate it
$newStr .=$str;
}
}//End of while
fclose($myfile2);
//Save the newStr in a new file named
$myfile = fopen("newDB.sql", "w") or die("Unable to open file!");
fwrite($myfile, $newStr);
echo "finished";
这段代码检索文件的每一行,更改字符串,连接变量并创建一个新文件。它应该有效,但事实并非如此。我不知道为什么。我正在使用xdebug来找出问题所在,但运气不好。
所以我改变了方法。我没有将每一行都保存在变量中,而是直接将其保存在文件中,效果很好。
这是新代码:
$myfile = fopen("newDB.sql", "w") or die("Unable to open file!");//Creates a new file "newDB.sql"
$myfile2 = fopen("myDB.sql", "r") or die("Unable to open file!");//Reads the file
while (!feof($myfile2)) {//Pass trough each line
$str=fgets($myfile2);//Store the line inside a variable
if (preg_match("/myDB/",$str)) {//If the string I want to change exists - replace it . (Do not concatenate)
$strRep=str_replace("myDB","myDB_NEW",$str);
}
else {
$strRep =$str;
}
fwrite($myfile, $strRep);// Add the new line to the file "newDB.sql"
}//End of while
fclose($myfile);
fclose($myfile2);
echo "finished";
好吧,我解决了我的问题,但这引发了一个思考。第一个代码的问题是什么?我认为问题在于要存储在PHP变量2Gb中的信息量。那么,存储值的PHP变量(在本例中是字符串)的大小有限制吗?如果是,我该如何检查或更改?有php.ini变量吗?
那么,存储值的Php变量的大小有限制吗?在这种情况下,是字符串吗?
是的。一个字符串可以大到2GB(最大2147483647字节)。您可以通过增加php.ini中的memory_limit指令来覆盖此限制。
从php7来看,64位系统中没有这个限制:
在64位构建中支持长度>=2^31字节的字符串。
允许脚本分配的最大字节数在php.ini中设置。查找memory_limit。默认情况下,这是PHP 5.2.0之后的16Mb!
这可以通过执行来改变
ini_set('memory_limit','24M');
如果memory_limit
允许,PHP中字符串的最大大小为2GB,这可能是由于地址限制。