Laravel 正确的条件处理
Laravel correct condition handling
我的网站上有一个功能,可以每 24 小时自动为会员创建一次促销代码。如果促销代码创建后已过去 24 小时,则会从数据库中删除旧促销,并重新生成一个新促销。但是现在这个功能有问题,不管是否过了24小时,每次都会生成一个新的优惠码。
我的函数:
public function autoGroupPromos()
{
$userList = Promo::get();
$userIds = $userList->pluck('user_id');
foreach ($userIds as $id) {
$date = Carbon::now();
$promoCodes = Promocode::query()->where('vk_user_id', '!=', null)->get();
foreach ($promoCodes as $promos) {
// If promo create 24 hours ago
$hours = $promos->created_at->diffInHours($date);
if ($hours >= 24) {
$promos->delete();
}
}
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
$code = substr(str_shuffle($permitted_chars), 0, 8);
Promocode::query()->create([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
'vk_user_id' => $id
]);
$promoText = Promocode::where('vk_user_id', $id)->orderBy('created_at', 'desc')->first();
$promoName = $promoText->name;
$message = 'Your new promo: ' . $promoName . ';
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
}
}
也就是说,如果促销创建后不到 24 小时 - 不应将其删除,也不应生成新的促销代码。但现在不幸的是某处出错了。
可能是什么问题?
function autoGroupPromos()
{
// removed for loop to clean outdated promos in single request
// note that this way of deleting rows won't fire model events (if any)
Promocode::whereNotNull('vk_user_id')
->where('created_at', '<=', Carbon::now()->subDay(1))
->delete();
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
$userIds = Promo::pluck('user_id');
foreach ($userIds as $id) {
/* in the begining we cleaned all outdated codes, so if user still has
some - no need to create new */
if (Promocode::where('vk_user_id', $id)->exists()){
continue;
}
$code = substr(str_shuffle($permitted_chars), 0, 8);
/* you can immidiately get create model like this -
no need to make another request
$createdPromo = Promocode::create([*/
Promocode::create([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
'vk_user_id' => $id
]);
/* didn't get why you were requesting newly created
promo to get name field if you put there $code value */
$message = `Your new promo: $code`;
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
}
}
upd:这里可以使用 hasOneOfMany 并跳过每个用户请求以检查促销代码是否存在
// User model
public function promocodes() {
return $this->hasMany(Promocode::class);
}
public function promocode() {
return $this->hasOne(Promocode::class)->latestOfMany();
}
function autoGroupPromos()
{
// note that this way of deleting rows won't fire model events (if any)
Promocode::whereNotNull('vk_user_id')
->where('created_at', '<=', Carbon::now()->subDay(1))
->delete();
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
// taking users without promo after cleanup
User::whereDoesntHave('promo')->get()
->each(function (User $user) use ($permitted_chars) {
$code = substr(str_shuffle($permitted_chars), 0, 8);
// pay attention on relation name - using hasMany
$user->promocodes()->save(
new Promocode([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
])
);
$message = `Your new promo: $code`;
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
});
}
我的网站上有一个功能,可以每 24 小时自动为会员创建一次促销代码。如果促销代码创建后已过去 24 小时,则会从数据库中删除旧促销,并重新生成一个新促销。但是现在这个功能有问题,不管是否过了24小时,每次都会生成一个新的优惠码。
我的函数:
public function autoGroupPromos()
{
$userList = Promo::get();
$userIds = $userList->pluck('user_id');
foreach ($userIds as $id) {
$date = Carbon::now();
$promoCodes = Promocode::query()->where('vk_user_id', '!=', null)->get();
foreach ($promoCodes as $promos) {
// If promo create 24 hours ago
$hours = $promos->created_at->diffInHours($date);
if ($hours >= 24) {
$promos->delete();
}
}
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
$code = substr(str_shuffle($permitted_chars), 0, 8);
Promocode::query()->create([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
'vk_user_id' => $id
]);
$promoText = Promocode::where('vk_user_id', $id)->orderBy('created_at', 'desc')->first();
$promoName = $promoText->name;
$message = 'Your new promo: ' . $promoName . ';
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
}
}
也就是说,如果促销创建后不到 24 小时 - 不应将其删除,也不应生成新的促销代码。但现在不幸的是某处出错了。
可能是什么问题?
function autoGroupPromos()
{
// removed for loop to clean outdated promos in single request
// note that this way of deleting rows won't fire model events (if any)
Promocode::whereNotNull('vk_user_id')
->where('created_at', '<=', Carbon::now()->subDay(1))
->delete();
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
$userIds = Promo::pluck('user_id');
foreach ($userIds as $id) {
/* in the begining we cleaned all outdated codes, so if user still has
some - no need to create new */
if (Promocode::where('vk_user_id', $id)->exists()){
continue;
}
$code = substr(str_shuffle($permitted_chars), 0, 8);
/* you can immidiately get create model like this -
no need to make another request
$createdPromo = Promocode::create([*/
Promocode::create([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
'vk_user_id' => $id
]);
/* didn't get why you were requesting newly created
promo to get name field if you put there $code value */
$message = `Your new promo: $code`;
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
}
}
upd:这里可以使用 hasOneOfMany 并跳过每个用户请求以检查促销代码是否存在
// User model
public function promocodes() {
return $this->hasMany(Promocode::class);
}
public function promocode() {
return $this->hasOne(Promocode::class)->latestOfMany();
}
function autoGroupPromos()
{
// note that this way of deleting rows won't fire model events (if any)
Promocode::whereNotNull('vk_user_id')
->where('created_at', '<=', Carbon::now()->subDay(1))
->delete();
$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
// taking users without promo after cleanup
User::whereDoesntHave('promo')->get()
->each(function (User $user) use ($permitted_chars) {
$code = substr(str_shuffle($permitted_chars), 0, 8);
// pay attention on relation name - using hasMany
$user->promocodes()->save(
new Promocode([
'name' => $code,
'sum' => '0.25',
'activates' => '100',
])
);
$message = `Your new promo: $code`;
$url = 'https://api.vk.com/method/messages.send';
$params = array(
'message' => $message,
'access_token' => 'token',
'v' => '5.81',
'peer_ids' => $id
);
$result = file_get_contents($url, false, stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => http_build_query($params)
)
)));
});
}