ExBB Community ExBB Community
 Сайт проекта ExBB Общение объединяет!
Войдите на форум при помощиВойти через loginza
 Чат на форуме      Помощь      Поиск      Пользователи     BanList BanList


 Страниц (2): [1] 2 »   

> Без описания
khapugin
Отправлено: 28 марта 2010 — 06:50
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


Помогите пожалуйста. Пишу партнёрку, нужен совет.
Нужно записывать IP адреса в файл, а потом брать их из него и сравнивать с тем который у пользователя. В интернете кто то советовал использовать для записи такой код. Будет ли скрипт эффективен в случае если он будет одновременно запущен несколькими пользователей, не приведёт ли это к обнулению файла? Посоветуйте как правильнее написать?

CODE:
$lock = fopen("./partner/baseIP.db", "a"); //блокировка файла
if(flock($lock, 1)) {
copy ("./partner/baseIP.db", "./partner/tmpbaseIP.db");
$tmp=fopen("./partner/tmpbaseIP.db","a");
fputs($tmp, $IP."\r\n"); //запись строк
fclose($tmp); //закрытие файлка и переименование его
flock($lock, 3);
fclose($lock);
unlink("./partner/baseIP.db");
rename("./partner/tmpbaseIP.db", "./partner/baseIP.db");
}
 
 
Александр Михалицын
Отправлено: 28 марта 2010 — 07:06
Post Id


Администратор
Super Member


Покинул форум
Сообщений всего: 723
Дата рег-ции: Февр. 2009  
Репутация: 42




khapugin,
к чему столько сложностей? Код можно проще переписать.

CODE:
//Реализация:
function add_ip_to_db($ip)
{
$fp = fopen('ip.db', 'a');//Открываем файл
flock($fp, LOCK_EX);//Блокируем файл
fwrite($fp, $ip . "\r\n");//Пишем в файл
fflush($fp);//Сбрасываем буфер (в PHP существует система буферизации записи)
flock($fp, LOCK_UN);//Снимаем блокировку
fclose($fp);//Закрываем файл
}

//Использование (пример):
add_ip_to_db($_SERVER['REMOTE_ADDR']);//Добавляем в базу айпи посетителя.
 
 
khapugin
Отправлено: 28 марта 2010 — 08:54
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


Вот такие вот умельцы в интернете Улыбка) Говорят, что так можно избежать потери данных если несколько пользователей одновременно будут писать в файл свой ip.

Можно тогда несколько вопросов по вашему коду?
1. Код действительно безопасный для данных хранящихся в файле?
2. fflush служит для уменьшения нагрузки на сервер?
3. По вашему проверять заблокирован ли файл не обязательно?

(Отредактировано автором: 28 марта 2010 — 09:04)

 
 
yura3d
Отправлено: 28 марта 2010 — 10:37
Post Id


Пользователь
ExBB Team
ExBB Developer
ExBB Mods Author


Покинул форум
Сообщений всего: 3394
Дата рег-ции: Февр. 2009  
Откуда: Минск, Беларусь
Репутация: 353




khapugin пишет:
Помогите пожалуйста. Пишу партнёрку, нужен совет.
Нужно записывать IP адреса в файл, а потом брать их из него и сравнивать с тем который у пользователя. В интернете кто то советовал использовать для записи такой код. Будет ли скрипт эффективен в случае если он будет одновременно запущен несколькими пользователей, не приведёт ли это к обнулению файла? Посоветуйте как правильнее написать?

CODE:
$lock = fopen("./partner/baseIP.db", "a"); //блокировка файла
if(flock($lock, 1)) {
copy ("./partner/baseIP.db", "./partner/tmpbaseIP.db");
$tmp=fopen("./partner/tmpbaseIP.db","a");
fputs($tmp, $IP."\r\n"); //запись строк
fclose($tmp); //закрытие файлка и переименование его
flock($lock, 3);
fclose($lock);
unlink("./partner/baseIP.db");
rename("./partner/tmpbaseIP.db", "./partner/baseIP.db");
}

