【发布时间】:2019-06-10 09:01:52
【问题描述】:
我创建了一个名为 wp_tickets 的表,其中包含从我的 wordpress 帖子中设置的自定义字段生成的一系列票号。表中的列是'id', 'ticket_id', 'lottery_id' 和'used'。
当客户在我的网站上购买产品时,我试图生成一个随机的唯一编号。
例如,如果客户订购了五件相同的产品。它需要根据产品元字段中设置的字段'maximum_entries' 生成5 个随机唯一数字,然后在wp_tickets 表中将这些数字标记为“已使用”。
我需要这是一个原子操作,这样如果客户同时订购,他们就不能拥有相同的号码。
到目前为止,我已经创建了一个要在 woocommerce_order_status_processing 钩子上调用的函数,它遍历购物车中的每个产品并获取产品数量。然后在调用 array_rand 之前,我使用 range 函数将其转换为数字数组。
然后我在$wpdb 更新函数中使用$ticketallocated。
我遇到的问题是,如果正在生成的号码已经在表格中标记为“已使用”,那么它不会循环回到顶部并重试。我需要以某种方式设置一个 if/else 语句,因此如果生成的随机数是 5,并且数据库中已经有一个 5 为“已使用”,那么它将尝试不同的数字。
add_action('acf/save_post', 'my_acf_save_post', 20);
function my_acf_save_post( $post_id ) {
global $wpdb;
$qty = get_field('maximum_entries');
$array = range(1, $qty);
foreach ($array as $ticket) {
$wpdb->insert('wp_tickets', array(
'ticket_number' => $ticket,
'lottery_id' => $post_id,
));
}
}
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
"
);
}
}
【问题讨论】:
-
虽然可以使用数据库执行此操作,但我建议您使用适当的 fifio 队列,例如
beanstalkd,并使用唯一的随机票号预先填充它。 -
嗨@Geoffrey 我想我现在已经设法让它在数据库中工作。与 fifio 队列相比,使用数据库的缺点是什么?
-
@Geoffrey 你认为使用数据库可能会导致问题吗?
-
如果你有一个真正的原子操作应该没问题,只是它的性能不如专用的先进先出队列。此外,由于您有一个可行的解决方案,请发布您对此问题的答案并接受它。
-
嗨@Geoffrey,我提供了对我有用的解决方案。如果您能看一下,看看我所做的是否是“真正的原子操作”,那就太好了。我怀疑这不是我在调用多个函数?
标签: php sql arrays wordpress foreach