0

下面是我的代码:

<?php
$response = array();

if ($_POST['code_input'] != ''){
    $code_input = $_POST['code_input'];
    $email_code = $_POST['email_code'];

    $link = mysql_connect('localhost','root','') or die ('Could not connect: '.mysql_error());
    mysql_select_db('ichop') or die ('Could not connect to database');

    //check if redemption code exist
    $exist = mysql_query("select * from redemption where red_code = '$code_input'");

    //check if redemption code is usable
    $usable = mysql_query("select * from redemption where code_status = 'usable' and red_code = '$code_input'");

    //check if users already have the card
    $possess = mysql_query("select * from customer customer join card card on customer.customer_id = card.customer_id join redemption redemption on card.merchant_id = redemption.merchant_id where card.merchant_id = redemption.merchant_id and redemption.red_code = '$code_input'");

    //check if reward name is "reward point"
    $point = mysql_query("SELECT * FROM redemption redemption JOIN reward reward ON redemption.merchant_id = reward.merchant_id WHERE reward.reward_name LIKE  '%point%' AND redemption.red_code =  '$code_input'");
    $data3 = mysql_fetch_array($point);

    $customer = mysql_query("select * from customer where C_email = '$email_code'");
    $data1 = mysql_fetch_array($customer);

    $merchant = mysql_query("select * from redemption where red_code = '$code_input'");
    $data2 = mysql_fetch_array($merchant);

    $card = mysql_query("select redemption.Total_Point, card.card_id from customer customer join card card on customer.customer_id = card.customer_id join redemption redemption on card.merchant_id = redemption.merchant_id where redemption.red_code = '$code_input'");
    $data4 = mysql_fetch_array($card);

    if(mysql_num_rows($exist) == 1){
        if(mysql_num_rows($usable) == 1){
            if(mysql_num_rows($possess) == 1){

            } else {
                //create new card for customer              
                $create = mysql_query("INSERT INTO card (Card_ID, Chop_Amt, Customer_ID, Merchant_ID) VALUES ('', '0', '".$data1["Customer_ID"]."', '".$data2["Merchant_ID"]."')");

                if(mysql_num_rows($point) == 1){
                    //update the chop amount in card details
                    $update1 = mysql_query("UPDATE card SET Chop_Amt = '".$data3["Total_Point"]."' where Customer_ID = '".$data1["Customer_ID"]."' and Merchant_ID = '".$data2["Merchant_ID"]."'");

                    $update2 = mysql_query("UPDATE redemption SET Code_Status = 'Unusable', Red_Date = now(), Point_Balance = '".$data3["Total_Point"]."', Card_ID = '".$data4["Card_ID"]."' where red_code = '$code_input'");

                    $response["success"] = 1;
                    $response["message"] = "Code redeemed!";

                    echo json_encode($response);
                } else {
                    $response["success"] = 0;
                    $response["message"] = "You do not have enough point to use the code!";

                    echo json_encode($response);
                }
            }
        } else {
            //error for non-usable code
            $response["success"] = 0;
            $response["message"] = "Code is not usable!";

            echo json_encode($response);
        }
    } else {
        //error for non existing code
        $response["success"] = 0;
        $response["message"] = "Code does not exist!";

        echo json_encode($response);
    }
} else {
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    echo json_encode($response);
}
?>

我的情况是,如果他们没有 1,我希望我的系统在“卡”中创建一个新记录,然后相应地更新“兑换”表..

但是,我只设法创建了一张新卡,但无法更新“兑换”表……有人可以帮我吗?请告诉我您需要检查的任何事情...谢谢!

我努力了

