Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Сеть > Работа с FTP


Автор: Oflashp 14.8.2007, 20:57
Вообщем написал FTP-индексатор, обходит все файлы и каталоги. Если файл -  то происходит закачка контрольной суммы, последние 64кб из каждого файла или весь файл если весит меньше 64кб. Далее кодируется в мд5 и сливается в базу, для того, чтобы видеть повторные файлы. Столкнулся с проблемой, что большие фтп которые имеют очень большое дерево, индексируются не корректно. Скрипт застревает и пишет ошибку. Естественно при повторе он всё таки индексирует полностью или застревает на шаге открытия каталога или чтения файла.
Пробовал:
1)Выставлять интервал (была мысль, что команды слишком быстро летят на сервер)
2)Пробовал методом получения всех каталогов, а потом пошагово каждый каталог обходился
3)Пробовал менять размер закачиваемого куска.
Ничего не помогает, бывает так, что скрипт застревает в самом начале и проблему найти не удаётся. Нашёл топики в интернете, возникали такие же проблемы и у других людей.
Ищу решения, пробовал на PHP4.
Так же ищу решения для другой проблемы, а именно работа с файлами больше 1024мб. При попытке закачать часть файла, то-есть последних 64кб, закачивается весь файл. Если DownloadMasterom ручками делаешь закачку с того же фтп, докачка делается.
Заранее благодарю.

Автор: Diesel Draft 16.8.2007, 10:35
Индексатор писать на РНР немного жестоко smile

А есть закономерность когда вылетает? И какого рода ошибки

Автор: Oflashp 19.8.2007, 01:59
Закономерности нет.
Ошибки аля, не могу зайти в каталог или не могу открыть файл для закачки.
Хотя при повторе читает.

Автор: console 19.8.2007, 02:11
Цитата(Oflashp @  14.8.2007,  19:57 Найти цитируемый пост)
При попытке закачать часть файла, то-есть последних 64кб, закачивается весь файл

Покажи код... что значит весь закачивается?
fopen, fread, fclose

А вообще такие вещи лучше на С писать.

Автор: Diesel Draft 19.8.2007, 02:28
Может проблема только на одном FTP, или это проблемы коннекта.

Автор: Oflashp 19.8.2007, 02:39
Пробовали на разных фтп и под разными ОС.
Код

<?
//<--load libs
include("./init/game.php");
//-->load libs
db_connect();
//<--vars
$time_stamp = time();
$type = $config[type];
$all_size = 0;
$count_files = 0;
$num_of_servers = 1;
//Mysql
$config[mysql_login] = "Alex";
$config[mysql_password] = "123";
$config[mysql_hosthost] = "localhost";
$config[mysql_db] = "mur";
$config[mysql_table] = "game_links";
//File
$config[file_extention] = "iso,bin,mdf,rar";
$config[md5_size] = "64000";
//Parameters
$config[type] = 'game';
//-->vars
//<-- functions
function db_connect()
        {
        global $config;
        $connection=mysql_connect($config[mysql_host], $config[mysql_login], $config[mysql_password]) or die("EBAD CONNECT TO DATABASE, PLEASE RELOAD PAGE @".mysql_error());
        mysql_select_db($config[mysql_db]);
        }
function xmlentities($string)
        {
           return str_replace ( array ("'"), array ("\'"), $string );
        }
