Laravel - 生成唯一的订单号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49446329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:33:19  来源:igfitidea点击:

Laravel - generate unique order number

phplaravellaravel-5laravel-4

提问by Rainier Laan

I'm currently trying to generate a unique order number when the user reaches the create method. The order numbers are generated like this in the seed and need to look like this as well

我目前正在尝试在用户到达 create 方法时生成一个唯一的订单号。订单号在种子中是这样生成的,也需要看起来像这样

Seed

种子

foreach(range(1,25) as $index)
    {
        DB::table('orders')->insert([

            'user_id' => rand(1,25),
            'order_nr' => '#' . sprintf("%08d", $index),
            'price_sum' => $faker->randomNumber($nbDigits = 4, $strict = false) . '.' . $faker->randomNumber($nbDigits = 2, $strict = false),
            'status' => $faker->randomElement(['paid', 'pending', 'failed']),
            'created_at' => Carbon::now(),
            'updated_at' => Carbon::now(),

        ]);
    }

The order numbers look like this #00000001or #00000002. Now when the user reaches the create method in my controller a new unique order number in this sequence needs to be created. How can I achieve that? The controller currently looks like this:

订单号看起来像这样#00000001#00000002。现在,当用户到达我的控制器中的 create 方法时,需要在此序列中创建一个新的唯一订单号。我怎样才能做到这一点?控制器目前看起来像这样:

 public function create()
{
    $order = new Order;

    $order->user_id = Auth()->id();
    $order->order_nr = 


    dd($order);


    return view('steps.order');
}

It needs to check the latest order number and create one with +1 on that order number. Say for instance there are 25 orders and the last one is #00000025 the one that needs to be created next needs to be #00000026. How can I achieve that?

它需要检查最新的订单号并在该订单号上创建一个带有 +1 的订单号。比如说有25个订单,最后一个是#00000025,接下来需要创建的订单是#00000026。我怎样才能做到这一点?

回答by KalyanLahkar

Try doing as following

尝试执行以下操作

$order = new Order;

$order->user_id = Auth()->id();
$latestOrder = App\Order::orderBy('created_at','DESC')->first();
$order->order_nr = '#'.str_pad($latestOrder->id + 1, 8, "0", STR_PAD_LEFT);
$order->save();

Here I am assuming that the id is auto-incrementing. See the str_padmethod for more details

这里我假设 id 是自动递增的。有关更多详细信息,请参阅str_pad方法

回答by Adam

Use the auto column id value of your rows to generate the order number. However, do not create an extra column for your order number, because this would give you an unnormalized DB, since the order-column is completely dependent of the id column.

使用行的自动列 id 值生成订单号。但是,不要为您的订单号创建额外的列,因为这会给您一个非规范化的数据库,因为订单列完全依赖于 id 列。

Instead, add this method to you ordermodel

相反,将此方法添加到您的order模型中

public function get_order_number()
{
    return '#' . str_pad($this->id, 8, "0", STR_PAD_LEFT);
}

If your last order had the id 5and you would delete it, then the next order would have the id 6.

如果您的上一个订单具有 id5并且您将其删除,那么下一个订单将具有 id 6

The only possible exception is if you create orders within an transaction. If a transaction is rolled back, the associated order id would be skipped.

唯一可能的例外是您在交易中创建订单。如果事务回滚,则将跳过关联的订单 ID。

回答by Harun

You can use the Laravel ID generator.

您可以使用Laravel ID 生成器

First Install it: composer require haruncpi/laravel-id-generator

首先安装它: composer require haruncpi/laravel-id-generator

Import the class in your controller.

在您的控制器中导入该类。

use Haruncpi\LaravelIdGenerator\IdGenerator;

Now simply use it

现在只需使用它

$prefix = "#";  
$id = IdGenerator::generate(['table' => 'your_table_name', 'length' => 9, 'prefix' =>$prefix]);

Output

输出

#00000001
#00000002
#00000003
...

回答by Mahoor13

There is a problem in reading the maximumid and increment it. In heavy servers or parallel requests, two requests may read the same max(id) from MySQL.

有一个在读的最大问题ID和递增它。在繁重的服务器或并行请求中,两个请求可能会从 MySQL 读取相同的 max(id)。

The best way to create unique sequence number is use a sequence table with just one auto increment field.

创建唯一序列号的最佳方法是使用只有一个自动增量字段的序列表。

  1. First insert new record in the sequence table.
  2. Then read the last inserted id from db by LAST_INSERT_ID() MySQL function.
  3. At last you can remove old records lower than your id.
  1. 首先在序列表中插入新记录。
  2. 然后通过 LAST_INSERT_ID() MySQL 函数从 db 读取最后插入的 id。
  3. 最后,您可以删除低于您的 id 的旧记录。

Laravel way:

Laravel 方式:

$id = DB::table('seq_foo')->insertGetId(['id' => null]);
DB::table('seq_foo')->where('id', '<', $id)->delete();

$id is your unique sequence number.

$id 是您的唯一序列号。

回答by Nazmus Shakib

You may try with this:

你可以试试这个:

public function generateOrderNR()
{
    $orderObj = \DB::table('orders')->select('order_nr')->latest('id')->first();
    if ($orderObj) {
        $orderNr = $orderObj->order_nr;
        $removed1char = substr($orderNr, 1);
        $generateOrder_nr = $stpad = '#' . str_pad($removed1char + 1, 8, "0", STR_PAD_LEFT);
    } else {
        $generateOrder_nr = '#' . str_pad(1, 8, "0", STR_PAD_LEFT);
    }
    return $generateOrder_nr;
}

You can generate order_nrby using this: $this->generateOrderNR();in your create()function.

您可以order_nr通过$this->generateOrderNR();create()函数中使用 this:来生成。

In addition mt_rand()is 4 times faster than rand()you may use this for better user experience.

此外,mt_rand()它比rand()您使用它的速度快 4 倍,以获得更好的用户体验。

回答by Rajakishore B

I have found a better solution:

我找到了一个更好的解决方案:

$paynowbillprefix1="ADDON-";
$paynowbillprefix1=strlen($paynowbillprefix1);
$query2 = "select gen_id from user_cart_addon order by id desc limit 0, 1";
$exec2 = mysqli_query($conn,$query2) or die ("Error in Query2".mysqli_error());
$res2 = mysqli_fetch_array($exec2);
$num2 = mysqli_num_rows($exec2);
$billnumber = $res2["gen_id"];
$billdigit=strlen($billnumber);
if ($billnumber == '')
{
    $billnumbercode ='ADDON-'.'1';
}
else
{
    $billnumber = $res2["gen_id"];
    $billnumbercode = substr($billnumber,$paynowbillprefix1, $billdigit);
    $billnumbercode = intval($billnumbercode);
    $billnumbercode = $billnumbercode + 1;
    $maxanum = $billnumbercode;   
    $billnumbercode = 'ADDON-'.$maxanum;
}