好的,我正在寻找以最快的方式通过php在服务器上读取文件的所有内容,这些文件也可能很大.因此,尽可能快地对它进行只读是非常重要的.
是否比阅读整个内容更快地逐行阅读?虽然,我记得读过这篇文章,但阅读全部内容会导致大文件出错.这是真的?
Pas*_*TIN 35
如果要将文件的全部内容加载到PHP变量,那么最简单(也可能是最快)的方式就是file_get_contents.
但是,如果您正在使用大文件,将整个文件加载到内存中可能不是一个好主意:您可能最终会出现memory_limit错误,因为PHP不允许您的脚本使用超过(通常)一对兆字节的内存.
因此,即使它不是最快的解决方案,逐行读取文件(fopen+ fgets+ fclose),并在不将整个文件加载到内存中的情况下动态处理这些行,可能是必要的......
Ali*_*xel 15
file_get_contents()然而,这是在PHP中读取文件的最优化方式 - 因为您正在读取内存中的文件,所以总是限制在可用内存量上.
ini_set('memory_limit', -1)如果您拥有正确的权限,则可以发出一个权限,但您仍将受到系统上可用内存量的限制,这对所有编程语言都是通用的.
唯一的解决方案是以块的形式读取文件,因为您可以使用file_get_contents()第四个和第五个参数($offset以及$maxlen- 以字节为单位指定):
string file_get_contents(string $filename[, bool $use_include_path = false[, resource $context[, int $offset = -1[, int $maxlen = -1]]]])
Run Code Online (Sandbox Code Playgroud)
以下是我使用此技术提供大型下载文件的示例:
public function Download($path, $speed = null)
{
if (is_file($path) === true)
{
set_time_limit(0);
while (ob_get_level() > 0)
{
ob_end_clean();
}
$size = sprintf('%u', filesize($path));
$speed = (is_int($speed) === true) ? $size : intval($speed) * 1024;
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $size);
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Transfer-Encoding: binary');
for ($i = 0; $i <= $size; $i = $i + $speed)
{
ph()->HTTP->Flush(file_get_contents($path, false, null, $i, $speed));
ph()->HTTP->Sleep(1);
}
exit();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用更少的优化fopen(),feof(),fgets()和fclose()功能,特别是如果你在乎让整行一次,这里是我在另一个StackOverflow的问题,提供了导入大型SQL查询到数据库中另一个例子:
function SplitSQL($file, $delimiter = ';')
{
set_time_limit(0);
if (is_file($file) === true)
{
$file = fopen($file, 'r');
if (is_resource($file) === true)
{
$query = array();
while (feof($file) === false)
{
$query[] = fgets($file);
if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1)
{
$query = trim(implode('', $query));
if (mysql_query($query) === false)
{
echo '<h3>ERROR: ' . $query . '</h3>' . "\n";
}
else
{
echo '<h3>SUCCESS: ' . $query . '</h3>' . "\n";
}
while (ob_get_level() > 0)
{
ob_end_flush();
}
flush();
}
if (is_string($query) === true)
{
$query = array();
}
}
return fclose($file);
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
您使用哪种技术将取决于您正在尝试做什么(正如您可以通过SQL导入功能和下载功能看到的那样),但您始终必须以块的形式读取数据.
$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
$line = fgets($file_handle);
echo $line;
}
fclose($file_handle);
Run Code Online (Sandbox Code Playgroud)
$file_handle为文件本身的引用.你可以用 file_get_contents
例:
$homepage = file_get_contents('http://www.example.com/');
echo $homepage;
Run Code Online (Sandbox Code Playgroud)