Я собрал несколько тестовых таблиц, чтобы эмулировать структуру, которая может быть выведена из вышеизложенного (она, вероятно, отличается от вашей фактической схемы БД), и проработал код выше для получения следующего. Это сработало для моих тестов ОК. Обратите внимание, что я добавил операторы транзакций PDO, так как это казалось уместным в этой ситуации. Одна проблема, которую я обнаружил, - это формат даты, используемый в скрытом поле - если столбец в таблице базы данных является полем date
, то это может вызвать ошибки, поэтому я изменил формат в скрытом поле.
mysql> describe client;
+---------+------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(64) | NO | UNI | NULL | |
| balance | decimal(10,2) unsigned | NO | | NULL | |
+---------+------------------------+------+-----+---------+----------------+
mysql> describe wit;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(64) | NO | MUL | NULL | |
| w_date | date | NO | | NULL | |
| method | varchar(50) | NO | | NULL | |
| w_amount | decimal(10,2) | NO | | NULL | |
| w_status | varchar(50) | NO | | NULL | |
| wallet | varchar(255) | NO | | NULL | |
+----------+------------------+------+-----+---------+----------------+
mysql> describe inv;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| email | varchar(64) | NO | MUL | NULL | |
+-------+------------------+------+-----+---------+----------------+
Скрипт все на одной странице для тестирования:
<?php
$error=false;
$message=false;
$dbport = 3306;
$dbhost = 'localhost';
$dbuser = 'root';
$dbpwd = 'xxx';
$dbname = 'xxx';
$options=array(
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL,
PDO::ATTR_PERSISTENT => false,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'utf8mb4\' COLLATE \'utf8mb4_general_ci\', @@sql_mode = STRICT_ALL_TABLES, @@foreign_key_checks = 1'
);
$dsn='mysql:host='.$dbhost.';port='.$dbport.';dbname='.$dbname.';charset=utf8';
$db=new PDO( $dsn, $dbuser, $dbpwd, $options );
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['email'],$_POST['w_date'],$_POST['method'],$_POST['w_amount'],$_POST['w_status'],$_POST['wallet'] ) ){
#$datei=date("D M d, Y g:i a"); /* unused */
$email = $_POST['email'];
$wdate = $_POST['w_date'];
$method = $_POST['method'];
$wamount = $_POST['w_amount'];
$wstatus = $_POST['w_status'];
$wallet = $_POST['wallet'];
/* seems like an appropriate candidate for a `Transaction` !! */
$db->beginTransaction();
$sql='select * from `client` join `wit` on client.email = wit.email where client.email = :uname';
$stmt=$db->prepare( $sql );
$args=array(
':uname' => $email
);
$stmt->execute( $args );
$rs=$stmt->fetch( PDO::FETCH_OBJ );
$balance = floatval( $rs->balance ) - floatval( $wamount );
if( $balance < 0 ){
/* Cannot withdraw more than is in the account - error */
$db->rollback();
$error='Error: Insufficient funds!';
} else {
$status=false;
$sql='insert into `wit` ( `email`, `w_date`, `method`, `w_amount`, `w_status`, `wallet` ) values ( :email, :date, :method, :amount, :status, :wallet )';
$stmt=$db->prepare( $sql );
$args=array(
':email' => $email,
':date' => $wdate,
':method' => $method,
':amount' => $wamount,
':status' => $wstatus,
':wallet' => $wallet
);
$res=$stmt->execute( $args );
if( $res ){
$sql='update `client` set `balance`=:balance where `email`=:email';
$stmt=$db->prepare( $sql );
$args=array(
':balance' => $balance,
':email' => $email
);
$status=$stmt->execute( $args );
}
if( $status ){
$db->commit();
$message=sprintf('Congratulations! You have successfully transferred %s', floatval( $wamount ) );
} else {
$message=sprintf('Sorry, there was a problem transferring %s', floatval( $wamount ) );
}
}
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Money money money</title>
<style>
.error{color:red}
.status{color:green}
</style>
</head>
<body>
<?php
/* to emulate header.php */
$sql='select * from `client` join inv on client.email = inv.email where client.email = :uname';
$stmt=$db->prepare( $sql );
/* Rather than a session, to test a statically declared email will suffice */
$id='client@example.com';
/* In practice you will use $_SESSION['email'] here */
$args=array(
':uname' => $id
);
$res=$stmt->execute( $args );
$userVal=$stmt->fetch( PDO::FETCH_BOTH );
?>
<form method='post'><!-- POST to same page for testing -->
<?php
if( $error )printf( '<h1 class="error">%s</h1>', $error );
if( $message )printf( '<h1 class="status">%s</h1>', $message );
?>
<input type='hidden' name='email' value='<?php echo $userVal['email']; ?>' />
<input type='hidden' name='w_date' value='<?php echo date('Y-m-d'); ?>' /><!-- incorrect date format for DB -->
<input type='hidden' name='w_status' value='Pending' />
<input type='hidden' name='balance' value='<?php echo $userVal['balance']; ?>' />
<input type='text' name='method' value='' placeholder='Method' />
<input type='text' name='balance' value='$<?php echo $userVal['balance']; ?>' disabled=true readonly />
<input type='number' name='w_amount' value='' placeholder='<?php echo $userVal['balance']; ?> or less' required />
<input type='text' name='wallet' value='' placeholder='Wallet Address' required />
<input type='submit' name='withdraw' value='Withdraw' />
</form>
</body>
</html>