Есть скрипт. Работает, делает все, как надо. Но вот выполняется он слишком долго (около 15 секунд) жрет 100% проца и 5мб оперативы!(я уже подумал, не разместить ли мне этот топ в HUMOR). Вроде ничего особенного там нет и файлы по 2Кб, в чем может быть дело? Может кто знает? PHP: <?php ini_set("session.use_trans_sid", true); session_start(); $nickq = $_REQUEST['nick']; $passq = $_REQUEST['pass']; $nickq = trim($nickq); $passq = trim($passq); $passq = md5($passq); $nickq = strtolower($nickq); $pnu = "udb/online.u"; $erru = false; $file = fopen("udb/users.dbs", "a+t"); flock($file, LOCK_EX); $us = explode("\n", fread($file, (filesize("udb/users.dbs")+1))); for($i=0;$i<=count($us); $i++){ $m = $us[$i]; $m = trim($m); $r = strpos($m, "="); $nick = substr($m, 0, $r); $pass = substr($m, ($r+1)); $nick = strtolower($nick); if($nick==$nickq && $pass==$passq){ $filen = @fopen($pnu, "r+t"); if(!$filen){ $filen = fopen($pnu, "a+t"); flock($filen, LOCK_EX); if(filesize($pnu)==0){ $put = "**********\n"; fputs($filen, $put); fclose($filen); $filen = fopen($pnu, "r+t"); } } flock($filen, LOCK_EX); $uso = explode("\n", fread($filen, (filesize($pnu)+1))); for($i=0;$i<count($uso);$i++){ $m = $uso[$i]; $m = trim($m); if($m !== $nick && $i == (count($uso)-1)){ fclose($filen); fclose($file); $_SESSION['auth']="OK"; $_SESSION['nick']=$nick; setcookie("nick", $nick); $_SESSION['first']=true; Header("Location: http://{$_SERVER['SERVER_NAME']}{$hostpoddir}/chat.php"); } if($m == $nick){ $erru = true; break; } } } } fclose($filen); fclose($file); ?> P.S. Если есть советы по коду, приму, т.к. он очень сырой и будет еще сотни раз апдетиться.
Весит 2Кб. Принцип в том, чтобы все сделать без БД чисто на файловой структуре. Причем, перед тем, как я добавил $filen все работало отлично, может это как-то связано с перекресной блокировкой?(кстати, это мысль, надо прошерстить!)
Davil, а вы специально файл "udb/online.u" открываете столько раз сколько строк в файле "udb/users.dbs" ? и при этом для каждой строки из "users.dbs" вы в цикле просматриваете все записи одного и того же файла "online.u"... (оправдание что это делается потому что online.u может измениться во время исполнения скрипта, сами понимаете - фигня !) Переделайте так: 1) один раз грузится online.u, распихивается в ассоциированный массив, $online[$nick] = ... 2) сравнение производится по индексам типа (isset($online[$user])) 3) извращенные конструкции типа Код (Text): $file = fopen("udb/users.dbs", "a+t"); flock($file, LOCK_EX); $us = explode("\n", fread($file, (filesize("udb/users.dbs")+1))); легко заменяются на $us = @file("udb/users.dbs");
Я думал, что код в операторе if() выполняется только при подтверждении условия... Выполняется интерпретатором в сотни раз быстрее, чем конструкция А блокировка мне необходима потому, что файл users.dbs может поменяться привыполнении этого кода. Предпочитаю пользоваться собаками только в виде исключения. В этом случае (как мне кажется) лучше обойтись без нее, иначе во время runtime может произойти нечто УЖАСНОЕ P.S. Спасибо за критику.
во первых не те конструкции сравниваете - нужно было сравнивать с file(), а то с чем вы сравнили (оно вообще не относится к файловому вводу/выводу) уверяю вас работает намного быстрее. во вторых file() сработает быстрее чем fopen + explode("\n",fread()) хоть и делает тоже самое... посмотрите исходники самого php это вам только кажется, что блокировка вам необходима - в обоих случаях вы загружаете файлы целиком сразу после открытия и их можно тут же закрывать после этого... ужасное происходит обычно когда одну переменную используют во вложенных циклах, типа как у вас: Код (Text): for($i=0;$i<=count($us); $i++){ for($i=0;$i<count($uso);$i++){ а от собаки хуже не станет - она просто удавит warning если файл будет отсутсвовать, что вполне нормально при файловой организации данных, - просто не обращайте на нее внимание.
Ответ: Цитата из книги Дмитрия Котерова PHP5: $f = fopen($fname="file.txt", "rt"); $lines = explode("\n", fread($f, filesize($fname))); Эти две строчки не только поместят в массив $lines все строки файла, но еще и: -- Удалят лишние символы перевода строки (\n); -- Удалят символы \r (на счет режима открытия файла "rt"); -- Сделают это даже быстрее, чем сработала бы функция file(). Последний пункт наводит на размышление, но простая проверка показывает: да, пара fread()+explode() работает быстрее, чем один вызов file(). Парадокс. Все - таки эта блокировка необходима из - за возможности синхронного использования этого скрипта с другим. При этом получится бяка Согласен, мой косяк. Спасибо за замечание. Я так и поступил. Причем сразу после этого сделал проверку данной функции на false.
Все, я нашел проблему. В файле, который вставлялся через require_once был лишний пробел. Странно, почему ошибка модификации хедеров не выводилась? Я уже написал почти все заново, а тут такая лабуда... Впринципе я выяснил несколько вещей, которые надо поменять вопреки совету главной страницы php.ru