php - 生成一个唯一的随机数并根据用户订单存储它 - 同时处理请求?
问题描述
当客户在 Woocommerce 中完成订单并将其保存在数组中时,我使用下面的函数生成一个唯一的随机数,以便其他客户无法生成它。我在 woocommerce_order_processing 钩子上调用该函数。
我只是想知道这个解决方案有多防弹,以及它如何处理多个客户同时订购?它们是否有可能最终得到相同的数字,或者数据库是否能够足够快地返回正在使用的数字数组?
function add_lottery_ticket_number( $postId ) {
if (metadata_exists('post', $postId, 'optionsToGive')) {
$ticketOptions = get_post_meta( $postId, 'optionsToGive', true );
} else {
$lottery_max_tickets = get_post_meta( $postid, '_max_tickets', true );
$ticketOptions = range(1, $lottery_max_tickets);
shuffle($ticketOptions ); //random order of all number
}
$ticketAllocated = array_shift($ticketOptions); //take the first element
update_post_meta( $postId, 'optionsToGive', $ticketOptions ); //update all the rest
return $ticketAllocated;
}
for ( $i = 0; $i < $item_meta['_qty'][0]; $i++ ) {
add_post_meta( $product_id, '_participant_id', $order->get_user_id() );
$participants = get_post_meta( $product_id, '_lottery_participants_count', true ) ? get_post_meta( $product_id, '_lottery_participants_count', true ) : 0;
update_post_meta( $product_id, '_lottery_participants_count', intval( $participants ) + 1 );
$this->add_lottery_to_user_metafield( $product_id, $order->get_user_id() );
$ticketnumber = $this->add_lottery_ticket_number($product_id);
$log_ids[] = $this->log_participant( $product_id, $order->get_user_id(), $ticketnumber, $order_id, $item );
}
更新
我已经为所有要存储的票号创建了一个表格,其中包含您建议的“已使用”列。然后我在 foreach 语句中使用 $wpdb->query 函数并更新表。
但是,我不确定如何生成要在 WHERE ticket_number = $randomnumber' 中使用的随机数,并且它是唯一的,因此订购 5 张门票的一位客户将有 5 个不同的号码。那有意义吗?
add_action( 'woocommerce_order_status_processing', 'ektgn_meta_to_line_item', 20, 4 );
function ektgn_meta_to_line_item( $order_id )
{
$order = wc_get_order($order_id);
foreach( $order->get_items() as $item_id => $item_product ) {
global $wpdb;
$product_id = $item_product->get_product_id();
$qty = get_field('maximum_entries', $product_id, true);
$ticketOptions = range(1, $qty);
$ticketAllocated = array_rand($ticketOptions, 1);
$wpdb->query(
"
UPDATE wp_tickets
SET used = 1
WHERE ticket_number= ".$ticketAllocated." AND lottery_id = ".$product_id." AND used = 0
"
);
}
}
解决方案
如果您每天只有几份订单,这很公平,但亚马逊肯定会以这种方式获得多张重复票。您正在寻找的是原子操作。
可能的方式:
为票号创建一个具有唯一列的 mysql 表。因为你不能两次插入一个数字...做 { INSERT INTO Tickets ($random_number) } while duplicate key error
创建一个包含所有票证和“已使用”标志列的 mysql 表... do { UPDATE Tickets SET used=1 WHERE ticket_number=$random_number and used=0; } 而受影响的行 == 0;
使用 redis 集... do { SADD Tickets $random_number } while result == 0
推荐阅读
- r - 计算 R 中特定日期范围的平均值
- ignite - 使用公共和私有 ip 连接到 Ignite 服务器
- azure - azure 事件网格 - 使用 azure 存储队列作为 endpointType 创建订阅
- php - 如何将默认表格内容显示为不同的,当单击按钮时,UI 中的同一个表格中的表格内容应该不同?
- wordpress - WPBakery Grid builder 获取帖子内容
- mongodb - MongoDB $从带有过滤器的数组中提取
- javascript - 带有ajax的表单-没有刷新页面的消息表单php
- r - R中的HSD Tukey测试错误
- javascript - 尽管已绑定,但在 onClick 处未定义 React 函数?
- html - 如何在图像上创建响应式 div?