如何动态操作传递给 Model::find 的数据?
How to manipulate data being passed to Model::find dynamically?
我的问题
假设您有以下列:
ai - auto incrementing
ref - ABC<ai> (ai but with a prefix)
现在,在模型中,主键是 ai
,但是,在整个应用程序中传递查询参数或作为 post 变量通过表单传递 ref (ABC120
), 所以当 Model::find()
被调用时,它总是 return null
因为自动递增列没有匹配 <prefix><auto-increment>
.
的值
我的尝试
我试图通过 __call
和简单的函数替换来覆盖 find
函数:
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
下面的示例对我有用(使用 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);
}
}
我的问题
假设您有以下列:
ai - auto incrementing
ref - ABC<ai> (ai but with a prefix)
现在,在模型中,主键是 ai
,但是,在整个应用程序中传递查询参数或作为 post 变量通过表单传递 ref (ABC120
), 所以当 Model::find()
被调用时,它总是 return null
因为自动递增列没有匹配 <prefix><auto-increment>
.
我的尝试
我试图通过 __call
和简单的函数替换来覆盖 find
函数:
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
下面的示例对我有用(使用 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);
}
}