php Laravel -允许的内存耗尽的观察者触发器更新模型返回

jc3wubiy  于 2023-03-21  发布在  PHP
关注(0)|答案(2)|浏览(101)

我使用的IntertiaJS有一个Vue组件,可以显示模型的信息,还允许用户在后端更新模型和PATCH:
在前端组件的〈script setup〉标签中:

const postMyModelEdit = () => {
    editMode.value = false; // this is just for controlling state on my component
    router.patch('/mymodels/' + props.mymodel.id, {
        name: props.mymodel.name,
        description: props.mymodel.description,
        ...
        expected_start_date: props.mymodel.expected_start_date,
        expected_end_date: props.mymodel.expected_end_date,
        ..
    });
}

当这被发送到后端时,我更新模型并返回到这个页面,但我的模型上还有一个Observer,它检查 expected_start_dateexpected_end_date 何时更改并更新模型上名为 duration_in_months 的字段。
MyModelController.php

public function update(Request $request, MyModel $mymodel)
{
    $mymodel->update($request->validate([
        'name' => ['max:255'],
        'description' => ['nullable', 'max:255'],
         ...
        'expected_start_date' => ['date'],
        'expected_end_date' => ['nullable', 'date'],
        ...
    ]));

    return redirect()->route('mymodels.show', $mymodel);
}

MyModelObserver.php

public function updated(MyModel $mymodel): void
{
    if ($mymodel->isDirty('expected_start_date') || $mymodel->isDirty('expected_end_date')) {
        $mymodel->updateDurationInMonths();
    }
}

最后,在MyModel.php中:

public function updateDurationInMonths()
{
    $startDate = Carbon::parse($this->expected_start_date);
    $endDate = Carbon::parse($this->expected_end_date);
    $this->duration_in_months = $startDate->diffInMonths($endDate);
    $this->save();
}

当我尝试更新模型时,除了更新 expected_start_dateexpected_end_date 时,所有字段都正常工作。当我尝试这样做时,我得到一个500错误,下面是一个空白屏幕,日志中没有任何条目。然而,我在终端中得到一个错误,告诉我已经超出内存。
第一节第一节第一节第一节第一次
这些操作都是非常基本的,不应该超出内存。也许这与我正在更新和返回的模型上的观察有关,但希望能得到一些帮助来弄清楚这一点!

holgip5t

holgip5t1#

通常,当无限循环发生时,您会看到“Allowed Memory Exhausted”错误。我没有在代码中看到导致无限循环的东西。它可能是代码中的其他地方,您没有添加到问题中。
然而,在update事件的监听器中进行update操作总是很危险的,任何遗漏的点都可能导致无限循环。
我建议修改updating事件中的duration_in_months字段。这样可以避免可能的无限循环,并通过减少更新操作来提高数据库性能。
MyModel.php:

protected static function boot() {
    static::updating(function($mymodel) {
        if ($mymodel->isDirty('expected_start_date') || $mymodel->isDirty('expected_end_date')) {
            $startDate = Carbon::parse($mymodel->expected_start_date);
            $endDate = Carbon::parse($mymodel->expected_end_date);
            $mymodel->duration_in_months = $startDate->diffInMonths($endDate);

            // You must not call "$mymodel->save()" because it will automatically saved.

        }
    }
}
11dmarpk

11dmarpk2#

  • 你可以尝试编辑php.ini(Apache2):
;Old Limit

;memory_limit = 512M

;New Limit

memory_limit = 2048M

sudo服务apache2重新启动

  • 你可以尝试编辑php.ini(Nginx):
; Old Limit

; memory_limit = 512M

; New Limit

  memory_limit = 2048M

sudo systemctl重新启动nginx

相关问题