You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:25:27