$card = mysql_query("select redemption.Total_Point, card.card_id from customer customer 
join card card on customer.customer_id = card.customer_id 
join redemption redemption on card.merchant_id = redemption.merchant_id 
where redemption.red_code = '$code_input'");
$data4 = mysql_fetch_array($card);

在一个单独的 php 文件中,我可以获得我想要的数据...但是我不明白为什么它没有更新><

4

2 回答 2

0

如果不调试代码——单步调试——我无法弄清楚发生了什么,但是代码的结构方式使得很难遵循逻辑。单个 SQL 查询没有按照您的预期执行可能会导致它静默失败,并且有大量嵌套条件使得很难跟上正在发生的事情。

我觉得您可以更有效地编写更新 - 您正在从其他查询中将数据抓取到 PHP 变量中,并将它们传递给更新,您可能可以通过在更新语句中加入该数据来做到这一点。

其次,请考虑“早破”。例如:

if ($_POST['code_input'] == ''){
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    die json_encode($response);
}

这会将您在验证步骤后立即发回的错误放在代码文件的另一端,而不是放在代码文件的另一端。

接下来,考虑将所有这些验证/数据检索步骤分解为它们自己的函数。因此,请考虑以下代码,而不是上面的代码:

if (!isInputValid($_POST['code_input'])){
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    die json_encode($response);
}
function isInputValid($input){
    if ($input == ''){
       return false;
    }
    return true; 
}

接下来,考虑不要依赖多个 MySQL 结果集及其奇怪的“返回 FALSE 或数组”行为。考虑创建一个名为$totalPoints,而不是的变量$data3["Total_Point"]

试试这个,我很确定这个错误会变得很明显......

于 2013-05-19T20:17:52.293 回答
0

您应该开始使用PDO而不是mysql_*函数,因为它们已被弃用。此外,您应该更加小心查询 - 我看到您从同一个表中选择了几乎相同的信息几次,但只请求不同的列。例如$exist,这些查询$usable可以合并为一个查询,然后您可以使用简单的if/else语句检查查询结果。这将节省一些系统资源,并且会更快地加载应用程序。

另外,当别名本身与表名相同时,我不明白为什么在 sql 查询中使用表别名?别名适用于您想要缩短表名(即my_table_namemtn使其更容易和更快速地编写)或者如果您要连接几个具有相同名称但含义和用法不同的列的表的情况。

关于您编写​​的代码,正如@Neville K 指出的那样,很难确定它有什么问题。您编写它的方式并不容易调试。我花时间使用PDO. 该代码很可能不会立即工作 - 我没有测试过它,我没有你的数据库结构。您可能需要做一些工作才能使其正常工作。我想建议您不要使用变量名,例如data,data1data2。尝试给变量起一个有意义的名称,并澄清它所包含的数据。

这是代码:

<?php

$response = array();
$code_input = $_POST['code_input'];
$email_code = $_POST['email_code'];

if ($code_input != "" && $email_code != ""){

    // PDO link to database;
    $host = 'localhost';
    $port = 3306;
    $dbname = 'ichop';
    $dbuser = 'PUT_YOUR_DB_USER_HERE';
    $dbpass = 'PUT_YOUR_DB_USER_PASS_HERE';
    $connect_string = "mysql:host=".$host.";port=".$port.";dbname=".$dbname;
    $db = new PDO( $connect_string, $dbuser, $dbpass );
    $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

    // Get the code from the database using a prepared statement (ps in the variables stands for Prepared Statement)
    $rps = $db->prepare('
    SELECT *
    FROM redemption
    WHERE red_code = :code_input');
    // Bind a the value from $code_input to the :code_input variable in the sql code.
    $rps->bindValue(':code_input', $code_input, PDO::PARAM_STR); // If the $code_input is an integer, use PDO::PARAM_INT
    // Execute the query
    $rps->execute();
    // Fetch the results
    // - PDO::FETCH_ASSOC would return an associative array, containing the column names of the table
    //   i.e.
    //   array(
    //      'red_code' => 1234,
    //      'usable' => true
    //      ..........
    //   )
    // For more information visit http://www.php.net/manual/en/pdo.constants.php
    $redemption_code = $rps->fetch(PDO::FETCH_ASSOC);

    // Check if the code exists in the database.
    if($redemption_code != ""){
        // Check if the code is usable
        if($redemption_code['usable'] == 1 && $redemption_code['red_code'] == $code_input) {
            //check if users already have the card
            $pps = $db->prepare('
            SELECT *
            FROM customer
            JOIN card on customer.customer_id = card.customer_id
            JOIN redemption redemption on card.merchant_id = redemption.merchant_id
            WHERE card.merchant_id = redemption.merchant_id
            AND redemption.red_code = :code_input');
            $pps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
            $pps->execute();
            $possessed = $pps->fetch(PDO::FETCH_ASSOC);

            // This card haven't been used yet
            if($possessed == ""){
                // check if reward name is "reward point"
                // I believe this code can be merged with $redemption_code but I don't know your database structure so I'm leaving it as is.
                $point_ps = $db->prepare("
                SELECT *
                FROM redemption redemption
                JOIN reward reward ON redemption.merchant_id = reward.merchant_id
                WHERE reward.reward_name LIKE '%point%'
                AND redemption.red_code = :code_input");
                $point_ps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                $point_ps->execute();
                $point = $point_ps->fetch(PDO::FETCH_ASSOC);

                // Please check if the column name "C_email" is with a capital C. Do the check for the column names in the other queries as well.
                $customer_ps = $db->prepare('SELECT * FROM customer WHERE C_email');
                $customer_ps->bindValue(':email_code', PDO::PARAM_STR);
                $customer_ps->execute();
                $customer = $customer_ps->fetch(PDO::FETCH_ASSOC);

                // I've got no idea what this is.
                $cdps = $db->prepare("
                SELECT
                    redemption.Total_Point,
                    card.card_id
                FROM customer
                JOIN card ON customer.customer_id = card.customer_id
                JOIN redemption ON card.merchant_id = redemption.merchant_id
                WHERE redemption.red_code = :code_input");
                $cdps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                $card = $cdps->fetch(PDO::FETCH_ASSOC);

                // Create new card for the customer
                $insert_ps = $db->prepare("INSERT INTO card(Chop_Amt, Customer_ID, Merchant_ID) VALUES ('0', :customer_id, :merchant_id)");
                $insert_ps->bindValue(':customer_id', $customer["Customer_ID"], PDO::PARAM_INT);
                $insert_ps->bindValue(':merchant_id', $redemption_code["Merchant_ID"], PDO::PARAM_INT);
                $insert_ps->execute(); // This will return true on successful insert and false on unsuccessful.

                if($insert_ps) {
                    // If, when executing the code, the redemption & card tables don't get updated
                    // you need to debug the $point variable - see if a record is being returned and
                    // if that's what you need.
                    if($point != ""){
                        $card_update_ps = $db->prepare("UPDATE card SET Chop_Amt = :total_point WHERE Customer_ID = :customer_id AND Merchant_ID = merchant_id");
                        $card_update_ps->bindValue(':customer_id', $customer["Customer_ID"], PDO::PARAM_INT);
                        $card_update_ps->bindValue(':merchant_id', $redemption_code["Merchant_ID"], PDO::PARAM_INT);
                        $card_update_ps->bindValue(':total_point', $point["Total_Point"], PDO::PARAM_INT); // I guess this is an integer?
                        $card_update_ps->execute();

                        $redemption_update_ps = $db->prepare("UPDATE redemption SET Code_Status = 'Unusable', Red_Date = now(), Point_Balance = :total_point, Card_ID = :card_id WHERE red_code = :code_input");
                        $redemption_update_ps->bindValue(':code_input', $code_input, PDO::PARAM_STR);
                        $redemption_update_ps->bindValue(':total_point', $point["Total_Point"], PDO::PARAM_INT);
                        $redemption_update_ps->bindValue(':card_id', $card['Card_ID'], PDO::PARAM_INT);
                        $redemption_update_ps->execute();

                        $response["success"] = 1;
                        $response["message"] = "Code redeemed!";

                        echo json_encode($response);
                    } else {
                        $response["success"] = 0;
                        $response["message"] = "You do not have enough point to use the code!";

                        echo json_encode($response);
                    }
                }
                else {
                    // Print an error if you can't insert the card.
                }
            }
            // This card was used
            else {
                // Print an error?
            }
        }
        else {
            //error for non-usable code
            $response["success"] = 0;
            $response["message"] = "Code is not usable!";
            echo json_encode($response);
        }
    }
    // The redemption code does not exists
    else {
        //error for non existing code
        $response["success"] = 0;
        $response["message"] = "Code does not exist!";

        echo json_encode($response);
    }
} else {
    //error for blank field
    $response["success"] = 0;
    $response["message"] = "Please fill in the code field!";

    echo json_encode($response);
}

?>
于 2013-05-20T16:12:16.783 回答