php中 ,一直以来,服务端搜索,我都是写一堆条件判断,搜索条件少时还好,条件一多,就显的代码有点丑陋了;
看着非常不舒服。今天在园子里看到一篇文章(http://www.cnblogs.com/xqin/archive/2013/06/03/3114634.html)。
不过,他是用NET写的。但受了这篇文章一点启发。将我的搜索改了下,虽然现在看起来还不是很完美。但代码看起来没那么丑了。
$data = array();
$data = fixer::input('post')
->specialChars('username,nickname,regdate_startDate,regdate_endDate')
->get();
$searchSetting = array(
array('field'=>'username' , 'cp'=> 'like'),
array('field'=>'nickname' , 'cp'=> 'like'),
array('field'=>'regdate' , 'cp'=> 'daterange'),
);
$map = service('Search')->loadSearchSettings($searchSetting , $data);
上面代码是先将客户端提交的数据,先整理好。包括转义和类型转换。因为搜索那边,是不处理数据的。数据是在外围处理好的
$searchSetting 这个数组存的是每个搜索的配置 ,其它 cp 的值就是我们需要写的.我目前只写了 equal ,like ,daterange.刚好用到了这几个。
这样执行后,在控制器里的代码很少,看上去没那么乱,直接将$map做为where条件
class SearchService
{
/** $searchSetting = array(
array('field'=>'username' , 'cp'=> 'like','variable'=>'uname'),
);
* 根椐传递过来的动态搜索配置,生成相应的查询条件,返回去
* @param array $searchSettings [description]
* @return [type] [description]
*/
public function loadSearchSettings($searchSettings = array() , $data)
{
$map = array();
if (empty($searchSettings) || ! is_array($searchSettings)) return $map;
foreach ($searchSettings as $item)
{
$cp = isset($item['cp']) && $item['cp'] ? trim($item['cp']) : '';
if (empty($cp)) continue;
if(method_exists('cp' , $cp)) {
$s = call_user_func_array(array('cp' , $cp) , array($item , $data) );
if ($s) $map[] = $s;
}
}
$whereData = array();
if ($map)
{
foreach($map as $key => $item)
{
if (is_array($item))
{
foreach($item as $field => $value)
{
$whereData[$field] = $value;
}
}
}
}
return $whereData;
}
}
cp.php类
<?php
/**
* 搜索的各种逻辑
* 注意,不处理数据,数据在外围处理好,包括类型转换这种
* @package framework
*/
class cp
{
const FIELD_NAME = 'field';
const VARIABLE = 'variable';
/**
* 相等
* @param [type] $fieldConfig [description]
* @param array $data [description]
* @return [type] [description]
*/
public static function equal($fieldConfig ,$data = array())
{
$map = array();
if (! isset($fieldConfig[self::FIELD_NAME])) return $map;
$fieldName = $fieldConfig[self::FIELD_NAME];
$getfield = self::getField($fieldConfig);
if (isset($data[$getfield]) && $data[$getfield])
{
$map[$fieldName] = $data[$getfield];
}
return $map;
}
/**
* like查询
* @param [type] $fieldConfig [description]
* @param array $data [description]
* @return [type] [description]
*/
public static function like($fieldConfig ,$data = array())
{
$map = array();
import('ORG.Util.Input');
if (! isset($fieldConfig[self::FIELD_NAME])) return $map;
$fieldName = $fieldConfig[self::FIELD_NAME];
$getfield = self::getField($fieldConfig);
if (isset($data[$getfield]) && $data[$getfield])
{
$map[$fieldName] = array('like' , Input::forSearch($data[$getfield]));
}
return $map;
}
/**
* like查询
* @param [type] $fieldConfig [description]
* @param array $data [description]
* @return [type] [description]
*/
public static function daterange($fieldConfig ,$data = array())
{
$map = array();
if (! isset($fieldConfig[self::FIELD_NAME])) return $map;
$fieldName = $fieldConfig[self::FIELD_NAME];
$getfield = self::getField($fieldConfig);
if (isset($data[$getfield.'_start']) && $data[$getfield.'_start'])
{
$map[$getfield][] = array('EGT' , strtotime($data[$getfield.'_start']));
}
if (isset($data[$getfield.'_end']) && $data[$getfield.'_end'])
{
$map[$getfield][] = array('ELT' , strtotime($data[$getfield.'_end']));
}
return $map;
}
/**
* 获取字段名称
* @param [type] $fieldConfig [description]
* @return [type] [description]
*/
private function getField($fieldConfig)
{
$field = self::FIELD_NAME;
if (isset($fieldConfig[self::VARIABLE]))
{
$field = self::VARIABLE;
}
return $fieldConfig[$field];
}
}
这样就把以前的逻辑,全放到cp.php这个类里面来了。要加什么规则,直接在这个类里面加上就行了。
虽说不是很高深的,但适合就行了。