为了账号安全,请及时绑定邮箱和手机立即绑定

由于条件关系而对 null 调用成员函数 addEagerConstraints()

由于条件关系而对 null 调用成员函数 addEagerConstraints()

PHP
慕莱坞森 2024-01-19 15:03:19
我必须处理一个 Laravel 7 应用程序,该应用程序的数据库设计不理想,导致标题中提到的错误。数据库看起来像这样:mains- id- sub_typesubs_a- id- main_idsubs_b- id- main_id然后我有一个Main带有方法的类sub:public function sub(){    switch($this->sub_type) {        case 'a':            return $this->hasOne('SubTypeA');            break;        case 'b':            return $this->hasOne('SubTypeB');            break;        default:            return null;    }}此代码适用于 99% 的情况,但 Laravel 有时会加载 的空实例Main,然后尝试加载关系。这是行不通的,因为 method 的默认值sub是null.重组数据库已列入待办事项列表,但目前没有任何帮助。我需要什么选项来阻止 Laravel 尝试sub在空对象上加载关系?
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

我知道这是某种预期,但尝试返回一个空关系?


public function sub()

{

    switch($this->sub_type) {

        case 'a':

            return $this->hasOne('SubTypeA');

            break;

        case 'b':

            return $this->hasOne('SubTypeB');

            break;

        default:

            return $this->newQuery();  // or newQueryWithoutScopes()

    }

}

它应该防止 addEagerConstraints() 对 null 的错误。



查看完整回答
反对 回复 2024-01-19
?
12345678_0001

TA贡献1802条经验 获得超5个赞

我想指出的几件事是,您的关系不应该是有条件的,在将默认关系设置为您想要的默认关系之后,您可以定义范围并管理内容或使用withDefault在失败情况下返回某些内容。

关于在 null 上调用成员函数的错误:- 下面是另一个示例

<?php

class MyClass{

    function bar(){

        echo "something";

    }

}


class MyAnotherClass{

    function foo(){

        if (1>2) {

            $obj = new MyClass();

            $obj->x = $x;

            $obj->y = $y;

            $obj->save();

            return $obj;

        } else {

            return null;

        }

    }

}


$myAnotherObj = new MyAnotherClass();

$myClass = $myAnotherObj->foo();

$myClass->bar()

?>

与其这样做,我更愿意抛出异常并处理它,这样我就能得到失败的具体原因,在 Laravel救援辅助函数中你可以选择使用。


<?php

class MyClass{

    function bar(){

        echo "something";

    }

}


class MyAnotherClass{

    function foo(){

        if (1>2) {

            $obj = new MyClass();

            $obj->x = $x;

            $obj->y = $y;

            $obj->save();

            return $obj;

        } else {

            throw new Exception("could not create my class object", 100); // Better to create custom exception class here

        }

    }

}


$myAnotherObj = new MyAnotherClass();

try {

    $myClass = $myAnotherObj->foo();

    $myClass->bar();

} catch(Exception $e) {

    echo $e->getMessage();

}

?>

如果对我来说数据不是那么重要我会考虑创建一个空对象


<?php

    class MyClass{

        function bar(){

            echo "something";

        }

    }

    

    class MyAnotherClass{

        function foo(){

            $obj = new MyClass();

            if (1>2) {

                $obj->x = $x;

                $obj->y = $y;

                $obj->save();  

            } 

            return $obj;

        }

    }

    

    $myAnotherObj = new MyAnotherClass();

    $myClass = $myAnotherObj->foo();

    $myClass->bar()

  ?>

但是如果您正在使用该对象属性进行操作,那么属性将为 null 而不是对象,因此根据您在使用它时的纪律,您可以做出决定。


我想如何处理你的情况?


异常类


<?php


namespace App\Exceptions;


use Exception;


class SubTypeNotFound extends Exception {

    public function report()

    {

        \Log::debug('Could not find this subtype');

    }

}

?>


模型类


<?php

class Mains extends Model

{

    public function subA()

    {

        return $this->hasOne(SubTypeA::class);

    }    


    public function subB()

    {

        return $this->hasOne(SubTypeB::class);

    }


    public function scopeSub($query, $type)

    {

        return $query

          ->when($type === 'a',function($q){

              return $q->with('subA');

         })

         ->when($type === 'b',function($q){

              return $q->with('subB');

         }),function($q){

             throw SubTypeNotFound();

         });

    }

}

?>

检索它时


try {

    $sub = Mains::sub('a')->get();

} catch(SubTypeNotFound $e) {

    return $e->getMessage();

}

如果有,$this->sub_type您可以避免使用该type参数。


查看完整回答
反对 回复 2024-01-19
?
慕沐林林

TA贡献2016条经验 获得超9个赞

您可以简单地将 if 条件放在 switch case 之前。


public function sub()

{

    if($this->sub_type){

        switch($this->sub_type) {

            case 'a':

                return $this->hasOne('SubTypeA');

                break;

            case 'b':

                return $this->hasOne('SubTypeB');

                break;

            default:

                return null;

        }

    }else{

        return null

    }       

}


查看完整回答
反对 回复 2024-01-19
  • 3 回答
  • 0 关注
  • 45 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信