Alf*_*rez 4 php slim twig eloquent
我试图在Slim中使用Twig访问Eloquent属性,并收到错误.
我有一个Field和一个Type对象,关系如下
class Field extends \Illuminate\Database\Eloquent\Model {
protected $table = 'fields';
public function type()
{
return $this->belongsTo('models\Type');
}
Run Code Online (Sandbox Code Playgroud)
在做{{ f }}(作为fa字段)时,输出是这样的:
{"field_id":"1","field_name":"Your name","form_id":"2","type_id":"1","placeholder":"Please give us your name"}
Run Code Online (Sandbox Code Playgroud)
在做的时候{{ f.type }},结果是:
消息:在第97行的"pages/editform.html"中呈现模板("类Illuminate\Database\Eloquent\Relations\BelongsTo的对象无法转换为字符串")期间抛出了异常.
如果我尝试这样做{{ f.type.name }},不会抛出异常,但也不会打印任何东西.
如果我用PHP做的话
$fields = $form->fields;
var_dump($fields[0]->type->name);
Run Code Online (Sandbox Code Playgroud)
该值正确输出.
有什么想法吗?谢谢
如果你不想做一个热心的负荷,你可以重写魔术__isset方法在你的Field类返回true的type关系属性:
public function __isset($name)
{
if (in_array($name, [
'type'
])) {
return true;
} else {
return parent::__isset($name);
}
}
Run Code Online (Sandbox Code Playgroud)
说明
问题在于Eloquent如何为关系(在您的情况下f.type)实现"动态属性" 与Twig用于访问变量"属性"的规则之间的交互.
从Twig文档:
为方便起见
foo.bar,在PHP层上执行以下操作:
- 检查if
foo是否为数组和bar有效元素;- 如果不是,如果
foo是对象,请检查该bar属性是否有效 ;- 如果不是,并且if
foo是一个对象,检查这bar是一个有效的方法(即使bar是构造函数 -__construct()改为使用);- 如果不是,如果
foo是一个对象,检查这getBar是一个有效的方法;- 如果不是,如果
foo是一个对象,检查这isBar是一个有效的方法;- 如果不是,则返回空值.
foo['bar']另一方面,只适用于PHP数组:
- 检查if
foo是否为数组和bar有效元素;- 如果不是,则返回空值.
这里的关键是它说"检查酒吧是有效的财产"的部分.这意味着在PHP的水平,嫩枝呼吁isset上$f->type.洋洋洒洒实现了神奇__isset的方法Model,所以你可能会认为这不会是一个问题.
但是,看看它实际上如何实现__isset模型关系:
/**
* Determine if an attribute exists on the model.
*
* @param string $key
* @return bool
*/
public function __isset($key)
{
return (isset($this->attributes[$key]) || isset($this->relations[$key])) ||
($this->hasGetMutator($key) && ! is_null($this->getAttributeValue($key)));
}
Run Code Online (Sandbox Code Playgroud)
它通过查看加载关系数组(isset($this->relations[$key]))确定关系是否"设置" .问题是,如果type还没有加载,Eloquent会说它不是"设置".
因此,当Twig查看时$f->type,它会认为这type不是一个有效的属性,并继续下一个规则:
...如果
foo是对象,请检查该bar方法是否有效
所以现在它将寻找它找到的方法 type().唯一的问题? type()(该方法)返回Relation(具体地说,a BelongsTo)而不是Type对象.而BelongsTo对象不是模型.
如果您希望Twig知道该物业$f->type确实存在,您有两种选择:
Type对象Field,或者;__isset魔术方法Field:
public function __isset($name)
{
if (in_array($name, [
'type'
])) {
return true;
} else {
return parent::__isset($name);
}
}
这将迫使Twig识别出它type是一个有效的属性Field,甚至在实际加载相关模型之前.
我遇到了同样的问题,偶然发现了这个问题.在自己解决之后,我想我会尽力帮助你.
尝试在模型上执行Eager Load:
Field::with('type')->get()
Run Code Online (Sandbox Code Playgroud)
这应该允许您执行以下操作而不会出现其他问题.
{{ f.type }}
Run Code Online (Sandbox Code Playgroud)
在此处查看更多信息:http://laravel.com/docs/4.2/eloquent#eager-loading