【问题标题】:Laravel loading relations - framework bug?Laravel 加载关系 - 框架错误?
【发布时间】:2020-11-06 07:01:11
【问题描述】:

我遇到了一些奇怪的事情,我认为这可能是框架本身的错误,所以我想知道是否有类似的经历。

我有两个实体:ContactMedia 在 1:M 关系中。关系定义为:

public function media()
{
    return $this->hasMany(Media::class);
}

现在我看到的问题是,当我继续 show 控制器方法并加载这样的关系时:

public function show(Contact $contact)
{
    $contact->load('media');
    return response()->json($contact);
}

联系人已解决,媒体关系如下:

"first_name": "Melisa",
...
"media": [
    {
        "id": 50,
    ...

但是,如果我修改关系的大小写以便我调用:

public function show(Contact $contact)
{
    $contact->load('mEdIa');
    return response()->json($contact);
}

返回:

"first_name": "Melisa",
...
"m_ed_ia": [
    {
        "id": 50,
    ...

...这真是令人不安。它应该发生吗?

【问题讨论】:

  • 这就是野兽的本性。如果你的钥匙都一样,它怎么能区分你的意图。 mEdia 变成 m_edia,这不是错误,而是用户错误。
  • 是的,但从我的角度来看,mEdia 不应该被允许。我的关系函数名称是media,我希望它可以这样使用。对于多个单词关系,我也希望命名一致。例如 statusTypes...如果不是函数名,我不希望 sTaTuSTYpE 被称为关系。
  • 不,也许我不够清楚,或者你只是不知道。 PHP 不区分大小写,因此如果无法验证,您希望如何更正此行为。
  • 转换下划线的逻辑是区分大小写的,否则不知道下划线放在哪里。考虑到这一点,严格比较 2 个字符串并不难
  • 我认为我们在这里走错了路,我会回答澄清。

标签: php laravel laravel-7 laravel-7.x


【解决方案1】:

在 Laravel 中有这样的行为。要获得相同的密钥 'mEdIa' - 您必须添加到 media 模型。

public static $snakeAttributes = false;

【讨论】:

  • 是的,但我想保持 2 字关系的行为。如果我有customFields 关系,我希望用户检索custom_fields 属性...而不是cu_stomfiel_ds 一个...
【解决方案2】:

这种行为应该在 Laravel 的文档中注明,事实并非如此。如果我是你,我会打开一个 issue 来更新有关此行为的文档,看看会得到什么响应。

但总的来说,这是一个功能,而不是一个错误

PHP 的本质在很多方面都是敏感和不敏感的。对于类和方法; PHP 是不敏感的。

class Contact {
    public function media() {
        return .. relationship;
    }
}

// valid
new CONTACT();
(new contact())->mediA();
// valid reflection
$r = \ReflectionClass('contact');
$r->hasMethod('mediA'); // true

所以这些古怪的东西都是有效的。现在到你说的重点:

.. 从我的角度来看,mEdia 不应该被允许。我的关系 函数名是media,我希望它被这样使用。

那么你必须这样写。你必须这样做,因为 Laravel 依赖它。

  • PHP 根本无法验证/验证。
  • Laravel 必须改变编程语言的本质,因为它的敏感性是由选择故意设计的。
  • 这里的期望是;你(作为程序员)应该知道 PHP 的敏感性,所以在这种情况下,绝对不需要验证给定的输入。
  • 验证/验证此类事情的开销将是巨大的,而且没有任何意义。
$class = 'contact';
$method = 'mediA';

$r = new \ReflectionClass($class);
if($class !== $r->getName()) {
    throw new \Exception('unknown class');
}
if(!in_array($method, array_map(function($method) {
    return $method->name;
}, $methods))) {
    throw new \Exception('unknown method');
}

// valid from here

从各方面来看,$contacts->with('mediA')的用法是完全有效的。

mediA 在转换为数组时使用Str::snake('mediA') 变为medi_a(这样),这只是你必须处理的 Laravel 的一个特性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    相关资源
    最近更新 更多