Как в PHP запретить выполнение двух одновременных запросов

I
На сайте с 23.12.2010
Offline
25
#41
goodier:
Я так понял файл lock может иметь название какое угодно и если я его буду при обращении к обработчику создавать файл с таким же именем как у пользователя, то другие пользователи не пострадают?

конечно, это даже распараллелит процесс. при условии что ваша pay функция не пишет в какие-нибудь общие для всех пользователей переменные.

вот здесь почитайте http://stackoverflow.com/questions/2921469/php-mutual-exclusion-mutex

Ragnarok
На сайте с 25.06.2010
Offline
226
#42

опечатался, имелась ввиду php функция abs, которая возвращает модуль числа

//TODO: перестать откладывать на потом
dkameleon
На сайте с 09.12.2005
Offline
386
#43

goodier, господибожемой.....

вас обчистить проще, чем у ребенка конфету отобрать!

какие слипы??? СДЕЛАЙТЕ АТОМАРНОСТЬ!

Только не на файлах, а то вы не учтете многопользовательский вариант,

да и там надежность я бы поставил под сомнение, скажем, если хакер одновременно отправит 100-200 запросов. подозреваю, пройдет больше одного.

Дизайн интерьера (http://balabukha.com/)
goodier
На сайте с 10.03.2009
Offline
36
#44

dkameleon, СКАЖИТЕ МНЕ ПОЖАЛУЙСТА ПО РУССКИ

что значит АТОМАРНОСТЬ - это то что предлагает iopiop

создавать файл и с помощью его блокировать возможность обратиться к файлу обработчику? или что это вообще?

B
На сайте с 03.02.2005
Offline
165
#45
dkameleon:

Только не на файлах, а то вы не учтете многопользовательский вариант,
да и там надежность я бы поставил под сомнение, скажем, если хакер одновременно отправит 100-200 запросов. подозреваю, пройдет больше одного.

Многопользовательский вариант можно, файл лочки должен лочить запросы юзера, а не всей системы.

Хакерство таким образом не пройдёт, всё равно один из запросов будет первым.

ТС у вас принципиально неправильно, отправлять бабло по запросу юзера - нельзя. По запросу юзера надо формировать заявку на выдачу бабла. А выдочу бабла долджен проводить независимый от юзера скрипт (по крону, повесьте раз в минуту, только тоже с лочкой, чтоб два скрипта выдачи нельзя было запустить). При каждой выдаче происходит проверка: достаточно ли средств на балансе, если достаточно - то выдавать, если нет - не выдавать; затем удалять заявку; переходить к следующей заявке.

Интеграция сайтов с 1С (товары, контрагенты, документы, заказы). Консультации и услуги. Есть готовые решения - быстро и недорого. Приглашаю к сотрудничеству агентства и веб-студии.
siv1987
На сайте с 02.04.2009
Offline
427
#46

грубо говоря


$res = mysql_query( 'SELECT * FROM table_users WHERE login = "'. $login .'"' );
$row = mysql_fetch_assoc( $res );

//ставим метку на запись что она в отработке
mysql_query( 'UPDATE table_users SET status="close" WHERE login="'. $login.'"' );

if( $row['status'] == 'close' )
{
die( 'Данная запись в этот момент обрабатывается, повторите попытку позже' );
}

//После того как код отработал

mysql_query( 'UPDATE table_users SET status="open" WHERE login="'. $login.'"' );
LEOnidUKG
На сайте с 25.11.2006
Offline
1724
#47

Я вас уверяю, что проблема в какой-то мелочи, особенно если всё это ещё и через ajax.

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
B
На сайте с 03.02.2005
Offline
165
#48
siv1987:
грубо говоря

$res = mysql_query( 'SELECT * FROM table_users WHERE login = "'. $login .'"' );
$row = mysql_fetch_assoc( $res );

//ставим метку на запись что она в отработке
mysql_query( 'UPDATE table_users SET status="close" WHERE login="'. $login.'"' );

if( $row['status'] == 'close' )
{
die( 'Данная запись в этот момент обрабатывается, повторите попытку позже' );
}

//После того как код отработал

mysql_query( 'UPDATE table_users SET status="open" WHERE login="'. $login.'"' );

Это неправильно. Можно мильён раз успеть получить первый запрос, до того как отработает Update.

Lock-файл значительно надёжней.

<?

$try=false;

while(!$try)

{

if(удалось заблокировать lock-файл)

{

$try=true;

}

else

{

$try=false;

sleep(); // не обязательно, в зависимости от ситуации

}

}

?>

В начало скрипта.

goodier
На сайте с 10.03.2009
Offline
36
#49

betam,

Вот набросал такой код и думаю, что он неправильный.

Ведь если хакер пошлет 100 запросов в секунду, то некоторые сработают потому, что

в WHILE проверятеся заблокирован ли файл, а он уже в условии блокируется и мой код начнет выполнятся.

<?php

session_start();

$login = $_SESSION['username'];

$fp = fopen("LOG_POST/".$login.".txt","a");

$try=false; while(!$try){

if( flock( $fp, LOCK_EX )) { /* уже блокирует файл в условии */

$try=true;

} else {

$try=false;

}

}

if($try){

/* мой скрипт обрабатывается */

if($payout > $userbalance){

flock($fp, LOCK_UN);

fclose($fp);

exit("Недостаточно средств!");

}

mysql_query( 'UPDATE table_users SET balance=balance-$payout WHERE login="'. $login.'"' );

flock($fp, LOCK_UN);

fclose($fp);

exit("Деньги выплачены!");

}

?>

dkameleon
На сайте с 09.12.2005
Offline
386
#50
betam:
Многопользовательский вариант можно, файл лочки должен лочить запросы юзера, а не всей системы.
Хакерство таким образом не пройдёт, всё равно один из запросов будет первым.

конечно можно. я переживаю, что если на это не указать конкретно, то автор темы этот момент не учтет :)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий