小剑

Laravel使用体验

最近开发的一个项目用了Laravel

经过大概3个星期的开发,Laravel给我的感觉就是:“对!找的就是你!”,用着实在是太舒心了。一直以来用PHP开发系统时,面对着各种表单操作,增删改查时很令我头痛。无法写出令自己舒心的优雅代码,导致不愿去做类似的工作,加上眼界窄技艺差,也没能积累出一套好的工具或框架。Laravel就如他的介绍一般,是一个为工匠准备的框架,令你享受coding。

整理了些许技巧和例子备忘

扩展 \Illuminate\Database\Eloquent\Collection

文档Returning A Custom Collection Type部分有提及,但是不够详细,我乍看后并不明白其中意思。等到项目开发中有此需求时回头来细读才明白。 用Laravel的Form::select时,第二个参数是这个select的options,往往options的格式是:

array('value1' => 'title1', 'value2' => 'title2')

我一开始的做法是:

$options = array();
Model::all()->each(function($row) use (&$options)
{
    $options[$row->id] = $row->name;
});

后面有好几处都有这个需求,就想能不能扩展一个类似Model::all()->toArray()这样的方法,返回格式化好的options。带着需求查找文档和google,找到了方法。 在Model类中添加如下方法:

public function newCollection(array $models = Array())
{
	return new CustomCollection($models);
}

那么CustomCollection是个什么呢?他是继承\Illuminate\Database\Eloquent\Collection的一个类

class CustomCollection extends \Illuminate\Database\Eloquent\Collection{
    public function toOptions($params)
    {
        $valueKey = array_get($params, 'value', 'id');
		$titleKey = array_get($params, 'title', 'name');
		$optionArray = array();
		$this->each(function($row) use (&$optionArray, $valueKey, $titleKey)
		{
			$optionArray[$row->{$valueKey}] = $row->{$titleKey};
		});
		return $optionArray;
    }
}

这样一来,就可以使用Model::all()->toOptions()来得到options了。 其实说白了,Model::all()Model::where(...)->get()这些返回的都是\Illuminate\Database\Eloquent\Collection实例,你要扩展这个Collection自然是去继承他。最后由上面的public function newCollection(array $models = Array())这个方法来返回我们写好的CustomCollection实例。

PS:让我想起了几天前查什么是IoC,看了好多解释都还不懂。。

列表居然需要搜索的功能!!!(呵呵)

打一开始我就不打算为每个列表各写一次搜索功能。这个直接用Eloquent的scope。直接上酸菜!

public function scopeSearch($query, $conditions)
{
    if(empty($conditions))
	{
		return $query;
	}

	$searchConditions = $this->getSearchConditions();
    $conditions = array_where($conditions, function($key, $value) use ($searchConditions)
    {
        return array_key_exists($key, $searchConditions) && !empty($value);
    });
	
	foreach ($conditions as $key => $value)
	{
        $searchPattern = $searchConditions[$key];
        if(is_array($searchPattern))
        {
            $query->whereHas($searchPattern[0], function($q) use ($key, $searchPattern, $value)
            {
                $q->where($key, $searchPattern[1], $value);
            });
        }
        else
        {
            $query->where($key, $searchPattern, $value);
        }
	}

    return $query;
}

scope是什么意思呢?比如在User里定义scopeWomen

public function scopeWomen($query)
{
    return $query->where('female', '=', '0');
}

调用User::women()->all()返回的数据全是female=0的。上面的scopeSearch则是把结果集限定在了搜索条件范围内了。