Laravel 入库写法讨论

新手上路,请多包涵

很简单的文章提交功能,
平时入库的写法,我是这么写的:

foreach ($_POST['ArticelData'] as $item) {
    $model = new Articel();
    $model->Title = $item['Title'];
    $model->Content = $item['Content'];
    $model->Image = $item['Image'];
    $model->save();
 }

但是今天看到有这么写的:

主model类里这么写:

        $InsertData = [];
        foreach ($_POST['ArticelData'] as $item) {
            $model = new ArticelFilter($item);
            $model->setTitle($model->getTitle());
            $model->setContent($model->getContent());
            $model->setImage($model->getImage());
            $InsertData[] = $model->toArray();
        }
        Articel::insert($InsertData);

ArticelFilter的Model:

protected $Title;
protected $Content;
protected $Image;
  public function setTitle()
  {
      return $this->Title;
  }
  public function getTitle($Title)
  {
      $this->Title = $Title;
  }
  public function setContent($Content):  
  {
      $this->Content = $Content;
  }
  public function getContent()
  {
      return $this->Content;
  }
  public function setImage($Image): 
  {
      $this->Image = $Image;
  }
  public function getImage()
  {
      return $this->Image;
  }
  

这些set和get,在基类用这个构造方法实现:

public function __call($name, $params)
{
    $function_type = substr($name, 0, 3);
    if (in_array($function_type, array('get', 'set'))) {
        $property = lcfirst(substr($name, 3));
        if (property_exists($this, $property)) {
            switch ($function_type) {
                case 'get':
                    return $this->$property;
                case 'set':
                    $this->$property = $params[0];
            }
        }
    }
}

问一下各位经验丰富的大神们,这么写的原理是什么,好处是什么?
感觉很多SDK都是这么写的, 这属于一种设计模式吗?

阅读 3.3k
4 个回答

首先从性能上来说,

foreach ($_POST['ArticelData'] as $item) {
    ...
    $model->save();
 }

是不及

$InsertData = [];
foreach ($_POST['ArticelData'] as $item) {
    ...
    $InsertData[] = $model->toArray();
}
Articel::insert($InsertData);

如果 ArticleData 的长度是 N ,那么前者就会产生 N 个 insert 语句,而后者只会产生一条 insert 语句。

再看后面这个例子

$model = new ArticelFilter($item);
$model->setTitle($model->getTitle());
$model->setContent($model->getContent());
$model->setImage($model->getImage());
$InsertData[] = $model->toArray();

这里 model 先 get 再 set ,有些奇怪,说明 ArticleFilter 的构造方法应该是类似于下面的形式

foreach($item as $prototype => $value){
    $this->{$prototype} = $value;
}

然后再 get 出来,然后再 set 进去,而这里就可以在 set 的时候做数据校验,让代码看起来也更加的面向对象了。

其实如果对构造函数稍加改造,就可以不用再手动的 get/set 一次了

这是java的习惯。但是最新的laravel8,确实有get和set写法,但是却不同于Java的这种写法。具体我到了公司给你粘个图就知道了

image.png

相关 commit 可以查看这里。

8.x Attribute Cast / Accessor Annotations

他这样写的好处在于未来便于对入库的字段和获取的字段操作进行升级,便于加入一些逻辑,get(),set()方法里都可以加入一些逻辑。可以简单理解成这样写便于扩展,追求完美。
但从实际经验来看,你那样写也行。真正需要扩展时,往往简单的代码修修补补,复杂的代码直接重构。

新手上路,请多包涵

方法二的好处是减少数据库操作次数吧,更效率。
get set 感觉略显冗余

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题