2013-07-30 14 views
0

。一切都在發佈,但用戶名。任何提示如何調試這將非常感激。如何調試變量我試圖找出如何調試問題具有可變的張貼到我的數據庫不張貼到MYSQL數據庫

的用戶名並通過一對夫婦的功能,首先運行。我沒有得到腳本本身的任何錯誤,但我也沒有得到任何東西發佈到數據庫。

<?php 

// Check to see there are posted variables coming into the script 
if ($_SERVER['REQUEST_METHOD'] != "POST") die ("No Post Variables"); 
// Initialize the $req variable and add CMD key value pair 
$req = 'cmd=_notify-validate'; 
// Read the post from PayPal 
foreach ($_POST as $key => $value) { 
    $value = urlencode(stripslashes($value)); 
    $req .= "&$key=$value"; 
} 
// Now Post all of that back to PayPal's server using curl, and validate everything with PayPal 
// We will use CURL instead of PHP for this for a more universally operable script (fsockopen has issues on some environments) 
//$url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; 
$url = "https://www.paypal.com/cgi-bin/webscr"; 
$curl_result=$curl_err=''; 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL,$url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded", "Content-Length: " . strlen($req))); 
curl_setopt($ch, CURLOPT_HEADER , 0); 
curl_setopt($ch, CURLOPT_VERBOSE, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
$curl_result = @curl_exec($ch); 
$curl_err = curl_error($ch); 
curl_close($ch); 

$req = str_replace("&", "\n", $req); // Make it a nice list in case we want to email it to ourselves for reporting 

// Check that the result verifies 
if (strpos($curl_result, "VERIFIED") !== false) { 
    $req .= "\n\nPaypal Verified OK"; 
} else { 
    $req .= "\n\nData NOT verified from Paypal!"; 
    mail(".com", "IPN interaction not verified", "$req", "From: .com"); 
    exit(); 
} 

/* CHECK THESE 4 THINGS BEFORE PROCESSING THE TRANSACTION, HANDLE THEM AS YOU WISH 
1. Make sure that business email returned is your business email 
2. Make sure that the transaction’s payment status is 「completed」 
3. Make sure there are no duplicate txn_id 
4. Make sure the payment amount matches what you charge for items. (Defeat Price-Jacking) */ 

// Check Number 1 ------------------------------------------------------------------------------------------------------------ 
$receiver_email = $_POST['receiver_email']; 
if ($receiver_email != ".com") { 
    $message = "Investigate why and how receiver email is wrong. Email = " . $_POST['receiver_email'] . "\n\n\n$req"; 
    mail(".com", "Receiver Email is incorrect", $message, "From: .com"); 
    exit(); // exit script 
} 
// Check number 2 ------------------------------------------------------------------------------------------------------------ 
if ($_POST['payment_status'] != "Completed") { 
    // Handle how you think you should if a payment is not complete yet, a few scenarios can cause a transaction to be incomplete 
} 
// Connect to database ------------------------------------------------------------------------------------------------------ 
require_once 'connect_to_mysql.php'; 
// Check number 3 ------------------------------------------------------------------------------------------------------------ 
$this_txn = $_POST['txn_id']; 
$sql = mysql_query("SELECT id FROM transactions WHERE txn_id='$this_txn' LIMIT 1"); 
$numRows = mysql_num_rows($sql); 
if ($numRows > 0) { 
    $message = "Duplicate transaction ID occured so we killed the IPN script. \n\n\n$req"; 
    mail(".com", "Duplicate txn_id in the IPN system", $message, "From: .com"); 
    exit(); // exit script 
} 
// Check number 4 ------------------------------------------------------------------------------------------------------------ 
$product_id_string = $_POST['custom']; 
$product_id_string = rtrim($product_id_string, ","); // remove last comma 
// Explode the string, make it an array, then query all the prices out, add them up, and make sure they match the payment_gross amount 
$id_str_array = explode(",", $product_id_string); // Uses Comma(,) as delimiter(break point) 
$fullAmount = 0; 
foreach ($id_str_array as $key => $value) { 

    $id_quantity_pair = explode("-", $value); // Uses Hyphen(-) as delimiter to separate product ID from its quantity 
    $product_id = $id_quantity_pair[0]; // Get the product ID 
    $product_quantity = $id_quantity_pair[1]; // Get the quantity 
    $sql = mysql_query("SELECT price FROM products WHERE id='$product_id' LIMIT 1"); 
    while($row = mysql_fetch_array($sql)){ 
     $product_price = $row["price"]; 
    } 
    $product_price = $product_price * $product_quantity; 
    $fullAmount = $fullAmount + $product_price; 
} 
$fullAmount = number_format($fullAmount, 2); 
$grossAmount = $_POST['mc_gross']; 
if ($fullAmount != $grossAmount) { 
     $message = "Possible Price Jack: " . $_POST['payment_gross'] . " != $fullAmount \n\n\n$req"; 
     mail(".com", "Price Jack or Bad Programming", $message, "From: .com"); 
     exit(); // exit script 
} 

// 
// 
require_once 'connect_to_mysql.php'; 

//now to always get unique username 
$username = substr($payer_email, 0, strpos($payer_email, '@')); 
if (! uniqueName($username)) 
{ 
    $username = makeUniqueName($username); 
} 


//function to check if is the existing username 
function uniqueName($username) 
{ 
    $sql = mysql_query("SELECT username FROM transactions WHERE username='$username'"); 
    $numRows = mysql_num_rows($sql); 
    if ($numRows > 0) 
    { 
     return false; 
    } 

    return true; 
} 


//function to generate new unique username 
function makeUniqueName($username) 
{ 
    //serch username string for number at the end 
    //regexp makes sure all preceeding zeroes go to first match group 
    if (preg_match('/^(\S*?0*)?(\d+?)$/', $username, $match)) 
    { 
     //we got digit from the end of string, just add 1 to the digit 
     $username = $match[1] . ($match[2] + 1); 
    } 
    else 
    { 
     //no digit at the end of string, just add digit 1 at the end 
     $username = $username . 1; 
    } 

if (uniqueName($username)) 
{ 
    return $username; 
} 

    return makeUniqueName($username); 
} 

// END ALL SECURITY CHECKS NOW IN THE DATABASE IT GOES ------------------------------------ 
//////////////////////////////////////////////////// 
// Homework - Examples of assigning local variables from the POST variables 
$txn_id = $_POST['txn_id']; 
$payer_email = $_POST['payer_email']; 
$custom = $_POST['custom']; 
$first_name = $_POST['first_name']; 
$last_name = $_POST['last_name']; 
$payment_date = $_POST['payment_date']; 
$mc_gross = $_POST['mc_gross']; 
$payment_currency = $_POST['payment_currency']; 
$txn_id = $_POST['txn_id']; 
$receiver_email = $_POST['receiver_email']; 
$payment_type = $_POST['payment_type']; 
$payment_status = $_POST['payment_status']; 
$txn_type = $_POST['txn_type']; 
$payer_status = $_POST['payer_status']; 
$address_street = $_POST['address_street']; 
$address_city = $_POST['address_city']; 
$address_state = $_POST['address_state']; 
$address_zip = $_POST['address_zip']; 
$address_country = $_POST['address_country']; 
$address_status = $_POST['address_status']; 
$notify_version = $_POST['notify_version']; 
$verify_sign = $_POST['verify_sign']; 
$payer_id = $_POST['payer_id']; 
$mc_currency = $_POST['mc_currency']; 
$mc_fee = $_POST['mc_fee']; 
$password = mt_rand(1000, 9999); 
$p_hash = md5($password); 
$username = $_POST['username']; 
// 

// Place the transaction into the database 
$sql = mysql_query("INSERT INTO transactions (product_id_array, payer_email, first_name, last_name, payment_date, mc_gross, payment_currency, txn_id, receiver_email, payment_type, payment_status, txn_type, payer_status, address_street, address_city, address_state, address_zip, address_country, address_status, notify_version, verify_sign, payer_id, mc_currency, mc_fee, password, ip, username) 
    VALUES('$custom','$payer_email','$first_name','$last_name','$payment_date','$mc_gross','$payment_currency','$txn_id','$receiver_email','$payment_type','$payment_status','$txn_type','$payer_status','$address_street','$address_city','$address_state','$address_zip','$address_country','$address_status','$notify_version','$verify_sign','$payer_id','$mc_currency','$mc_fee','$p_hash','$ip','$username')") or die ("unable to execute the query"); 
$to  = $payer_email; 
$subject = 'Learn | Login Credentials'; 
$message = ' 

Your officially all ready to go. To login use the information below. 

Your account login information 
------------------------- 
Email: '.$payer_email.' 
Password: '.$password.' 
------------------------- 

You can now login at https://www..com/signin.php'; 
$headers = 'From:[email protected]' . "\r\n"; 

mail($to, $subject, $message, $headers); 
mysql_close(); 
// Mail yourself the details 
mail(".com", "NORMAL IPN RESULT YAY MONEY!", $req, "From: "); 

?> 
+3

我們稱之爲小型鮑比表...從來沒有直接將後置值插入到sql語句中。請閱讀SQL注入請! – Gryphius

+0

@Gryphius 我打算做這樣的事情。一個小題目,但這是否是正確的方法? $用戶名= preg_replace函數( '#[^ A-Z]#', '',$ _POST [ '用戶名']); – Chris

+0

http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php – Gryphius

回答

0

調試包括:

  1. 確定變量的腳本執行過程中的價值應該是什麼。
  2. 確定腳本執行期間變量的值實際上是什麼。
  3. 確定兩者之間不匹配的原因。

然後可以使用此信息更改代碼,以便變量的實際值和預期值相匹配。

項目1,的代碼應該怎麼它應該做的是什麼,有必要的瞭解。在這一點上,代碼本身沒有什麼幫助,因爲代碼無法讀取程序員的頭腦,並不知道它的期望。

就第2項,您可以將print語句中的代碼(和調試後刪除)。更好的方法是使用像XDebug這樣的調試器,最好與Eclipse PDT這樣的IDE結合使用。

作爲一個例子,假設我後

$sql = mysql_query("INSERT INTO transactions (product_id_array, payer_email, first_name, last_name, payment_date, mc_gross, payment_currency, txn_id, receiver_email, payment_type, payment_status, txn_type, payer_status, address_street, address_city, address_state, address_zip, address_country, address_status, notify_version, verify_sign, payer_id, mc_currency, mc_fee, password, ip, username) 

$sql變量的值應該是true。 A print($sql)將證實或駁斥這一假設。如果是false,則撥打mysql_error()將會說明查詢失敗的原因。如果它是true並且沒有插入預期用戶名的記錄,則$username的值可能與您的預期不符。

+0

嗨@Oswald感謝您的迴應。我以同樣的方式看待它,但不太明白如何調試。 – Chris

+0

我詳細闡述了一下。我希望這有幫助。 – Oswald

0

只是一個猜測: 你$ username變量似乎基於電子郵件第一,通過各種功能的運行產生。

$username = $_POST['username']; 

你確定這個領域應該貼:

//now to always get unique username 
$username = substr($payer_email, 0, strpos($payer_email, '@')); 
if (! uniqueName($username)) 
{ 
    $username = makeUniqueName($username); 
} 
[...] 

,但最後你覆蓋它嗎?也許你只需要刪除這條線?

+0

我不太確定。我試過makeUniqueName和uniqueName,但我只是得到1 2等。不是包含從payer_email創建的用戶名的第一部分 – Chris

+0

我不確定。我已經嘗試了uniqueName和makeUniqueName,但我只是得到值1或2等。它不再包含用戶名。之前的用戶名是payer_email減去@符號後的所有內容。 – Chris