我找不到我的代码中的错误,我总是没有足够的资金

问题描述 投票:1回答:2

我设置了3个sql表:'client''inv'和'wit'数据库连接可以正常工作,代码中的其他页面也可以,但是此特定页面存在问题。

我有一个页面new.php:

<?php session_start();
if(!isset($_SESSION["email"]))
{
    header("location:../login.php");
    exit;
}
?>

<!DOCTYPE html>
<html lang="en">

<head></head>
<body>
<?php include("header.php"); ?>
<form action="withdraw.php" method="post" class="m-form m-form--label-align-right m-form--fit" id="withdrawalForm">
<input type="hidden" name="email" value="<?php echo $userVal['email']; ?>" />
<input type="hidden" name="w_date" value="<?php echo date("d-m-Y"); ?>" />
<input type="hidden" name="w_status" value="Pending" />
<input type="hidden" name="balance" value="<?php echo $userVal['balance']; ?>" />
<input type="text" name="method" value="" />
<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" />
</body>
</html>

header.php具有:

<?php
     include("pdoconnect.php");

      $id = $_SESSION["email"];
$user = $pdotestconn->prepare("SELECT * FROM client JOIN inv ON client.email = inv.email WHERE client.email = :uname ");
$user->bindParam(":uname", $id);
$user->execute();
$userVal = $user->fetch(PDO::FETCH_ASSOC);

?>

然后我有了withdraw.php:

<?php

include("pdoconnect.php");

$datei=date("D M d, Y g:i a"); 
$email = $_POST['email'];
$wdate = $_POST['w_date'];
$method = $_POST['method'];
$wamount = $_POST['w_amount'];
$wstatus = $_POST['w_status'];
$wallet = $_POST['wallet'];

$user = $pdotestconn->prepare("SELECT * FROM client JOIN wit ON client.email = wit.email WHERE client.email = :uname ");
$user->bindParam(":uname", $email);
$user->execute();
$userVal = $user->fetch(PDO::FETCH_ASSOC);

if ($wamount >= $userVal['balance']) {
        echo "Insufficient Fund";
    } else {
        $balance = $userVal['balance'] - $wamount;

        $ins = $pdotestconn->prepare("INSERT INTO wit (email,w_date,method,w_amount,w_status,wallet) VALUES (:email,:w_date,:method,:w_amount,:w_status,:wallet)");
        $ins->bindParam(":email", $email);

        $ins->bindParam(":w_date", $wdate);
        $ins->bindParam(":method", $method);
        $ins->bindParam(":w_amount", $wamount);
        $ins->bindParam(":w_status", $wstatus);
        $ins->bindParam(":wallet", $wallet);
        $ins->execute();

        $up = $pdotestconn->prepare("UPDATE client SET balance = :credit WHERE email = :email ");
        $up->bindParam(":credit", $balance);
        $up->bindParam(":email", $email);
        $up->execute();
        echo "ok";
    }
?>

每次尝试进行提款时,我都会收到“ 资金不足”,但那里有足够的资金。我需要帮助的人

php html sql pdo
2个回答
2
投票

如果您的代码做了意外的事情,则很有可能在某个地方进行假设。您可以确定的一件事是,如果代码中显示“资金不足”,则它会看到$wamount的值大于或等于$userVal['balance']的值。

这可能是出于两个原因,包括余额未达到您的预期,或者有可能出现某种强制性或类型差异或不正确的字段映射。

我的建议是在if语句之前查看那些值。如果您有调试器并且知道如何使用它,请执行此操作。但是,如果您不这样做,则可以在if语句之前临时添加此代码。

var_dump('Withdrawal amount', $wamount);
var_dump('Balance', $userVal['balance']);

这应该会产生一点输出,告诉您变量$wamount$userVal['balance']的值以及类型。看一下您获得的值。希望问题会很明显。如果不是,请特别注意变量的类型。如果它们不同,例如其中一个是字符串,另一个是浮点数或int等,则PHP正在执行类型强制,并且可能会导致您不了解某些东西,而那会导致值看起来达到您的期望,但实际上不是。

希望这会有所帮助!


0
投票

我整理了一些测试表,以模仿可以从上面推导出的结构(它可能与您的实际db模式不同),并通过上面的代码工作以产生以下内容。这对我的测试有效。注意,在这种情况下,我似乎添加了PDO Transaction语句。我发现的一个问题是隐藏字段中使用的日期格式-如果db表中的列是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 );



        if( floatval( $wamount ) >= floatval( $rs->balance ) ){

            /* Cannot withdraw more than is in the account - error */
            $db->rollback();
            $error='Error: Insufficient funds!';

        } else {
            $status=false;

            $balance = floatval( $rs->balance ) - floatval( $wamount );

            $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='[email protected]';

        /* 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>
© www.soinside.com 2019 - 2024. All rights reserved.