Тот вариант, который Вы привели, довольно странный. Не совсем понятно, что должен делать приведённый Вами фрагмент кода, но потенциальные проблемы такого подхода видны сразу. В самом начале идёт проверка на разделяемую (для чтения) блокировку:
CODE:
if(flock($lock, 1)) {

А дальше идёт вообще полная ерунда: создание временного файла, запись в него информации и далее, собственно, сама ошибка, когда предпринимается попытка переименовать временный файл в основной. Ппри этом вполне возможно, что процессы чтения со стороны других пользователей не окончились или были запущены новые, и в этом случае Вы получите повреждение или обнуление данных в файле.

khapugin пишет:
1. Код действительно безопасный для данных хранящихся в файле?

Предложенный Александром Михалицыном вариант классический с точки зрения решения проблемы с множественным доступом к файлам из PHP.

khapugin пишет:
2. fflush служит для уменьшения нагрузки на сервер?

Читайте описание функции в мануале PHP: http://php.net/fflush
Эту функцию необходимо запускать, чтобы сбросить в файл все накопившиеся в буфере данные (поскольку непосредственно после записи данные могут в файл и не быть записаны, как правило запись в файл происходит только после накопления определённого объёма информации - это сделано для ускорения работы).

khapugin пишет:
3. По вашему проверять заблокирован ли файл не обязательно?

Файл не будет заблокирован только в том случае, если соответствующая функция не поддерживается используемыми операционной или файловой системами. Поскольку с такими системами Вы, скорее всего, работать не будете, то делать проверку на блокировку не имеет смысла. Проверять установку блокировки нужно, если Вы используете блокировку с запретом подвисания, однако такая блокировка далеко не лучший вариант (она использовалась в ExBB FM 1.0 Beta и более старых версиях, поэтому на тех версиях были гораздо более частые проблемы с обнулением).

Ну и напоследок, если к файлам предполагается довольно частое обращение при хранении большого объёма данных, лучше подумать о MySQL
 
 
khapugin
Отправлено: 28 марта 2010 — 11:05
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


Спасибо ребята Хорошо

Цитата:
Ну и напоследок, если к файлам предполагается довольно частое обращение при хранении большого объёма данных, лучше подумать о MySQL

ох и не люблю я эту MySQL, а частое это примерно сколько? 1000? 2000? обращений в сутки? Сколько примерно?
 
 
Леголегс
Отправлено: 28 марта 2010 — 19:10
Post Id


Пользователь
Junior Member


Покинул форум
Сообщений всего: 87
Дата рег-ции: Март 2010  
Репутация: 12




fflush можно выкинуть, но только вместе с unlock. fclose автоматиччески делает сброс буфера и разблокировку.
khapugin пишет:
а частое это примерно сколько? 1000? 2000? обращений в сутки? Сколько примерно?
В данном случае это запросы в секунду.
 
 
khapugin
Отправлено: 24 апреля 2010 — 07:35
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


Помогите пожалуйста, мучаюсь уже часов 6...
задача на первый взгляд простая, но я уже задолбался нифига у меня не выходит(((

Суть задачи такая, есть некая директория в которой несколько папок с порядковыми именами 1, 2, 3, 4 и файл index.html задача скрипта выявить папку самого высокого названия в данном случае 4 прибавить к этому числу единицу и создать новую папку. Выполняется это тремя строчками.

CODE:
$spisokdir = scandir('../papka/');
$newpapka = max($spisokdir) + 1;
mkdir('../papka/' . $newpapka, 0777); // создаём папку


получаем список файлов и папок в дирректории
находим максимальное название числа и создаём папку на единицу больше, проблема начинается как только скрипт натыкается на файлы или папки отличные от цифр
 
 
yura3d
Отправлено: 24 апреля 2010 — 09:09
Post Id


Пользователь
ExBB Team
ExBB Developer
ExBB Mods Author


Покинул форум
Сообщений всего: 3394
Дата рег-ции: Февр. 2009  
Откуда: Минск, Беларусь
Репутация: 353




khapugin пишет:
проблема начинается как только скрипт натыкается на файлы или папки отличные от цифр

В Вашем случае список (массив) файлов и папок нужно предварительно отфильтровать таким образом, чтобы в нём остались только папки, названия которых состоят из цифр. Это необходимо для правильной работы функции PHP max():
CODE:
function int_dir_filter($filename)
{
if (is_int($filename) && is_dir('../papka/'.$filename))
return true;

return false;
}

$spisokdir = array_filter(scandir('../papka/'), 'int_dir_filter');
$newpapka = max($spisokdir) + 1;
mkdir('../papka/' . $newpapka, 0777); // создаём папку

Подробнее про фильтрацию элементов массива при помощи функции обратного вызова можно почитать в документации PHP по функции array_filter().
 
 
khapugin
Отправлено: 24 апреля 2010 — 09:49
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


непонимаю почему но код не работает Однако

ошибки
Warning: max() [function.max]: Array must contain at least one element in Y:\home\test1.ru\www\myphp\1.php on line 9
Warning: mkdir() [function.mkdir]: File exists in Y:\home\test1.ru\www\myphp\1.php on line 10

CODE:
function int_dir_filter($filename)
{
if (is_int($filename) && is_dir('../user/'.$filename) && $filename != '.' && $filename != '..')
return true;
return false;
}
$spisokdir = array_filter(scandir('../user/'), 'int_dir_filter');
$newuser = max($spisokdir) + 1;
mkdir('../user/' . $newuser, 0777); // создаём папку

Я ещё заглянул в масив и обнаружил там две директории "." и ".." перехода выше. их я тоже проверяю, но всё равно ошибка... в чём же дело?
 
 
Hast
Отправлено: 24 апреля 2010 — 10:01
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 7
Дата рег-ции: Апр. 2010  
Репутация: 0




Достаточно перевести текст ошибки.

khapugin пишет:
Warning: max() [function.max]: Array must contain at least one element

в массиве $spisokdir должен быть по крайней мере 1 элемент
khapugin пишет:
Warning: mkdir() [function.mkdir]: File exists

папка которую ты пытаешься создать уже существует

(Отредактировано автором: 24 апреля 2010 — 10:01)

 
 
yura3d
Отправлено: 24 апреля 2010 — 10:05
Post Id


Пользователь
ExBB Team
ExBB Developer
ExBB Mods Author


Покинул форум
Сообщений всего: 3394
Дата рег-ции: Февр. 2009  
Откуда: Минск, Беларусь
Репутация: 353




khapugin пишет:
CODE:
$filename != '.' && $filename != '..'

Такая проверка не имеет смысла, у Вас ведь уже есть проверка на то, чтобы имя принадлежало множеству целых чисел:
CODE:
is_int($filename)

Очевидно, что имена переходов на предыдущий уровень этому множеству не принадлежат, поэтому Вы делаете лишнюю проверку, что в конечном итоге не самым лучшим образом скажется на производительности. Оставьте первоначальный предложенный мною вариант:
CODE:
if (is_int($filename) && is_dir('../papka/'.$filename))


khapugin пишет:
Warning: max() [function.max]: Array must contain at least one element

Всё просто. Предполагается, что у Вас в папке papka уже имеется хотя бы одна папка, соответствующая критериям фильтра. В противном случае функции max() передаётся пустой массив $spisokdir, что недопустимо. Если в Вашем случае допускается отсутствие первой папки, соответствующей критериям фильтра, то лучше сделать так:
CODE:
function int_dir_filter($filename)
{
if (is_int($filename) && is_dir('../papka/'.$filename))
return true;

return false;
}

$spisokdir = array_filter(scandir('../papka/'), 'int_dir_filter');
$newpapka = ($spisokdir) ? max($spisokdir) + 1 : X;
mkdir('../papka/' . $newpapka, 0777); // создаём папку

В этом примере в строке:
CODE:
$newpapka = ($spisokdir) ? max($spisokdir) + 1 : X;

вместо X Вам нужно указать имя первой папки, которая будет создана в папке papka. В дальнейшем все новые папки будут создаваться с числовым именем, на единицу большим, чем у предыдущей созданной папки.
 
 
Hast
Отправлено: 24 апреля 2010 — 10:09
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 7
Дата рег-ции: Апр. 2010  
Репутация: 0




Если конкретно по тому, что должен делать скрипт. Во-первых, пользователь которого ты пытаешься создать уже существует. Точнее, это ошибка, вытекающая из другой: max($spisokdir) возвращает 0, поэтому $newuser равняется единице.
Во-вторых
khapugin пишет:
ещё заглянул в масив и обнаружил там две директории "." и ".." перехода выше.

Как-то не стыкуется. Скрипт утверждает что в массиве $spisokdir нет ни одного элемента. А тут ты говоришь, что заглянул в массив и нашёл там "." и "..". м?
(Добавление)
CODE:
$newpapka = ($spisokdir)

Вроде как данное условие не всегда будет возвращать false. Ошибка "Array must contain at least one element" как бы предполагает, что $spisokdir уже инициализирован как массив, иначе ошибка звучала бы как "1st param must be an array". Или я не прав? Сейчас сервера под рукой нет, проверить не могу, к сожалению. Если я прав, то проверку нужно производить как
CODE:
$newpapka = ($spisokdir[0])
или
CODE:
$newpapka = (count($spisokdir) > 0)

(Отредактировано автором: 24 апреля 2010 — 10:17)

 
 
yura3d
Отправлено: 24 апреля 2010 — 11:02
Post Id


Пользователь
ExBB Team
ExBB Developer
ExBB Mods Author


Покинул форум
Сообщений всего: 3394
Дата рег-ции: Февр. 2009  
Откуда: Минск, Беларусь
Репутация: 353




Результатом работы функции array_filter() будет всегда массив, в частном случае это может быть пустой массив, если критерию фильтрации не соответствует ни один элемент. Поэтому проверка:
Hast пишет:
CODE:
$newpapka = ($spisokdir[0])

закончится нотисом Undefined offset: 0..., если массив пуст.

Hast пишет:
CODE:
$newpapka = (count($spisokdir) > 0)

В данном случае выражение в скобках справа от оператора присваивания (=) равнозначно выражению ($spisokdir), но последнее будет работать несколько быстрее.

Hast пишет:
Вроде как данное условие не всегда будет возвращать false

Пруфлинк из официальной документации - для пустых массивов приведение к типу boolean (а выражение в конструкции if всегда к таковому приводится) даст false. Если массив содержит хотя бы один элемент, результат приведения будет true.
 
 
khapugin
Отправлено: 24 апреля 2010 — 11:08
Post Id


Пользователь
Newbie


Покинул форум
Сообщений всего: 33
Дата рег-ции: Авг. 2009  
Репутация: 0

[+]


Большое спасибо вам обоим))) Нашёл решение
кому нибудь пригодится рабочий код
CODE:
<?php
function int_dir_filter($filename)
{
if (!is_int($filename) && is_dir('../user/'.$filename))
return true;
return false;
}
$spisokdir = array_filter(scandir('../user/'), 'int_dir_filter');
$newuser = max($spisokdir) + 1;
mkdir('../user/' . $newuser, 0777); // создаём папку
?>

проблема была !is_int($filename) в нём Хорошо
____________________________________________________
is_int - определяет, является ли переменная integer.
Описание

bool is_int (mixed var)

Возвращает TRUE, если var является integer, FALSE - в ином случае.

теперь непонятно ведь насколько я понимаю !is_int($filename) это как раз обратное тому что мне нужно, но скрипт заработал Не понял
(Добавление)
yura3d пишет:
$newpapka = ($spisokdir) ? max($spisokdir) + 1 : X;

у меня и без этой строки проблем не возникает когда удаляю все папки.

(Отредактировано автором: 24 апреля 2010 — 11:21)

 
 
yura3d
Отправлено: 24 апреля 2010 — 11:48
Post Id


Пользователь
ExBB Team
ExBB Developer
ExBB Mods Author


Покинул форум
Сообщений всего: 3394
Дата рег-ции: Февр. 2009  
Откуда: Минск, Беларусь
Репутация: 353




khapugin пишет:
теперь непонятно ведь насколько я понимаю !is_int($filename) это как раз обратное тому что мне нужно, но скрипт заработал

Вообще, честно говоря, всё правильно. Функция is_int() возвращает true только в том случае, если аргумент принадлежит типу integer. В нашем же случае имена файлов и папок принадлежат строковому типу string, поэтому is_int() возвращает false. Думаю, вместо is_int() лучше применить функцию ctype_digit(), она обрабатывает строковые переменные и возвращает true только в том случае, если все символы в строке являются цифрами.

Таким образом, правильным будет вариант:
CODE:
function int_dir_filter($filename)
{
if (ctype_digit($filename) && is_dir('papka/'.$filename))
return true;

return false;
}

$spisokdir = array_filter(scandir('papka/'), 'int_dir_filter');
$newpapka = ($spisokdir) ? max($spisokdir) + 1 : 0;
mkdir('papka/' . $newpapka, 0777); // создаём папку


khapugin пишет:
у меня и без этой строки проблем не возникает когда удаляю все папки.

Это из-за неразберихи с is_int() в предыдущих примерах. Если в исправленном варианте убрать данную проверку, то передача пустого массива функции max() приведёт к выводу предупреждения:
Цитата:
Warning: max() [function.max]: Array must contain at least one element
 
 
Страниц (2): [1] 2 »
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« PHP/Perl »

> Похожие темы: Есть ли ошибки в скрипте?
Темы Форум Информация о теме Обновление
Критические обновления для ExBB FM 1.0 RC1
Обновления (патчи), устраняющие ошибки в работе форуме
Новости Ответов: 0
Автор темы: yura3d
15 июля 2009 — 19:10
Автор: yura3d
Превью изображения расположить горизонтально
Есть возможность?
Настройка форума Ответов: 7
Автор темы: mastersound
24 ноября 2010 — 14:02
Автор: Pauk
sitemap для форума
Есть ли какой мод для создания карты сайта (форума)
Модификации и дополнения Ответов: 0
Автор темы: GreatALF
22 мая 2014 — 04:53
Автор: GreatALF
Уважаемые администраторы помогите пожалуйста
ошибка на скрипте!!!!
Решение проблем Ответов: 1
Автор темы: kysovich
24 ноября 2010 — 23:48
Автор: yura3d
Испортилась тема
И выдает ошибки
Решение проблем Ответов: 2
Автор темы: Mashtab
15 апреля 2009 — 13:13
Автор: Mashtab
 



Все гости форума могут просматривать этот раздел.
Только администраторы и модераторы могут создавать новые темы в этом разделе.
Только администраторы и модераторы могут отвечать на сообщения в этом разделе.
 




Яндекс.Метрика   

Powered by ExBB
ExBB FM 1.0 RC1 by TvoyWeb.ru
InvisionExBB Style converted by Markus®

[Script Execution time: 0.0811]     [ ]