function index($init, $folder)
        {
        global $conn_id, $server_id, $time_stamp, $all_size, $count_files;
        //<--vars
        $expansion_db = $init[file_extention];
        $type = $init[type];
        $md5_size = $init[md5_size];
        $rexp = "/([-ldrwx]{10})[ ]+([0-9]+)[ ]+([A-Z,0-9]+)[ ]+([A-Z,0-9]+)[ ]+([0-9]+)[ ]+([A-Z]{3}[ ]+[0-9]{1,2}[ ]+[0-9:]{4,5})[ ]+(.*)/i";
        //-->vars
        //echo $expansion_db;
        ftp_chdir($conn_id, "/");
        echo "Открываю категорию: <b>".$folder."</b><br>";
        if(ftp_chdir($conn_id, $folder))
                {
                $buff = ftp_rawlist($conn_id, "");
                foreach($buff as $rawlist)
                        {
                        //echo "Получаю списки файлов и папок категории: <b>".$folder."</b><br>";
                        preg_match($rexp, $rawlist, $regs);
                        if($regs[1][0] == 'd')
                                {
                                //echo "<b>".$folder."/".$regs[7]."</b><br>";
                                if($regs[7] != "." && $regs[7] != "..")
                                        {
                                        index($init, $folder."/".$regs[7]);
                                        }
                                }
                        if($regs[1][0] == '-')
                                {
                                $file_name = $regs[7];
                                $size = $regs[5];
                                echo "<b>".$folder."/".$regs[7]."</b> [".$size."]<br>";
                                //echo $size."<br>";
                                $file_name_code = xmlentities($file_name);
                                $folder_code = xmlentities($folder);
                                //---
                                $lenght_file_name = strlen($file_name);
                                $expansion_length_file = $lenght_file_name - 3;
                                $expansion_file = strtolower(substr($file_name, $expansion_length_file, $lenght_file_name));
                                $expansion_db = strtolower($expansion_db);
                                $expansions_array = explode(",", $expansion_db);
                                foreach($expansions_array as $exp_key => $exp_val)
                                        {
                                        //echo $expansion_file." == ".$exp_val."<br>";
                                        if($exp_val == $expansion_file)
                                                {
                                                $all_size = $all_size + $size;
                                                $count_files = $count_files + 1;
                                                //echo $all_size;
                                                $mysql_array_listfiles = mysql_query("SELECT * FROM ".$init[mysql_table]." WHERE server_id='$server_id' AND file='$file_name_code' AND folder='$folder_code'") or die(mysql_error());
                                                if(mysql_num_rows($mysql_array_listfiles) == '0')
                                                        {
                                                        if($size >= 200000)
                                                                {
                                                                $pos = $size-$md5_size;
                                                                //echo $pos;
                                                                }
                                                        else
                                                                {
                                                                $pos= 0;
                                                                }
                                                                if($size < 1073741824)
                                                                         {
                                                                         if(ftp_get($conn_id, 'content', $file_name, FTP_BINARY, $pos))
                                                                                {
                                                                                $fws = file_get_contents('content');
                                                                                unlink('content');
                                                                                $fws_md5 = md5($fws);
                                                                                echo "[<font color='#ff0000'><b>".$fws_md5."</b></font>]<br>";
                                                                                $file_name_code = xmlentities($file_name);
                                                                                $folder_code = xmlentities($folder);
                                                                                flush();
                                                                                $mysql_query[0] = mysql_query("INSERT INTO ".$init[mysql_table]."(server_id, file, folder, size, content, time) VALUES ('$server_id', '$file_name_code', '$folder_code', '$size', '$fws_md5', '$time_stamp')");
                                                                                echo "[<b>".$file_name."</b>] файл добавлен.<br> \n";
                                                                                }
                                                                        }
                                                                else
                                                                        {
                                                                        $file_name_code = xmlentities($file_name);
                                                                        $folder_code = xmlentities($folder);
                                                                        flush();
                                                                        $mysql_query[0] = mysql_query("INSERT INTO ".$init[mysql_table]."(server_id, file, folder, size, content, time) VALUES ('$server_id', '$file_name_code', '$folder_code', '$size', '', '$time_stamp')");
                                                                        echo "[<b>".$file_name."</b>] файл обновлён.<br> \n";
                                                                        }

                                                        }
                                                else
                                                        {
                                                        $mysql_array_listfiles = mysql_query("UPDATE ".$init[mysql_table]." SET time='$time_stamp' WHERE server_id='$server_id' AND file='$file_name_code' AND folder='$folder_code'") or die(mysql_error());
                                                        echo "[<b>".$file_name."</b>]<font color='#009900'><b> файл обновлён.</b></font><br> \n";
                                                        }
                                                }
                                        }

                                }
                        }
                }
        return 1;
        }
//--> functions
if($server_id != '')
        {
        echo "single mode<br>";
        $mysql_query = mysql_query("SELECT * FROM ident_servers WHERE id = '$server_id' LIMIT 1") or die(mysql_error());
        $s = 1;
        }
else
        {
        echo "multi mode<br>";
        $mysql_query = mysql_query("SELECT * FROM ident_servers WHERE want_game = '1' AND status = '1'") or die(mysql_error());
        }
