Laravel Job发送逾期用户短信报错:常量表达式含无效操作
解决Laravel Job中"Constant expression contains invalid operations"错误
错误原因
PHP类的成员属性在声明时,只能用常量表达式初始化(比如字符串、数字、静态数组等),你直接在private $defaulters后面绑定DB查询操作,属于动态执行的代码,PHP不允许这种写法,所以抛出了这个错误。
修复方案
方案1:构造函数传入查询结果(推荐,符合Job职责分离)
先移除属性上的查询初始化,只声明变量;然后在外部执行查询,把结果传给Job的构造函数:
class SendDefaulterMessage implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $twilioClient; private $defaulters; // 仅声明变量,不做初始化查询 public function __construct($defaulters) { $this->defaulters = $defaulters; $sid = config('services.twilio.account_sid'); $token = config('services.twilio.auth_token'); $this->twilioClient = new Client($sid, $token); } // 短信发送逻辑写在handle方法中 public function handle() { foreach ($this->defaulters as $defaulter) { // 执行短信发送 $this->twilioClient->messages->create( $defaulter->Phone, [ 'from' => config('services.twilio.phone_number'), 'body' => "您好 {$defaulter->Tfullname},您的房租已逾期,请及时缴纳。" ] ); } } }
调用Job时先执行查询再传入结果:
$defaulters = DB::table('forrent') ->join('landlord','forrent.LandLordID','=','landlord.LandLordID') ->join('tenant','forrent.AccountNo','=','tenant.AccountNo') ->join('property','tenant.PropertyID','=','property.PropertyID') ->select(DB::raw("CONCAT(landlord.Title,' ',landlord.OtherNames,' ',landlord.Surname) as Lfullname"),DB::raw("CONCAT(tenant.Title,' ',tenant.OtherNames,' ',tenant.Surname) as Tfullname"),'tenant.RegDate as RegDate', 'tenant.AccountNo as Accno','tenant.Rent as Rent', 'tenant.NoOfProperty as NoOfProperty','tenant.Address as Address','tenant.Phone as Phone','forrent.LastPeriod as LastPeriod','forrent.LPDate as Lp', 'property.Property as Property','property.Description as Description') ->get(); SendDefaulterMessage::dispatch($defaulters);
方案2:在handle方法内执行查询
如果不需要外部传入查询结果,也可以把查询逻辑移到handle方法里,让Job自行获取数据:
class SendDefaulterMessage implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; private $twilioClient; public function __construct() { $sid = config('services.twilio.account_sid'); $token = config('services.twilio.auth_token'); $this->twilioClient = new Client($sid, $token); } public function handle() { // 在这里执行逾期用户查询 $defaulters = DB::table('forrent') ->join('landlord','forrent.LandLordID','=','landlord.LandLordID') ->join('tenant','forrent.AccountNo','=','tenant.AccountNo') ->join('property','tenant.PropertyID','=','property.PropertyID') ->select(DB::raw("CONCAT(landlord.Title,' ',landlord.OtherNames,' ',landlord.Surname) as Lfullname"),DB::raw("CONCAT(tenant.Title,' ',tenant.OtherNames,' ',tenant.Surname) as Tfullname"),'tenant.RegDate as RegDate', 'tenant.AccountNo as Accno','tenant.Rent as Rent', 'tenant.NoOfProperty as NoOfProperty','tenant.Address as Address','tenant.Phone as Phone','forrent.LastPeriod as LastPeriod','forrent.LPDate as Lp', 'property.Property as Property','property.Description as Description') ->get(); foreach ($defaulters as $defaulter) { // 执行短信发送 $this->twilioClient->messages->create( $defaulter->Phone, [ 'from' => config('services.twilio.phone_number'), 'body' => "您好 {$defaulter->Tfullname},您的房租已逾期,请及时缴纳。" ] ); } } }
调用时直接触发Job即可:
SendDefaulterMessage::dispatch();
额外提示
- 方案1更灵活,可在外部调整查询条件后再传给Job;方案2把查询和发送逻辑绑定,适合查询规则固定的场景。
- 如果逾期用户数据量较大,建议用
chunk方法分批处理,避免内存溢出:DB::table(...)->chunk(100, function ($batch) { /* 批量发送短信 */ })
内容的提问来源于stack exchange,提问作者Oscark
相关产品推荐
相关产品推荐

