如何优化这个简单的PHP脚本?
第一个脚本通过AJAX请求为每个用户调用数次。它在不同的服务器上调用另一个脚本以获取文本文件的最后一行。它工作得很好,但我认为还有很大的改进空间,但我不是一个很好的PHP程序员,因此我希望在社区的帮助下,我可以优化它的速度和效率: 对该脚本发出的AJAX POST请求如何优化这个简单的PHP脚本?,php,optimization,file,performance,Php,Optimization,File,Performance,第一个脚本通过AJAX请求为每个用户调用数次。它在不同的服务器上调用另一个脚本以获取文本文件的最后一行。它工作得很好,但我认为还有很大的改进空间,但我不是一个很好的PHP程序员,因此我希望在社区的帮助下,我可以优化它的速度和效率: 对该脚本发出的AJAX POST请求 <?php session_start(); $fileName = $_POST['textFile']; $result = file_get_contents($_SESSION['serverURL']."fileR
<?php session_start();
$fileName = $_POST['textFile'];
$result = file_get_contents($_SESSION['serverURL']."fileReader.php?textFile=$fileName");
echo $result;
?>
它向读取文本文件的外部脚本发出GET请求
<?php
$fileName = $_GET['textFile'];
if (file_exists('text/'.$fileName.'.txt')) {
$lines = file('text/'.$fileName.'.txt');
echo $lines[sizeof($lines)-1];
}
else{
echo 0;
}
?>
我将感谢任何帮助。我认为在第一个脚本中可以做更多的改进。它做了一个昂贵的函数调用(file\u get\u contents),至少我认为它很昂贵 如果文件不变,则应缓存最后一行 如果文件正在更改,并且您可以控制生成它们的方式,那么根据行在其生命周期中的读取频率,反转写入顺序可能是一种改进,也可能不是一种改进 编辑: 您的服务器可以找出要写入日志的内容,将其放入memcache,然后将其写入日志。最后一行的请求可以从memcache而不是从文件读取中得到满足。是您的朋友吗 它读取磁盘上的文件并将其流式传输到客户端 脚本1:
<?php
session_start();
// added basic argument filtering
$fileName = preg_replace('/[^A-Za-z0-9_]/', '', $_POST['textFile']);
$fileName = $_SESSION['serverURL'].'text/'.$fileName.'.txt';
if (file_exists($fileName)) {
// script 2 could be pasted here
//for the entire file
//readfile($fileName);
//for just the last line
$lines = file($fileName);
echo $lines[count($lines)-1];
exit(0);
}
echo 0;
?>
通过向脚本中添加缓存,可以进一步改进该脚本。但这更复杂。
非常的基本缓存可以是
脚本2:
<?php
$lastModifiedTimeStamp filemtime($fileName);
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$browserCachedCopyTimestamp = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
if ($browserCachedCopyTimestamp >= $lastModifiedTimeStamp) {
header("HTTP/1.0 304 Not Modified");
exit(0);
}
}
header('Content-Length: '.filesize($fileName));
header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 604800)); // (3600 * 24 * 7)
header('Last-Modified: '.date('D, d M Y H:i:s \G\M\T', $lastModifiedTimeStamp));
?>
此脚本应限制要返回的位置和文件类型 想象一下有人尝试这样做: (或类似的东西) 试着找出发生延误的地方。。HTTP请求需要很长时间,还是文件太大以至于读取它需要很长时间 如果请求很慢,请尝试在本地缓存结果
如果文件很大,则可以设置cron作业,定期(或每次更改)提取文件的最后一行,并将其保存到其他脚本可以直接访问的文件中 第一件事:你真的需要优化它吗?这是用例中最慢的部分吗?你曾经验证过吗?如果您已经这样做了,请继续阅读: 您无法真正有效地优化第一个脚本:如果需要http请求,则需要http请求。如果可能的话,跳过http请求可能会提高性能(例如,如果第一个脚本可以访问第二个脚本将要操作的相同文件) 至于第二个脚本:将整个文件读入内存看起来确实有些开销,但如果文件很小,这是可以忽略的。代码看起来可读性很强,我会保持原样 但是,如果您的文件很大,您可能希望使用及其好友和
最可能的延迟源是跨服务器HTTP请求。如果文件很小,那么fopen/fread/fclose的成本与整个HTTP请求相比是微不足道的 (不久前,我使用HTTP检索图像,以友好方式生成基于图像的菜单。用本地文件读取代替HTTP请求将延迟从秒减少到十分之一秒。) 我认为直接访问文件服务器文件系统的明显解决方案是不可能的。如果不是,那么这是最好、最简单的选择 如果没有,您可以使用缓存。您只需发出HEAD请求并将时间戳与本地副本进行比较,而不是获取整个文件
此外,如果您是基于相同文件更新Ajax的许多客户端,您可能会考虑使用慧星(例如,流星)。它用于诸如聊天之类的事情,其中一个更改必须广播到多个客户端
谢谢你富有洞察力的答复。我以前没有使用过它(xdebug),但现在我正在研究它。我读到的文本文件不超过20行,行长约为5/6个字。那么,我就不会碰代码了。解释循环的开销甚至可能大于该大小文件的收益:)如果客户端只需要最后一行,您认为我应该使用它吗?“脚本1”替换您的2个脚本。readfile()读取整个文件并将其发送到浏览器。如果您不确定,请忘记“脚本2”是的,文件一直在更改。我喜欢最后一个想法,颠倒行的顺序,所以我只检索第一行。我需要我能获得的每一点性能提升!我知道它没有什么问题,因为它可以工作,但我只是在尝试改进它,因为这个脚本将被称为100000s of times.:)# Do not forget to sanitize the file name here!
# An attacker could demand the last line of your password
# file or similar! ($fileName = '../../passwords.txt')
$filePointer = fopen($fileName, 'r');
$i = 1;
$chunkSize = 200;
# Read 200 byte chunks from the file and check if the chunk
# contains a newline
do {
fseek($filePointer, -($i * $chunkSize), SEEK_END);
$line = fread($filePointer, $i++ * $chunkSize);
} while (($pos = strrpos($line, "\n")) === false);
return substr($line, $pos + 1);