2013-07-30 15 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