我需要登录到生产服务器检索文件并使用此文件中的数据更新我的数据库。由于这是一个生产数据库,我不想每5分钟获取整个文件,因为文件可能很大,这可能会影响服务器。我需要每5分钟间隔获取此文件的最后30行,并尽可能减少影响。
以下是我目前的代码,我将非常感谢有关如何最好地完成此任务的任何见解:
<?php
$user="id";
$pass="passed";
$c = curl_init("sftp://$user:[email protected]/opt/vmstat_server1");
curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($c);
curl_close($c);
$data = explode("\n", $data);
?>
SFTP无法进行部分文件传输。使用全流程SSH连接并使用远程“尾部”操作来获取文件的最后几行(例如,
$lines = shell_exec("ssh [email protected] 'tail -30 the_file'");
当然,你可能希望有一些更强大的功能,可以处理阻止ssh通过的net.glitches之类的东西,但作为一个基本的起点,这应该可以解决问题。
Marc B错了。 SFTP完全能够进行部分文件传输。以下是如何使用phpseclib, a pure PHP SFTP implementation执行所需操作的示例:
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
$size = $sftp->size('filename.remote');
// outputs the last ten bytes of filename.remote
echo $sftp->get('filename.remote', false, $size - 10);
?>
事实上,我推荐这样的方法,因为有些SFTP服务器不允许你通过系统shell运行命令。此外,SFTP可以在Windows SFTP服务器上运行,而即使您有shell访问权限,也不太可能这样做。即。总的来说,它是一个更便携的解决方案。
如果要获取文件的最后x行,可以重复循环,每次读取多个字节,直到遇到10个新行字符。即。获取最后10个字节,然后是最后10个字节的下一个字节,然后是那10个字节之前的10个字节,等等。
@Sammitch回答一个重复的问题Get last 15 lines from a large file in SFTP with phpseclib:
以下内容应该会产生一个文本blob,文件末尾至少有15行,然后您可以使用现有逻辑进一步处理。您可能需要调整一些逻辑,具体取决于您的文件是否以尾随换行符结束等。
$filename = './file.txt'
$filesize = $sftp->size($filename);
$buffersize = 4096;
$offset = $filesize; // start at the end
$result = '';
$lines = 0;
while( $offset > 0 && $lines < 15 ) {
// work backwards
if( $offset < $buffersize ) {
$offset = 0;
} else {
$offset -= $buffer_size;
}
$buffer = $sftp->get($filename, false, $offset, $buffer_size));
// count the number of newlines as we go
$lines += substr_count($buffer, "\n");
$result = $buffer . $result;
}