if(mysql_num_rows($mysql_query) != 0)
        {
        echo "start...<br>";
          while($server_array = mysql_fetch_array($mysql_query))
                {
                $server_id = $server_array[id];
                if($s == '')
                        {
                        $time_ident = $server_array[$type."_lastident"] + (($server_array[game_identperiod]*60)*60);
                        }
                //echo $time_stamp."=>".$time_ident."<br>";
                $time_del = $time_stamp - ($time_ident*4);
                  if($time_stamp > $time_ident)
                        {
                        $ftp_server = $server_array[ip];
                        $ftp_user = $server_array[$type."_client_login"];
                        $ftp_pass = $server_array[$type."_client_pass"];
                        $dir = $server_array[$type."_dir"];
                        if(empty($ftp_user))
                                {
                                $ftp_user = "anonymous";
                                $ftp_pass = "offtopic.net.ru";
                                }
                        if($conn_id = ftp_connect($ftp_server) or die("ftp: Не удалось установить соединение с ".$ftp_server))
                                {
                                echo "<b>ПОДКЛЮЧЕНИЕ К [".$ftp_server."] установлено</b><br>";
                                ftp_login($conn_id, $ftp_user, $ftp_pass) or die("ftp: Не удалось войти на сервер ".$ftp_server);
                                ftp_set_option($conn_id, FTP_AUTOSEEK, false);
                                $dir_ar = explode("\n", $dir);
                                foreach($dir_ar as $dir_key=>$dir_value)
                                        {
                                        if(index($config, trim($dir_value)))
                                                {
                                                $var_del = mysql_query("SELECT * FROM ".$config[mysql_table]." WHERE time < '$time_del' AND server_id='$server_id' AND folder LIKE '".$dir_value."%'") or die(mysql_error());
                                                $var_delete = mysql_query("DELETE FROM ".$config[mysql_table]." WHERE time < '$time_del' AND server_id='$server_id' AND folder LIKE '".$dir_value."%'");
                                                $num_of_del = mysql_num_rows($var_del);
                                                echo "<font color='#009900'><b>Не существующие ссылки удалены(".$num_of_del.")</b></font><br>";
                                                if($dir_ar[$dir_key+1] == '')
                                                        {
                                                        $mysql_update = mysql_query("UPDATE ident_servers SET game_lastident = '$time_stamp', game_datasize = '$all_size', game_countfiles = '$count_files' WHERE id = '$server_id' LIMIT 1");
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
?>

Функция Flush для того, чтобы при отладке видеть идёт скрипт или застрял снова, а вообще запускался cron'ом

Автор: WolfON 19.8.2007, 13:51
О ужс. Я думаю никто не будет разбираться в таком огромном месиве кода.
Читайте правила - надо спрашивать только про неработающий участок.
Попробуйте его локализовать.

Автор: Oflashp 20.8.2007, 15:18
Цитата(WolfON @ 19.8.2007,  13:51)
О ужс. Я думаю никто не будет разбираться в таком огромном месиве кода.
Читайте правила - надо спрашивать только про неработающий участок.
Попробуйте его локализовать.

Читайте топик внимательнее.
Ошибки нет. Это видимо, что-то с функциями. Вот я и спрашиваю, что может быть.
И если этот код большой, то я чайник. У меня обычно код меньше 3000 строк не бывает. Это тоже вырезка, рабочая.

Автор: sTa1kEr 21.8.2007, 00:14
Oflashp, вы не пробовали вызывать функцию ftp_rawlist() с 3им параметром, т.е. с рекурсивным вызовом? Так же посмотрите первый комментарий на php.net http://ru2.php.net/manual/en/function.ftp-rawlist.php#76137. Там решается аналогичная задача.

По второму вопросу, не могли бы вы привести тут часть кода, которая отвечает за чтение и запись в файл?

Автор: LAVO 22.9.2007, 14:15
Oflashp, теперь на фтп выложено большое количество файлов, размер которых превосходит 2, 4 и даже 10 ГБ. Сохранить данные о таком размере файла в переменную PHP нельзя. Она поддерживает только положительные числа до 2 в 16 степени... т.е. может хранить информацию о размере файлов вплоть до 2 ГБ, но не более. Далее идет переход в отрицательные числа и после 4 ГБ - переполнение...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)