Php 基于变量MYSQL IPN的substr问题

Php 基于变量MYSQL IPN的substr问题,php,mysql,paypal-ipn,Php,Mysql,Paypal Ipn,您好,我很难理解为什么我的表中的用户名列没有添加内容。我正在尝试使用我的IPN中的付款人电子邮件来引入一个用于登录的用户名。除用户名外,所有内容都已发布。用户名变量编辑的位置是否有问题?是否有我遗漏的东西阻止了这篇文章的发布 <?php // Check to see there are posted variables coming into the script if ($_SERVER['REQUEST_METHOD'] != "POST") die ("No Post Varia

您好,我很难理解为什么我的表中的用户名列没有添加内容。我正在尝试使用我的IPN中的付款人电子邮件来引入一个用于登录的用户名。除用户名外,所有内容都已发布。用户名变量编辑的位置是否有问题?是否有我遗漏的东西阻止了这篇文章的发布

<?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("chris@test.com", "IPN interaction not verified", "$req", "From: chris@test.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 != "chris@test.com") {
    $message = "Investigate why and how receiver email is wrong. Email = " . $_POST['receiver_email'] . "\n\n\n$req";
    mail("chris@test.com", "Receiver Email is incorrect", $message, "From: chris@test.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("chris@test.com", "Duplicate txn_id in the IPN system", $message, "From: chris@test.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("chris@test.com", "Price Jack or Bad Programming", $message, "From: chris@test.com" );
        exit(); // exit script
} 
require_once '../includes/db_conx.php';
//
$payer_email = $_POST['payer_email'];
// Select the member from the users table
$username = substr($payer_email, 0, strpos($payer_email, '@'));
$sql = "SELECT username FROM transactions WHERE username='{$username}%'";
$user_query = mysqli_query($db_conx, $sql);

$numrows = mysqli_num_rows($user_query);
if($numrows < 1){

   $i = 0;

   while ($name_arr = mysqli_fetch_assoc($result)) {

      $name = $name_arr['username'];       

      $after = substr($name, strlen($username));

      if (ctype_digit($after)) {

         if (($after = (int) $after) > $i) {

            $i = $after;

         }

      }

   }

   if ($i > 0) {
      $username .= $i;
   }

}


// 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 = ' 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.test.com/signin.php';  
$headers = 'From:noreply@test.com' . "\r\n";  

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

?>

我并没有过多地讨论这个问题,但最让我感到怀疑的是:

$sql = "SELECT `username` FROM `transactions` WHERE `username` = \'' . $username . '%\';";
它应该看起来更像

$sql = "SELECT `username` FROM `transactions` WHERE `username` = '{$username}%'";
供参考: -PHP可以处理双引号中的单引号,而不需要反斜杠()转义。 -MySQL报价不需要分号(;)转义 -检查问题是否确实是用于将来调试的MySQL查询的一个好方法是在查询函数的末尾添加或删除(MySQL_error($db)),如下所示:

$result = mysqli_query($db_conx, $sql) or die(mysql_error($db_conx));
希望这有帮助

更新:
我已经将其添加到结果区域以尝试和调试,但我没有从中收到任何信息。这会出现在您的标准错误页面中吗

试一试

在进一步查看您的代码之后,您似乎不应该看到
username
='{$username}'的任何内容,因为$username是基于$payer_电子邮件的,该电子邮件尚未声明。您需要将这些用户名检查放入一个函数中,并在为变量分配了$\u POST索引后调用它,或者在首次声明$username变量之前将$\u POST[“payer\u email”]移动到$\u POST[“username”]。。。虽然我还没有看到您的表单,但听起来您是通过付款人电子邮件创建用户名的。这有帮助吗

更新2: mysql_fetch_assoc的错误是因为您尚未声明$result。我相信您可能试图引用$user_查询,在这种情况下,您的第108行应该是:

while ($name_arr = mysqli_fetch_assoc($user_query)) {  
更新3: 首先,我注意到您使用的是username='{$username}%'。我有几点要说,我希望你们能听听。我在这里给你鱼,但我也想教你

  • 如果你想做一个比较,它必须是像“{$username}%”这样的用户名
  • 我不清楚你想做什么。。。如果您想要一个唯一的标识符,我实际上会做一些更像username='{$username}'的事情,然后,如果它返回一个结果,则在末尾添加一个唯一的标识符
你看,当你用{$username}这样的东西做的时候,如果有人想注册成为awesome_bob,你会得到两行,而其他人已经有了awesome_bobby。我想你会想要一些更随机的东西,或者创建一个更复杂的函数。或者,只需将用户名保留为电子邮件,这样可以保持用户名的唯一性,这是一个非常简单的修复方法

我将就此离开这篇文章,因为我认为它已经回答了你最初的问题,然后是一些问题。如果你有更多的问题,我想人们会很乐意在一个单独的话题中讨论


我回答你的问题够了吗?如果是这样的话,我会感谢我的努力:)

我不会称之为安全。。。不管怎样,错误是什么,或者paypal只是抛出错误?我还没有完全完成安全性。谢谢你的提醒。没有错误。它只是没有输入到数据库编辑:只是重新加载以查找上面发布的错误。看起来您混合了MySQL(已弃用)和MySQLi扩展。不要那样做Hi Phil我实际上正在一步一步地转换成MYSQLI。哈哈,我还不是很擅长,所以需要一些时间来解决它。你认为这可能是它没有发布到数据库的原因吗?除此之外,所有其他条目都已过帐。这似乎不是用户名post的具体问题,但我不知道。我不再收到任何错误,但仍然没有将其作为更新发布到数据库。我已将其添加到结果区域以尝试和调试,但我没有收到任何来自它的信息。这会出现在你的标准错误页面吗?我也更新了我的回复。我得到了,我终于能够发布到我的数据库,但我无法计数并添加到用户名以防止重复。请查看我的编辑。我想这应该让你更清楚。我建议使用电子邮件作为您的用户名,或者,如果您希望它是单独的,可以使用str_replace(“at”、“@”、$string);或预更换。请注意使用增量解决方案的挑战。如果你想这样做,它将需要一个复杂得多的函数,并且考虑到它明显偏离了你最初的问题,我建议你创建一个新的主题,这样主持人就不会停止对话。谢谢你的帮助。我很乐意去碰碰。你能在这里聊天吗?如果你愿意帮忙,我还有一个问题。
while ($name_arr = mysqli_fetch_assoc($user_query)) {  
I got that and I've been able to post to my database finally, but I can't get it to count and add to the username to prevent duplicates.