goodier

goodier
Рейтинг
36
Регистрация
10.03.2009

Вообще не желательно использовать маленький размер текста, поисковики этого не любят.

Проверяю в любом случае на наличие блокировки и минусового баланса плюс добавил условие в

файл где юзер создает запрос на выплату.

$pay_date = mysql_fetch_row(mysql_query("SELECT `date` FROM `payout` WHERE `login`='$username' ORDER BY `id` DESC LIMIT 1"));
if(in_array(time() , $pay_date)){
exit("Повторите запрос еще раз!");
}

и кто знает, может это условие все бы решило.

Ragnarok:
что если, теоретически, в ту же секунду, как создадутся 2 запроса на вывод, деньги закажет ещё один человек и они занесутся в базу в виде
- первый дублирующийся запрос
- хороший запрос
- второй дубль

if($protect[$k] == $protect[$k-1]) уже не сработает так, как задумано

Я тоже думал над этим, всякое может произойти и придумал, что если проверять в массиве совпадения вот так:

if(in_array($protect[$k] , $protect)) Уже сработает

Ragnarok:
сделай очередь заявок и обрабатывай по порядку, без таких вот извращений

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

iopiop:
PS подумайте что произойдет если в базе появится запись
в момент когда ваш код пройдет эту проверку, но до апдейтов.

В любом случае когда каждую следующую минуту крон будет обращаться к нашему новому файлу,
будет происходить проверка по колонке state=0 и в условии будет сравнивать текущий с
предыдущим значением из массива, просто я другого решения не нашел и стал использовать массив.
Происходит что то типа такого:
если("userlogin-1326839241-100" == "userlogin-1326839241-100"){
то заблокировать и состояние у запроса на выплату обработать как отменено
} иначе {
проверить баланс на отрицательную сумму и если сумма не отрицательная,
только потом выплатить реальные деньги.
}

Проверял, тестировал вроде работает, но тему закрывать все таки пока не стоит,
Нужно дождаться этого хацкера и посмотреть, что получится с его счетом и аккаунтом.

Написал скриптик для крона:

<?php
$path = "/var/www/UserName/data/www/Domain.ru/";
include($path."DB_conf.php");
$query = mysql_query("SELECT * FROM `pay_out` WHERE `state`='0' ORDER BY `id`");
if(mysql_num_rows($query) > 0)
{
$k = 0;
$protect = array('null');
while($res = mysql_fetch_array($query))
{
$k++;
$id = $res['id'];
$login = $res['login'];
$date = $res['date'];
$summa = $res['summa'];
$protect[$k] = $login."-".$date."-".$summa;

if($protect[$k] == $protect[$k-1])
{
mysql_query("UPDATE `users` SET `block`=2 WHERE `login`='$login'");
mysql_query("UPDATE `pay_out` SET `state`=2 WHERE `id`='$id'");

} else {

mysql_query("UPDATE `pay_out` SET `state`=1 WHERE `id`='$id'");
/* Отправляю данные через CURL на другой сервер для выплаты денег */
}
}
}
exit();
?>

Вручную создал 4 одинаковые записи в таблице с запросами на выплату
и подождал минуту, вроде работает пока правильно, но это работает в том случае если UNIX время одинаковое.

Ниже смотрите скрин из таблицы статистики платежей этого красавчика который меня грабит ))

То есть если один раз сработает команда flock( $fp, LOCK_EX ) ,

то повторно она уже не сработает пока не произойдет flock($fp, LOCK_UN)

да или нет, вот этот момент у меня в голове не укладывается.

dkameleon, Многопользовательский вариант - это и есть лочить файл с названием юзера или нет , понять не могу

вот что нашел про flock:

В некоторых операционных системах flock() реализован на уровне процессов. При использовании многопоточных серверных API, таких как ISAPI, вы не можете полагаться на flock() для защиты ваших файлов от дугих PHP-скриптов, которые работают в параллельном потоке на том же сервере!

/*/*/*/*/*/*/

В итоге мне этот вариант не подходит?

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

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

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

<?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("Деньги выплачены!");

}

?>

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, СКАЖИТЕ МНЕ ПОЖАЛУЙСТА ПО РУССКИ

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

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

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

Всего: 78