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);
}
?>

私の状況では、システムが「カード」に新しいレコードを作成し、それに応じて「償還」テーブルを更新する必要があります..

ただし、新しいカードを作成することしかできませんでしたが、「償還」テーブルを更新することはできません...誰か助けてくれますか? これを調べるために必要なことを教えてください...ありがとう!

私が試してみました

$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

関数は非推奨であるため、関数の代わりにPDOの使用を開始する必要があります。mysql_*また、クエリにはもっと注意する必要があります。同じテーブルからほとんど同じ情報を数回選択しているのに、異なる列でのみリクエストしていることがわかりました。たとえば、これらのクエリ$exist$usable1 つのクエリにマージして、簡単なif/elseステートメントでクエリの結果を確認できます。これにより、一部のシステム リソースが節約され、アプリケーションの読み込みが少し速くなります。

また、エイリアス名自体がテーブル名と同じであるのに、なぜSQLクエリ内でテーブルエイリアスを使用しているのかわかりませんか? エイリアスは、テーブルの名前を短くしたい場合 (つまりmy_table_namemtnより簡単かつ迅速に記述できるようにしたい場合)、または名前が同じで意味と使用法が異なる列を持ついくつかのテーブルを結合する場合を対象としています。

@Neville Kが指摘したように、あなたが書いたコードに関しては、何が問題なのかを突き止めるのは非常に難しいでしょう。あなたが書いた方法では、デバッグは簡単ではありません。を使用してコードを再編成するのに時間がかかりましたPDO。コードはおそらくすぐには機能しません - 私はそれをテストしておらず、あなたのデータベースの構造を持っていません. 機能させるには、いくつかの作業が必要になる場合があります。、などの変数名を使用しないようにアドバイスしたいと思います。意味があり、保持するデータを明確にする名前を変数に付けてみてください。datadata1data2

コードは次のとおりです。

<?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 に答える
0

コードをデバッグせずに (ステップ実行して) 何が起こっているのか理解できませんが、コードが構造化されているため、ロジックをたどるのは非常に困難です。単一の SQL クエリが期待どおりに動作しないと、これが黙って失敗する可能性があります。また、ネストされた条件文が多数あるため、何が起こっているのかについていくのが難しくなります。

更新をより効率的に記述できるように感じます。他のクエリからデータを PHP 変数に取得し、それらを更新に渡します。代わりに update ステートメントでそのデータに結合することで、おそらくそれを行うことができます。

第二に、「早割り」を考えてください。例えば:

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 に答える