我为客户设置了许多不同的主机帐户,需要计算每个帐户使用的存储空间量,这将定期更新。
我有一个数据库设置来记录每个客户端的存储使用情况。
我首先尝试使用每个帐户上的PHP文件,由Cron作业运行。如果由我自己手动运行,它将输出正确的文件大小并将正确的大小更新到数据库,尽管从Cron作业运行时,它将输出0。
然后我尝试从主帐户从Cron作业运行此文件,但认为这实际上不起作用,因为我的托管将阻止来自另一台服务器的文件,我最终会得到与以前相同的结果。
我现在正在玩主要帐户中来自Cron Job的每个帐户的FTP访问,如下所示,唯一的问题是我不知道如何使用FTP访问计算目录大小而不是单个文件大小,并且不要不知道如何重申这种方式?希望有人能够在我最终绕圈子之前在这里提供帮助吗?
我也将添加之前的第一次尝试。
$ftp_conn = ftp_connect($ftp_host, 21, 420) or die("Could not connect to server");
$ftp_login = ftp_login($ftp_conn, $ftp_username, 'mypassword');
$total_size = 0;
$contents = ftp_nlist($ftp_conn, ".");
// output $contents
foreach($contents as $folder){
while($search == true){
if($folder == '..' || $folder == '.'){
} else {
$file = $folder;
$res = ftp_size($ftp_conn, $file);
if ($res != -1) {
$total_size = $total_size + $res;
} else {
$total_size = $total_size;
}
}
}
}
ftp_close($ftp_conn);
这不起作用,因为它不计算文件夹大小,我不知道如何使用此方法打开重复?
第二个脚本确实有效,但只有在手动打开时才能工作,如果由cron作业运行则返回0。
class Directory_Calculator {
function calculate_whole_directory($directory)
{
if ($handle = opendir($directory))
{
$size = 0;
$folders = 0;
$files = 0;
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
if(is_dir($directory.$file))
{
$array = $this->calculate_whole_directory($directory.$file.'/');
$size += $array['size'];
$files += $array['files'];
$folders += $array['folders'];
}
else
{
$size += filesize($directory.$file);
$files++;
}
}
}
closedir($handle);
}
$folders++;
return array('size' => $size, 'files' => $files, 'folders' => $folders);
}
}
/* Path to Directory - IMPORTANT: with '/' at the end */
$directory = '../public_html/';
// return an array with: size, total files & folders
$array = $directory_size->size($directory);
$size_of_site = $array['size'];
echo $size_of_site;
请记住,我目前正在测试,MySQLi或PHP脚本都没有安全性。
如果您的服务器支持MLSD
命令并且您使用的是PHP 7.2或更高版本,则可以使用ftp_mlsd
function:
function calculate_whole_directory($ftp_conn, $directory)
{
$files = ftp_mlsd($ftp_conn, $directory) or die("Cannot list $directory");
$result = 0;
foreach ($files as $file)
{
if (($file["type"] == "cdir") || ($file["type"] == "pdir"))
{
$size = 0;
}
else if ($file["type"] == "dir")
{
$size = calculate_whole_directory($ftp_conn, $directory."/".$file["name"]);
}
else
{
$size = intval($file["size"]);
}
$result += $size;
}
return $result;
}
如果你没有PHP 7.2,你可以尝试自己实现MLSD
命令。首先,请参阅ftp_rawlist
命令的用户注释:
https://www.php.net/manual/en/function.ftp-rawlist.php#101071
如果你不能使用MLSD
,你会特别有问题告诉entry is a file or folder。虽然你可以像使用ftp_size
技巧一样,为每个条目调用ftp_size
可能需要很长时间。
但是,如果您只需要针对一个特定的FTP服务器,您可以使用ftp_rawlist
以特定于平台的格式检索文件列表并解析它。
以下代码采用通用的* nix格式。
function calculate_whole_directory($ftp_conn, $directory)
{
$lines = ftp_rawlist($ftp_conn, $directory) or die("Cannot list $directory");
$result = 0;
foreach ($lines as $line)
{
$tokens = preg_split("/\s+/", $line);
$name = $tokens[8];
if ($tokens[0][0] === 'd')
{
$size = calculate_whole_directory($ftp_conn, "$directory/$name");
}
else
{
$size = intval($tokens[4]);
}
$result += $size;
}
return $result;
}
关于cron:我猜测cron没有使用正确的工作目录启动脚本,因此您需要计算不存在的目录的大小。
在这里使用绝对路径:
$directory = '../public_html/';
虽然你最好添加一些错误检查,以便你可以看到自己出了什么问题。