我目前正在使用Laravel应用程序,并且它具有某些特定用户将登录以生成唯一的12位PIN码的功能。
拥有特定权限的用户应该能够在一个请求中生成至少1,000或10,000个PINS。
我目前正在这样做,效率低下,因为它在服务器资源方面成本非常高:
class PinController extends ApiController
{
public function __construct(Auth $auth, Pin $pin){
$this->auth = $auth;
$this->pin = $pin;
$this->middleware('jwt.auth', ['except' => ['index','show']]);
}
//pin generator - works
protected function random($length = 14)
{
$pool = '123456789';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length - 2);
}
public function store(StoreRequest $request)
{
$number_of_pins = $request->get('number_of_pins');//say 10000
$user = $this->auth->user();
$numbers =[];
for($i=0; $i <= $number_of_pins; $i++){
$number = $this->random(); //generate random 12 digit pins
$numbers[] = $number;
if(!in_array($numbers, $number) || !$this->pin->where('number',$number)->get())
{
$this->pin->create(['number'=>$number,'user_id'=>$user->id]);
}else{
$i--;
}
}
}
}
这需要很长时间才能执行始终失败。 我正在考虑使用队列作业来执行此操作,但它可能不是我应用程序功能的最佳解决方案。
我怎么能以一种不用太久而且不会失败的方式做到这一点?
答案 0 :(得分:1)
if(!in_array($numbers, $number)
会随着$numbers
列表的增长而变得越来越慢.....而不是将$number
设置为数组中的值,将其设置为密钥,然后你可以直接检查重复,这比使用in_array()
快得多
您还要在 之前将$number
添加到$numbers
进行重复检查,因此您已经添加了复制到你的数组(这就是它总是失败的原因)
每个值的数据库检查也是一个很大的开销,最好的消除如果可以的话
if(!isset($numbers[$number])) {
$this->pin->create(['number'=>$number,'user_id'=>$user->id]);
$numbers[$number] = true;
}else{
$i--;
}