在我们使用PHPCMS开发一些产品展示类网站的时候,由于分类的多样化,我们需要客户在简短的时间内寻找到自己需要的产品,这样我们就会用到分类的多重筛选,也就是类似京东,淘宝等这么电商网站里面的产品筛选的功能,PHPCMS本身并没有这样的功能,需要我们进行二次开发,当然网上也出现了很多这样的功能,但不知道为什么,按照上面的步骤能实现的时候并不多,在经过一系列的查找和自己测试之后,我自己总结了以下的方法,希望后来者看到之后可以省去很多不必要的麻烦,我会尽可能的详细写出是怎么实现的。 实现的效果在这里就不贴图片了,淘宝,京东上比我做的还好。
首先,要实现这个功能,在建立字段的时候字段的类型必须选择box类型,在是否作为筛选字段的项目里勾选“是”,是否作为搜索条件勾选“是”。
这建立好字段之后,剩下的就是怎么实现这个功能了。咱们需要在PHPCMS的自定义函数库这个文件里编写相应的分类筛选函数,代码如下:
/**
* 通过指定keyid形式显示所有联动菜单
* @param $keyid 菜单主id
* @param $linkageid 联动菜单id,0调用顶级
* @param $modelid 模型id
* @param $fieldname 字段名称
*/
function show_linkage($keyid, $linkageid = 0, $modelid = '', $fieldname='zone') {
$datas = $infos = $array = array();
$keyid = intval($keyid);
$linkageid = intval($linkageid);
//当前菜单id
$field_value = intval($_GET[$fieldname]);
$urlrule = structure_filters_url($fieldname,$array,1,$modelid);
if($keyid == 0) return false;
$datas = getcache($keyid,'linkage');
$infos = $datas['data'];
foreach($infos as $k=>$v){
if($v['parentid']==$field_value){
$array[$k]['name'] = $v['name'];
$array[$k]['value'] = $k;
$array[$k]['url'] = str_replace('{$'.$fieldname.'}',$k,$urlrule);
$array[$k]['menu'] = $field_value == $k ? '<a class="click" style="color:#fff;">'.$v['name'].'</a>' : '<a href='.$array[$k]['url'].'>'.$v['name'].'</a>' ;
}
}
return $array;
}
function structure_filters_url($fieldname,$array=array(),$type = 1,$modelid) {
if(empty($array)) {
$array = $_GET;
} else {
$array = array_merge($_GET,$array);
}
//TODO
$fields = getcache('model_field_'.$modelid,'model');
if(is_array($fields) && !empty($fields)) {
ksort($fields);
foreach ($fields as $_v=>$_k) {
if($_k['filtertype'] || $_k['rangetype']) {
if(strpos(URLRULE,'.html') === FALSE) $urlpars .= '&'.$_v.'={$'.$_v.'}';
else $urlpars .= '-{$'.$_v.'}';
}
}
}
//后期增加伪静态等其他url规则管理,apache伪静态支持9个参数
if(strpos(URLRULE,'.html') === FALSE) $urlrule =APP_PATH.'index.php?m=content&c=index&a=lists&catid={$catid}'.$urlpars.'&page={$page}' ;
else $urlrule =APP_PATH.'list-{$catid}'.$urlpars.'-{$page}.html#wrap';
//根据get传值构造URL
if (is_array($array)) foreach ($array as $_k=>$_v) {
if($_k=='page') $_v=1;
if($type == 1) if($_k==$fieldname) continue;
$_findme[] = '/{\$'.$_k.'}/';
$_replaceme[] = $_v;
}
//type 模式的时候,构造排除该字段名称的正则
if($type==1) $filter = '(?!'.$fieldname.'.)';
$_findme[] = '/{\$'.$filter.'([a-z0-9_]+)}/';
$_replaceme[] = '0';
$urlrule = preg_replace($_findme, $_replaceme, $urlrule);
return $urlrule;
}
/**
* 生成分类信息中的筛选菜单
* @param $field 字段名称
* @param $modelid 模型ID
*/
function filters($field,$modelid,$diyarr = array()) {
$fields = getcache('model_field_'.$modelid,'model');
$options = empty($diyarr) ? explode("\n",$fields[$field]['options']) : $diyarr;
$field_value = intval($_GET[$field]);
foreach($options as $_k) {
$v = explode("|",$_k);
$k = trim($v[1]);
$option[$k]['name'] = $v[0];
$option[$k]['value'] = $k;
$option[$k]['url'] = structure_filters_url($field,array($field=>$k),2,$modelid);
$option[$k]['menu'] = $field_value == $k ? '<a class="click" style="color:#fff;">'.$v[0].'</a>' : '<a href='.$option[$k]['url'].'>'.$v[0].'</a>' ; //这个地方的a标签的class可以改成符合你自己网站的样式,
}
$all['name'] = '全部';//'全部';
$all['url'] = structure_filters_url($field,array($field=>'0'),2,$modelid);
$all['menu'] = $field_value == '' ? '<a class="click" style="color:#fff;">'.$all['name'].'</a>' : '<a href='.$all['url'].'>'.$all['name'].'</a>';
array_push($option,$all);
return $option;
}
把上面的这段代码复制到:extention.func.php这个文件里,在前台调用的时候需要一点点的改动,调用代码如下:
{php $sql = structure_filters_sql($modelid);}
{pc:content action="lists" where="$sql" catid="$catid" modelid="$modelid" num="12" page="$page"}
再调用的时候一定不要忽略了catid和modelid,二者缺其一无法调用。产品分类怎么调用呢?相信大家也看到了,在刚刚添加的函数里面有一个fliters函数,我们使用这个函数来调用已添加的box类型的字段,读取出我们需要进行筛选的分类。代码如下:
{loop filters('fengge',$modelid) $r} //filters('需要调用的字段','字段所在的模型ID')
<li>{$r[menu]}</li>
{/loop}
好了,在进行了如上几个步骤之后,你就会发现前台的分类筛选功能已经可以使用了,这时你是否是发现URL太长太不美观?没关系,假如你的空间支持伪静态的话,就可以把网站的URL调的简单美观。PHPCMS安装包里自带了一个.htaccess文件,直接复制到根目录里就好了。如果是IIS服务器的话,需要httpd.ini文件,转化一下就可以了,现在的IIS7有一个导入规则的功能,可以直接把.htaccess文件转化成web.config文件,这样就实现了伪静态。一定要注意,把你自己添加的box筛选字段也加入到伪静态的规则里,否则是出现一些不必要的错误。
在利用foreach语句循环图片URL,并通过CURL将所有图片进行本地保存的函数时 ,出现了只能采集到一个的问题。现将foreach和CURL结合进行多URL请求的方法进行下总如。
方法1:循环请求
$sr=array(url_1,url_2,url_3);
foreach ($sr as $k=>$v) {
$curlPost=$v.'?f=传入参数';
$ch = curl_init($curlPost) ;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) ; // 获取数据返回
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ; // 在启用 CURLOPT_RETURNTRANSFER 时候将获取数据返回
$data = curl_exec($ch) ;
echo $k.'##:'.$data.'<br>';
}
curl_close($ch);
上面代码需要特别注意的是,curl_close 一定要放在foreach循环结束的外面,如果放在里面的话,就会出现我上面提到的多个IMGURL ,只能采集到一个URL的问题。
方法2:多线程循环
<?php
multi_threads_request($nodes){
$mh = curl_multi_init();
$curl_array = array();
foreach($nodes as $i => $url)
{
$curl_array[$i] = curl_init($url);
curl_setopt($curl_array[$i], CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $curl_array[$i]);
}
$running = NULL;
do {
usleep(10000);
curl_multi_exec($mh,$running);
} while($running > 0);
$res = array();
foreach($nodes as $i => $url)
{
$res[$url] = curl_multi_getcontent($curl_array[$i]);
}
foreach($nodes as $i => $url){
curl_multi_remove_handle($mh, $curl_array[$i]);
}
curl_multi_close($mh);
return $res;
}
print_r(multi_threads_request(array(
'http://www.111cn.net',
'http://qq.111cn.net',
));
这里主要利用curl_multi_init()实现多个url 的请求,不过由于php自身并不支持多线程。所以伪多线程速度也不见得会比单线程快。
XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。现在我们来聊聊XHProf在开发环境中如何测试php性能。以百分之一的概率产生测试数据,尽量不影响正式环境效率。
class XHProf {
// private $XHProfPath = ‘xhprof/’;
private $XHProfPath = ‘/usr/local/apache/htdocs/xhprof/’;
private $applicationName = ‘sias_application’;
private $sampleSize = 100;
private static $enabled = false;
public function XHProf_Start() {
if (mt_rand(1, $this->sampleSize) == 1) {
include_once $this->XHProfPath . ‘xhprof_lib/utils/xhprof_lib.php’;
include_once $this->XHProfPath . ‘xhprof_lib/utils/xhprof_runs.php’;
xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
self::$enabled = true;
}
}
public function XHProf_End() {
if (self::$enabled) {
$XHProfData = xhprof_disable();
$XHProfRuns = new XHProfRuns_Default();
$XHProfRuns->save_run($XHProfData, $this->applicationName);
}
}
}
测试效果:
Overall Summary
Total Incl. Wall Time (microsec): 48,162 microsecs
Total Incl. CPU (microsecs): 32,994 microsecs
Total Incl. MemUse (bytes): 2,773,464 bytes
Total Incl. PeakMemUse (bytes): 2,867,664 bytes
Number of Function Calls: 749
从以下测试结果看出,耗时最多的居然是连接数据库,所以我们来尽量优化数据库。
php CURL函数可以模仿用户进行一些操作,如我们可以模仿用户提交数据也可以模仿用户进行网站访问了,下面我们来介绍利用CURL模拟进行微信接口的GET与POST例子,例子非常的简单就两个大家一起看看.Get提交获取数据
/**
* @desc 获取access_token
* @return String access_token
*/
function getAccessToken(){
$AppId = '1232assad13213123';
$AppSecret = '2312312321adss3123213';
$getUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$AppId.'&secret='.$AppSecret;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $getUrl);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURL_SSLVERSION_SSL, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$data = curl_exec($ch);
$response = json_decode($data);
return $response->access_token;
}
Post提交获取数据
/**
* @desc 实现天气内容回复
*/
public function testWeixin(){
$access_token = $this->getAccessToken();
$customMessageSendUrl = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token;
$description = '今天天气的详细信息(从第三方获取)。';
$url = 'http://weather.com/';
$picurl = 'http://weather.com/';
$postDataArr = array(
'touser'=>'OPENID',
'msgtype'=>'news',
'news'=>array(
'articles'=>array(
'title'=>'当天天气',
'description'=>$description,
'url'=>$url,
'picurl'=>$picurl,
),
),
);
$postJosnData = json_encode($postDataArr);
$ch = curl_init($customMessageSendUrl);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postJosnData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$data = curl_exec($ch);
var_dump($data);
}
例子相对来说比较简单也没有什么好详细分析的了,大家照抄就可以实现我们想要的功能了.
无限分类原理非常的简单就是找到自己上级目录交级递归去操作,然后再找自己的上级直到最上级为止了,这种就可以实现了无限级分类了,下面看个例子。一个非常简单清晰简单的无极限分类范例,带缩进效果,只需查询一次数据表,然后递归遍历结果集,就可以了,要在php中实现栏目缩进显示可以参考一下。
代码如下 | 复制代码 |
$sql = 'select * from cat order by cat_id desc'; function getLevelCat($catlist, $parent_id='0', $html=' ', $level='0'){ |
php无极限分类
短短几行代码,比较清晰,也比较好用,相信对你会有帮助。