如何操纵传递给Model ::动态的数据?

问题描述 投票:-1回答:1

我的问题

想象一下,您有以下列:

ai - auto incrementing
ref - ABC<ai> (ai but with a prefix)

现在,在Model中,主键是ai,但是,在整个应用程序中传递查询参数或作为post变量通过表单我们传递ref(ABC120),所以当调用Model::find()时,它将始终返回null,因为自动增量列没有与<prefix><auto-increment>匹配的值。

我的尝试

我试图通过find和简单的函数替换来覆盖__call函数:

function __call($method, $params)
{
    switch ($method) {
        case 'find':
            $params[0] = preg_replace('/[^0-9]/', '', $params[0]);
        break;
    }

    return parent::__call($method, $params);
}

要么

public static function find($p)
{
    $p = preg_replace('/[^0-9]/', '', $p);
    $r = self::where('ai', $p);

    if (!$r->count()) {
        return null;
    }

    return $r->first();
}

要么

public static function find($p)
{
    $p = preg_replace('/[^0-9]/', '', $p);

    return parent::find($p); // out of memory exception
}

两者的问题在于,如果您从不同的入口点(即Model::withTrashed()->find())链接模型,它将恢复为标准的find函数,这会导致找不到行(由于前缀)。

在一个理想的世界里,我只是让ref成为主键,但我不能。

那么,我怎样才能覆盖find函数或覆盖Eloquent,这样每当进行内部数据库调用时,它会删除ai(或传递给它的任何内容)的任何非数字字符?

我的例子

Model::find('ABC12345') // Internally, it strips off ABC
php laravel override laravel-5.7
1个回答
0
投票

下面的示例适用于我(使用User::find('ABC1')测试)。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Support\Arrayable;

class User extends Model
{
    /**
     * Find a model by its primary key.
     *
     * @param  mixed  $id
     * @param  array  $columns
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
     */
    public static function find($id, $columns = ['*'])
    {
        $id = preg_replace('/[^0-9]/', '', $id);

        $query = with(new static())->newQuery();

        if (is_array($id) || $id instanceof Arrayable) {
            return $query->findMany($id, $columns);
        }

        return $query->whereKey($id)->first($columns);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.