[英]php - how to check if table or table row is empty?
我定义了以下函数来检查表行是否为空
function check_table($table) {
global $con;
$result = mysqli_query($con, "SELECT * FROM $table");
return (mysqli_num_rows($result) > 0) ? true : false;
}
然后调用它来填写表格
// check if payment table is empty, then insert into in, else update it
if(check_table('payment_details') == false) {
insert_into_table('payment_details',$payment_detail);
} else {
update_table($session_user_id,'payment_details',$payment_detail);
}
insert_into_table()
定义
function insert_into_table($table,$register_data) {
global $con;
array_walk($register_data, 'array_sanitize');
$fields = '`' . implode('`, `', array_keys($register_data)) . '`';
$data = '\'' . implode('\', \'', $register_data) . '\'';
mysqli_query($con , "INSERT INTO $table ($fields) VALUES ($data)");
}
但它没有返回所需的值,并且执行该表后该表仍然为空。 它不起作用。
所以我哪里错了?
任何帮助将不胜感激。
谢谢
新更新
这就是我的所有代码,只是确保我做对了吗? 如果没有,请给我一些改进的建议。
init.php
$session_user_id = $_SESSION['userid'];
//users table
$user_data = user_data($session_user_id,'users', 'id','username','password','first_name','last_name','email','allow_email',
'password_recover','active','city','state','country','phone','custom','date','plan','duration','domain','amount',
'pp_txn_id', 'pp_item_no','pp_payment_status','pp_payer_email','pp_payment_date','pz_reference_no', 'pz_item_no',
'pz_payment_status','pz_payer_email','pz_payment_date','expiry','status','cpanel');
// for paypal payments
$pp_data = user_data($session_user_id,'pp_details','pp_txn_id','pp_item_no','pp_payment_status','pp_payer_email','pp_payment_date');
// for payza payments
$pz_data = user_data($session_user_id,'pz_details','pz_reference_no','pz_item_no','pz_payment_status','pz_payer_email','pz_payment_date');
member.php
require_once(get_template_directory().'/member/core/init.php');
$customField = $user_data['custom'];
//check if transaction is done
if ( $customField == $user_data['id'] && ($user_data['pz_payment_status'] == 'Success') || ($user_data['pp_payment_status'] == 'Completed') ) {
//info for pp_details table
$pp_detail = array(
'id' => $user_data['id'],
'pp_txn_id' => $user_data['pp_txn_id'],
'pp_item_no' => $user_data['pp_item_no'],
'pp_payment_status' => $user_data['pp_payment_status'],
'pp_payer_email' => $user_data['pp_payer_email'],
'pp_payment_date' => $user_data['pp_payment_date'],
);
//info for pz_details table
$pz_detail = array(
'id' => $user_data['id'],
'pz_reference_no' => $user_data['pz_reference_no'],
'pz_item_no' => $user_data['pz_item_no'],
'pz_payment_status' => $user_data['pz_payment_status'],
'pz_payer_email' => $user_data['pz_payer_email'],
'pz_payment_date' => $user_data['pz_payment_date'],
);
//reset the users table if transaction is success
$update_data = array(
'status' => 'Active',
'pp_txn_id' => NULL,
'pp_item_no' => NULL,
'pp_payment_status' => NULL,
'pp_payer_email' => NULL,
'pp_payment_date' => NULL,
'pz_reference_no' => NULL,
'pz_item_no' => NULL,
'pz_payment_status' => NULL,
'pz_payer_email' => NULL,
'pz_payment_date' => NULL,
);
// check if payment table is empty, then insert into in
if(check_table($session_user_id,'pp_details') == false) {
if ($user_data['pp_payment_status'] == 'Completed') {
insert_into_table('pp_details',$pp_detail);
update_user($session_user_id, $update_data);
}
} elseif (check_table($session_user_id,'pz_details') == false) {
if ($user_data['pz_payment_status'] == 'Success') {
insert_into_table('pz_details',$pz_detail);
update_user($session_user_id, $update_data);
}
}
// make sure if user_data transaction id's not match with payment_data details, then activate the package
if ( ($user_data['pp_txn_id']) != ($pp_data['pp_txn_id']) ) {
// update the pp_details table
update_table($session_user_id,'pp_details',$pp_detail);
// reset the users table and activate package
update_user($session_user_id, $update_data);
} elseif ( ($user_data['pz_reference_no']) != ($pz_data['pz_reference_no']) ) {
// update the pz_details table
update_table($session_user_id,'pz_details',$pz_detail);
// reset the users table and activate package
update_user($session_user_id, $update_data);
}
// email credentials
if ( $user_data['pp_payment_status'] == 'Completed' ) {
$transactionID = $pp_data['pp_txn_id'];
$itemNo = $pp_data['pp_item_no'];
$paymentStatus = $pp_data['pp_payment_status'];
$paymentDate = $pp_data['pp_payment_date'];
if ($pp_data['pp_payer_email'] !== $user_data['email']) {
$customer_Email = array($pp_data['pp_payer_email'],$user_data['email']);
} else {
$customer_Email = array($user_data['email']);
}
} elseif ( $user_data['pz_payment_status'] == 'Success' ) {
$transactionID = $pz_data['pz_reference_no'];
$itemNo = $pz_data['pz_item_no'];
$paymentStatus = $pz_data['pz_payment_status'];
$paymentDate = $pz_data['pz_payment_date'];
if ($pz_data['pz_payer_email'] !== $user_data['email']) {
$customer_Email = array($pz_data['pz_payer_email'],$user_data['email']);
} else {
$customer_Email = array($user_data['email']);
}
}
$message = "Thank You <b>".$user_data['first_name']."</b> for using our service.<br> Your Transaction details are below:<br><br>
Transaction ID/Reference: $transactionID<br>
Item No: $itemNo <br>
Payment Status: $paymentStatus <br>
Payment Date: $paymentDate <br><br>
Kind Regards <br>
- HostPLUS1 © ".date('Y')."
";
if ( isset($_GET['success']) && empty($_GET['success']) ) {
//if sucess then refresh the page to remove the $_GET val
refresh('3',$_SERVER['SCRIPT_URI']);
if ($user_data['status'] == 'Active') {
email($customer_Email,'Thank you, your payment has been completed',$message);
}
}
};
我已经在名为user_functions.php
的单独文件中定义了所有函数
HSN,您在哪里指定检查表格的条件? 您说的是"SELECT * FROM $table"
,但没有指定条件(或Yegor指出的限制)。 这意味着,即使您的payment_details
表中只有一 (1)个交易,也不会处理任何新交易。 您应该使用条件过滤结果。
我相信您是为PayPal IPN编写的,因此我将这样格式化我的答案。 在所有重写下面,您将看到有关为什么我建议我做什么的信息。
这是我建议重写它的方式:
/* Escape the variables right away */
// global $con; // uncomment this if you need to. I don't know where in your code it's defined
$clean_ppTxnId = ""; // we'll use this in check table.
foreach($payment_detail as $key => $value){
$escapedKey = $con->escape_string($key);
$escapedValue = $con->escape_string($value);
if($key == 'pp_txn_id'){ $clean_ppTxnId = $escapedValue; }
unset($payment_detail[$key]);
$payment_detail[$escapedKey] = $escapedValue;
}
// the payment details have now been looped, sanitized and replaced.
// check if payment table is empty, then insert into in, else update it
if(check_table('payment_details') == false) {
/* new payment that we've never seen before */
insert_into_table('payment_details',$payment_detail);
} else {
/* if we go into the else statement, this exact payment has already
* been processed once. */
/* update_table($session_user_id,'payment_details',$payment_detail); */
/*******
* The line above is going to force you to either double process or
* you'll overwrite PayPal transaction records.
* Instead, this should be regarded as PayPal sending the transaction
* to your IPN a second time (which does happen).
******/
}
/* If you're done with all database transactions at this point, you should call $con->close(); */
现在使用check_table
函数
function check_table($table, $clean_ppTxnId) {
global $con;
$result = $con->("SELECT * FROM `$table` WHERE (`pp_txn_id` = '$clean_ppTxnId') LIMIT 1");
// I've added a where conditional to filter results and a LIMIT statement as Yegor suggested.
$returnVal = ($result->num_rows > 0) ? true : false;
$result->close();
return returnVal;
}
最后是insert_into
函数:
function insert_into_table($table,$register_data) {
global $con;
/* removed array_walk because my solution filters the data in before
* calls this function.
*/
$fields = '`' . implode('`, `', array_keys($register_data)) . '`';
$data = '\'' . implode('\', \'', $register_data) . '\'';
$result = $con->query("INSERT INTO `$table` ($fields) VALUES ($data);");
// you can check the result for something if you want, but you shouldn't need to.
$result->close();
}
编辑摘要:
real_escape_string
(也称为escape_string
)函数。 此函数使用MySQL数据库的设置来清理/转义输入。 也许您的array_sanitize()
函数已经在执行此操作,但是我决定添加它,因为您没有发布该函数。 由于并非您的所有代码都已发布,因此您必须决定是否应将这些编辑中的任何一个添加到您的代码中。 但是,如果这是针对我认为的PayPal IPN,那么这些编辑可能会很有用。 无论如何,您都必须做出决定。
更新:好的,更新之后,我对您的代码及其逻辑有一些疑问。
这是您的代码:
// make sure if user_data transaction id's not match with payment_data details, then activate the package
if (!empty($payment_data['pp_txn_id']) === !empty($user_data['pp_txn_id']) || !empty($payment_data['pz_reference_no']) === !empty($user_data['pz_reference_no'])) {
$update_data = array(
'status' => 'Active',
);
update_user($session_user_id, $update_data);
}
注释说,请make sure if user_data transaction id's not match with payment_data details, then activate the package
,但是if语句不执行此操作。 实际上,此if语句可能会执行您不希望执行的操作。
第一部分说if(!empty($array['index']) === !empty($another_array['index']))
让我们来分解一下。
empty()
返回一个布尔值,该布尔值指示变量是否不包含内容(如果字符串为''
或""
则在字符串上调用empty
为true)。 因此,让$array['index'] = "foo";
,则empty($array['index'])
变为empty("foo")
。 而且我们知道它将返回false,因为该字符串不为空。 !empty(...)
。 因此,以扩展形式, $boolean_returned_by_not_empty = (empty(...) ? false : true);
。 您将布尔值切换为相反的值。 这很好并且可以理解。 !empty(...) === !empty($another_array['index'])
。 这是第一部分的逻辑失败的地方。 您在评论中说,您想比较它们是否匹配,但是您要比较的是它们是否均为空或都包含内容。 这意味着如果您分配$payment_details['pp_txn_id'] = "foo";
和$user_data['pp_txn_id'] = "bar";
if语句将运行,因为尽管它们不匹配,但没有一个为空。 同样,如果它们确实匹配( $payment_details['pp_txn_id'] = "foobar";
和$user_data['pp_txn_id'] = "foobar";
),则您的代码将运行if语句来更新表。
在if语句的第二部分中,您正在做同样的事情,然后只说if either pair contains two strings with some data (this data doesn't even have to match), then go ahead and update the table.
我认为,当您想知道它们是否不匹配时,这没有逻辑意义。 我相信对此更好的检查是:
if( ($payment_details['pp_txn_id'] !== $user_data['pp_txn_id']) ||
($payment_data['pz_reference_no'] !== !$user_data['pz_reference_no']) ){
$update_data = array(
'status' => 'Active',
);
update_user($session_user_id, $update_data);
}
另外,在看到您添加的代码后,我现在建议您执行array_walk($payment_detail, 'array_sanitize');
我把foreach循环放在哪里。 然后只需在array_walk
之后分配$clean_ppTxnId
。 现在,我可以看到您的array_sanitize
是安全的。
综上所述,由于该脚本缺少细节和内容,因此仍然存在一些问题。 基本思想应该是:
settle_amount
;恶意购买者有可能更改HTML amount
属性),并检查所有其他必要变量是否符合预期条件。 如果不是,则说明结帐已被篡改,不应进行处理。 INSERT INTO <Table name for the user table goes here> (<column name 1>, <column name 2>, ...) VALUES (<value 1>, <value 2>, ...);
添加一行INSERT INTO <Table name for the user table goes here> (<column name 1>, <column name 2>, ...) VALUES (<value 1>, <value 2>, ...);
。 如果您刚刚注册了执行此操作的用户,请转到步骤9。 status
设置为Active
。 否则,将错误记录在数据库的警告表中,以便以后可以查看它,以查看是否需要退款或更正代码。 payer_email
发送一封电子邮件(我不会详细介绍,但是您可以使用PHP的mail()
函数),以通知用户交易已被处理。 好吧,我发现了我的错误并解决了
我的数组'pz_payment_data' => $user_data['pz_payment_data'],
有拼写错误'pz_payment_data' => $user_data['pz_payment_data'],
$payment_detail = array(
'id' => $user_data['id'],
'pp_txn_id' => $user_data['pp_txn_id'],
'pp_payment_date' => $user_data['pp_payment_date'],
'pz_reference_no' => $user_data['pz_reference_no'],
'pz_payment_date' => $user_data['pz_payment_date'],
);
我修复了它,现在可以工作了:)
您的功能不好:
function check_table($table) {
global $con;
$result = mysqli_query($con, "SELECT * FROM $table");
return (mysqli_num_rows($result) > 0) ? true : false;
}
因为它只选择所有行以获取布尔结果,所以我认为您可以改进它:
function check_table($table) {
global $con;
$result = mysqli_query($con, "SELECT * FROM $table LIMIT 1");
return (mysqli_num_rows($result) > 0) ? true : false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.