简体   繁体   English

Laravel 4中的通用存取器和变换器

[英]Universal accessors and mutators in Laravel 4

I know it's possible to define accessors and mutators for individual fields, like so: 我知道可以为各个字段定义访问器和更改器,如下所示:

public function setSomeAttribute($value) {
    // set the attribute
}
public function getSomeAttribute() {
    // return the attribute}
}

But is it possible to define a fallback method that will be used for all attribute gets and sets? 但是,是否可以定义一个将用于所有属性获取和设置的回退方法?

The reason being that I want to convert any empty values to null values on the fly, to keep my database clean and allow nullable fields to be null instead of an empty string (if there's a better way to do this let me know!) 原因是我想动态地将任何空值转换为空值,以保持我的数据库干净并允许可空字段为空而不是空字符串(如果有更好的方法,请告诉我!)

I'm looking for something like 我正在寻找类似的东西

public function setAttribute($property,$value) {
    $this->$property = empty($value) ? null : $value;
}

UPDATE: 更新:

Thanks to Chris Goosey I've found a solution that works for me. 感谢Chris Goosey,我找到了一个适合我的解决方案。 I extended the Eloquent model method setAttribute, and I set the value to the column default if it's empty. 我扩展了Eloquent模型方法setAttribute,如果它是空的,我将值设置为默认列。 That's usually null, zero or an empty string in my databases so works for me! 我的数据库中通常为null,零或空字符串,因此对我有用!

public function setAttribute($key, $value)
{
    // Convert empty values to their default values (e.g. null, zero)
    if(empty($value) && $this->getSchema()->hasColumn($key)) {
        $value = $this->getSchema()->getColumn($key)->getDefault();
    }
    parent::setAttribute($key,$value);
}

Best way is probably to extend the Eloquent class overwriting the setAttribute and getAttribute methods. 最好的方法可能是扩展Eloquent类覆盖setAttribute和getAttribute方法。

For all your models to inherit these overwritten methods you would want to create a class that extends eloquent eg 对于所有模型继承这些重写方法,您可能希望创建一个扩展雄辩的类,例如

<?php 

class BaseModel extends eloquent {

    public function setAttribute($property,$value) {
        $this->$property = empty($value) ? null : $value;
    }

    public function getAttribute($key) {
        // Do Stuff
    }
}

and then all your models should extend from this new class, eg 然后你的所有模型都应该扩展到这个新类,例如

<?php

class User extends BaseModel {
    protected $table = 'users';
}

It is also worth mentioning your new methods should have all the functionality of the old method plus your new functionality, this is what the getAttribute() looks like (Illuminate\\Database\\Eloquent line 2212): 还值得一提的是,您的新方法应该具有旧方法的所有功能以及您的新功能,这就是getAttribute()的样子(Illuminate \\ Database \\ Eloquent line 2212):

/**
 * Get an attribute from the model.
 *
 * @param  string  $key
 * @return mixed
 */
public function getAttribute($key)
{
    $inAttributes = array_key_exists($key, $this->attributes);

    // If the key references an attribute, we can just go ahead and return the
    // plain attribute value from the model. This allows every attribute to
    // be dynamically accessed through the _get method without accessors.
    if ($inAttributes || $this->hasGetMutator($key))
    {
        return $this->getAttributeValue($key);
    }

    // If the key already exists in the relationships array, it just means the
    // relationship has already been loaded, so we'll just return it out of
    // here because there is no need to query within the relations twice.
    if (array_key_exists($key, $this->relations))
    {
        return $this->relations[$key];
    }

    // If the "attribute" exists as a method on the model, we will just assume
    // it is a relationship and will load and return results from the query
    // and hydrate the relationship's value on the "relationships" array.
    $camelKey = camel_case($key);

    if (method_exists($this, $camelKey))
    {
        return $this->getRelationshipFromMethod($key, $camelKey);
    }
}

and the setAttribute in the same file looks like this (line 2338): 并且同一文件中的setAttribute看起来像这样(第2338行):

/**
 * Set a given attribute on the model.
 *
 * @param  string  $key
 * @param  mixed   $value
 * @return void
 */
public function setAttribute($key, $value)
{
    // First we will check for the presence of a mutator for the set operation
    // which simply lets the developers tweak the attribute as it is set on
    // the model, such as "json_encoding" an listing of data for storage.
    if ($this->hasSetMutator($key))
    {
        $method = 'set'.studly_case($key).'Attribute';

        return $this->{$method}($value);
    }

    // If an attribute is listed as a "date", we'll convert it from a DateTime
    // instance into a form proper for storage on the database tables using
    // the connection grammar's date format. We will auto set the values.
    elseif (in_array($key, $this->getDates()))
    {
        if ($value)
        {
            $value = $this->fromDateTime($value);
        }
    }

    $this->attributes[$key] = $value;
}

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM