Php 生成一个唯一的随机数,同时根据用户订单处理请求存储它?

Php 生成一个唯一的随机数,同时根据用户订单处理请求存储它?,php,sql,wordpress,woocommerce,Php,Sql,Wordpress,Woocommerce,当客户在Woocommerce中完成订单时,我使用下面的函数生成一个唯一的随机数,并将其保存在一个数组中,以便其他客户无法生成该随机数。我正在调用woocommerce\u order\u处理钩子上的函数 我只是想知道这个解决方案是如何防弹的,它将如何处理多个客户同时订购?它们是否可能以相同的数字结束,或者数据库是否能够以足够快的速度返回正在使用的数字数组 function add_lottery_ticket_number( $postId ) { if (metadata_exist

当客户在Woocommerce中完成订单时,我使用下面的函数生成一个唯一的随机数,并将其保存在一个数组中,以便其他客户无法生成该随机数。我正在调用woocommerce\u order\u处理钩子上的函数

我只是想知道这个解决方案是如何防弹的,它将如何处理多个客户同时订购?它们是否可能以相同的数字结束,或者数据库是否能够以足够快的速度返回正在使用的数字数组

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 );
}

如果你每天只有几张订单就够了,但亚马逊肯定会以这种方式得到多张重复的机票。你要找的是原子操作

可能的方式:

  • 创建一个mysql表,其中包含唯一的票证号列。因为你不能插入一个数字两次。。。重复键错误时执行{INSERT INTO tickets($random_number)}

  • 创建一个包含所有票据和“已使用”标志列的mysql表。。。do{UPDATE tickets SET used=1,其中ticket_number=$random_number and used=0;}而受影响的_行==0

  • 使用redis集。。。当结果==0时执行{SADD tickets$random_number}


如果你每天只有几张订单,那就足够了,但亚马逊肯定会以这种方式得到多张重复的机票。你要找的是原子操作

可能的方式:

  • 创建一个mysql表,其中包含唯一的票证号列。因为你不能插入一个数字两次。。。重复键错误时执行{INSERT INTO tickets($random_number)}

  • 创建一个包含所有票据和“已使用”标志列的mysql表。。。do{UPDATE tickets SET used=1,其中ticket_number=$random_number and used=0;}而受影响的_行==0

  • 使用redis集。。。当结果==0时执行{SADD tickets$random_number}


你不能只使用一个自动递增的数据库id吗?它需要是从元字段max\u tickets中设置的值随机生成的数字。自动递增不是每次递增一个吗?你不能只使用自动递增的数据库id吗?它需要是从元字段max_tickets中设置的值随机生成的数字。自动增量不是每次只增加一个吗?嗨,Sui,谢谢你的回答。票证号码已经在一个表中,但我无法将其作为唯一列添加,因为每个产品的max_票证集都有不同的值,并且该号码是从该字段生成的。因此,如果您订购两种不同的产品,您可能会得到相同的编号,因为选项Togive将与每种产品相关。这有意义吗?创建一个包含所有tickets编号的mysql表会很棘手,因为我需要为每个产品创建不同的表。是否有其他方法可以拆分tickets表,这样我就不必为每个产品tickets创建表?请解释为什么受影响的_行==0?嗨,Sui,谢谢你的回答。票证号码已经在一个表中,但我无法将其作为唯一列添加,因为每个产品的max_票证集都有不同的值,并且该号码是从该字段生成的。因此,如果您订购两种不同的产品,您可能会得到相同的编号,因为选项Togive将与每种产品相关。这有意义吗?创建一个包含所有tickets编号的mysql表会很棘手,因为我需要为每个产品创建不同的表。是否有其他方法可以拆分tickets表,这样我就不必为每个产品tickets创建表?请解释为什么受影响的_行==0?
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
            "
);     

}             

}