web-dev-qa-db-ja.com

Laravel-一意の注文番号を生成

現在、ユーザーがcreateメソッドに到達したときに一意の注文番号を生成しようとしています。注文番号はシード内でこのように生成され、同様にこのようにする必要があります

シード

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(),

        ]);
    }

注文番号は次のようになります#00000001または#00000002。ここで、ユーザーがコントローラーのcreateメソッドに到達すると、このシーケンスの新しい一意の注文番号を作成する必要があります。どうすればそれを達成できますか?コントローラは現在、次のようになっています。

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

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


    dd($order);


    return view('steps.order');
}

最新の注文番号を確認し、その注文番号に+1を付けて作成する必要があります。たとえば、注文が25あり、最後の注文が#00000025で、次に作成する必要がある注文が#00000026であるとします。どうすればそれを達成できますか?

5
Rainier Laan

次のようにしてみてください

$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();

ここでは、idが自動インクリメントしていると想定しています。詳細は str_pad メソッドを参照してください

6
KalyanLahkar

行の自動列ID値を使用して、注文番号を生成します。ただし、order-columnはid列に完全に依存しているため、注文番号に追加の列を作成しないでください。これにより、正規化されていないDBが生成されます。

代わりに、このメソッドをorderモデルに追加します

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

最後の注文のIDが5で、それを削除する場合、次の注文のIDは6になります。

唯一の例外は、トランザクション内で注文を作成する場合です。トランザクションがロールバックされた場合、関連する注文IDはスキップされます。

2
Adam

Laravel IDジェネレーター を使用できます。

最初にインストールします:composer require haruncpi/laravel-id-generator

コントローラにクラスをインポートします。

use Haruncpi\LaravelIdGenerator\IdGenerator;

今すぐそれを使う

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

出力

#00000001
#00000002
#00000003
...
1
Harun

最大値を読み取る際の問題 IDがあり、それをインクリメントします。重いサーバーまたは並列リクエストでは、2つのリクエストがMySQLから同じmax(id)を読み取ることがあります。

一意のシーケンス番号を作成する最適な方法は、自動インクリメントフィールドが1つだけのシーケンステーブルを使用することです。

  1. 最初に、シーケンステーブルに新しいレコードを挿入します。
  2. 次に、LAST_INSERT_ID()MySQL関数によって、最後に挿入されたIDをdbから読み取ります。
  3. ついに、あなたのIDよりも古いレコードを削除することができます。

Laravelの方法:

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

$ idは、固有のシーケンス番号です。

0
Mahoor13

私はより良い解決策を見つけました:

$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;
}
0
Rajakishore B

これで試すことができます:

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

$this->generateOrderNR();関数でcreate()を使用して_order_nr_を生成できます。

さらに、mt_Rand()Rand()より4倍高速です。これを使用すると、ユーザーエクスペリエンスが向上します。

0
Nazmus Shakib