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这个类里面来了。要加什么规则,直接在这个类里面加上就行了。

虽说不是很高深的,但适合就行了。

php服务端搜索,功能改进的更多相关文章

  1. Bootstrap插件系列——Bootstrap-table初始化、分页、客户端搜索、服务端搜索

    又好久不写博客,最近项目都是用的bootstrap的样式,不出意外,应该是要在bootstrap的道路上越走越远了,所以下定决心,把bootstrap的插件都好好学学. 昨天写了boostrap-ta ...

  2. Vue.js与 ASP.NET Core 服务端渲染功能整合

    http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...

  3. SuperWebSocket实现服务端和WebSocket4Net实现客户端

    SuperWebSocket实现服务端和WebSocket4Net实现客户端具体实现如下: SuperWebSocket实现服务端 注:本作者是基于vs2019 enterprise版本,所有项目均为 ...

  4. WebSocket——SuperWebSocket实现服务端和客户端

    WebSocket——SuperWebSocket实现服务端和客户端具体实现如下: 注:本作者是基于vs2019 enterprise版本,所有项目均为.Net Framwork4.7版本(因为Web ...

  5. 服务端事件EventSource揭秘

    服务端推 服务端推,指的是由服务器主动的向客户端发送消息(响应).在应用层的HTTP协议实现中,"请求-响应"是一个round trip,它的起点来自客户端,因此在应用层之上无法实 ...

  6. ASP.NET Core 与 Vue.js 服务端渲染

    http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...

  7. Headless Chrome:服务端渲染JS站点的一个方案【上篇】【翻译】

    原文链接:https://developers.google.com/web/tools/puppeteer/articles/ssr 注:由于英文水平有限,没有逐字翻译,可以选择直接阅读原文 tip ...

  8. 实现PHP服务端和c#客户端数据交换

    服务端实现功能1,数据库的访问dbhelper.php包括执行语句返回多行,返回json数据,返回单条记录,返回第一行第一列的整数,返回第一行第一列的浮点数,返回第一行第一列的双精度数,返回第一行第一 ...

  9. Linux下用gSOAP开发Web Service服务端和客户端程序

    网上本有一篇流传甚广的C版本的,我参考来实现,发现有不少问题,现在根据自己的开发经验将其修改,使用无误:另外,补充同样功能的C++版本,我想这个应该更有用,因为能用C++,当然好过受限于C. 1.gS ...

随机推荐

  1. 阅读高翔的RGBD-SLAM博文笔记

    目录 高翔的RGBD-SLAM笔记 前端VO: 后端优化 高翔的RGBD-SLAM笔记 RGBD相机的特点: 使用RGBD相机中的深度这一维信息,以及相机的针孔成像模型,相机的内参,可以将二维点恢复成 ...

  2. C语言结构体(摘抄C语言设计)

    struct Student stu_1;//定义struct Student 类型的变量stu_1 struct Student *p;//定义指向struct Student类型数据的指针变量 p ...

  3. Spark之RDD

    Spark学习之路Spark之RDD 目录 一.RDD的概述 1.1 什么是RDD? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数 ...

  4. windows API下的模板缓冲(stencil buffer)

    在windows API搭建的OpenGL窗口中使用模板缓冲,需要在像素格式描述表中设置stencil buffer位宽为8,这样窗口会自动生成stencil buffer,然后可以在opengl环境 ...

  5. CMS垃圾收集器深入详解

    上一次[https://www.cnblogs.com/webor2006/p/11048407.html]对安全点和安全区进行了理论化的了解,接下来继续对CMS进行其它理论的了解,还是纯理论!!坚持 ...

  6. flask中利用session实现用户记住密码

    “记住密码”的实质,实际上就是把cookie的有效期设置的长一点,当用户没有选择记住密码时,cookie的有效期为会话结束,选择记住密码后,会根据服务器的设置延长cookie的有效期,默认是31天.在 ...

  7. django学习-数据库配置-创建模型

    数据库配置 在mysite/settings.py中,包含了django项目设置的python模块 通常,这个配置文件使用SQLite作为默认数据库.如果你不熟悉数据库,或者只是想尝试下django, ...

  8. Maven 依赖范围 scope 属性详解

    依赖范围就是用来控制依赖与三种 classpath(编译 classpath.测试 classpath.运行 classpath)的关系. 依赖范围(scope) 对于编译 classpath 有效 ...

  9. VMware10新建虚拟机

    1. 新建虚拟机 2. 选择 “典型(推荐)(T)” 安装 3. “稍后安装操作系统”,创建一个空白硬盘 4. 选择 “Linux” 的 “CentOS 64位” 5. 设置 “虚拟机名称” 和 “位 ...

  10. pytest--fixture

    前戏 fixture是在测试函数运行前后,由pytest执行的外壳函数.fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集.配置测试前系统的初始状态.为批量测试提供数据源等 ...