本文主要讲解了在V9中使用v9自带验证码并且需要使用session的情况下,多种问题的解决。:)。如有问题或者更好的解决办法,希望不吝赐教。

1、前端调用验证码

pc_base::load_sys_class('form', '', 0);{form::checkcode('code_img', '4', '14', 120, 26)}

2、管理端验证码验证
$code = isset($_POST['code']) && trim($_POST['code']) ? trim($_POST['code']) : exit(format_ajax_out_json('-1', '请输入验证码'));
if ($_SESSION['code'] != strtolower($code)) {
exit(format_ajax_out_json('-1', "验证码错误!"));
}

3、结合验证码Session的使用

一)、PHP原生Session

session_start();
//注意$output['data']['area']数据为数组,其他为字符串,原生session能够存储数组
$_SESSION['area'] = $output['data']['area'];
$_SESSION['yhid'] = $output['data']['yhid'];

在需要使用原生session且验证验证码时,验证码从session中是取不出来的:

if (isset($_GET['dosubmit'])) {session_start();$code = isset($_POST['code']) && trim($_POST['code']) ? trim($_POST['code']) : exit(format_ajax_out_json('-1', '请输入验证码'));if ($_SESSION['code'] != strtolower($code)) {exit(format_ajax_out_json('-1', "验证码错误!"));
}//-------------------------省略中间代码-------------------------------//添加session

  //注意$output['data']['area']数据为数组,其他为字符串,原生session能够存储数组
  $_SESSION['area'] = $output['data']['area'];$_SESSION['yhid'] = $output['data']['yhid'];exit(format_ajax_out_json($output['statusCode'], $output));
}

经过分析,session取不出来的原因,是因为v9代码中,存储code的session时,调用的是session_mysql类。

api/checkcode.php:

$session_storage = 'session_'.pc_base::load_config('system','session_storage');
pc_base::load_sys_class($session_storage);

二)、v9  session_mysql

session_mysql.class.php:(v9)

<?php
/***  session mysql 数据库存储类** @copyright            (C) 2005-2010 PHPCMS* @license             http://www.phpcms.cn/license/* @lastmodify         2010-6-8*/
class session_mysql {var $lifetime = 1800;var $db;var $table;
/*** 构造函数* */public function __construct() {$this->db = pc_base::load_model('session_model');$this->lifetime = pc_base::load_config('system','session_ttl');session_set_save_handler(array(&$this,'open'), array(&$this,'close'), array(&$this,'read'), array(&$this,'write'), array(&$this,'destroy'), array(&$this,'gc'));session_start();}
/*** session_set_save_handler  open方法* @param $save_path* @param $session_name* @return true*/public function open($save_path, $session_name) {return true;}
/*** session_set_save_handler  close方法* @return bool*/public function close() {return $this->gc($this->lifetime);}
/*** 读取session_id* session_set_save_handler  read方法* @return string 读取session_id*/public function read($id) {$r = $this->db->get_one(array('sessionid'=>$id), 'data');return $r ? $r['data'] : '';}
/*** 写入session_id 的值* * @param $id session* @param $data 值* @return mixed query 执行结果*/public function write($id, $data) {$uid = isset($_SESSION['userid']) ? $_SESSION['userid'] : 0;$roleid = isset($_SESSION['roleid']) ? $_SESSION['roleid'] : 0;$groupid = isset($_SESSION['groupid']) ? $_SESSION['groupid'] : 0;$m = defined('ROUTE_M') ? ROUTE_M : '';$c = defined('ROUTE_C') ? ROUTE_C : '';$a = defined('ROUTE_A') ? ROUTE_A : '';if(strlen($data) > 255) $data = '';$ip = ip();$sessiondata = array('sessionid'=>$id,'userid'=>$uid,'ip'=>$ip,'lastvisit'=>SYS_TIME,'roleid'=>$roleid,'groupid'=>$groupid,'m'=>$m,'c'=>$c,'a'=>$a,'data'=>$data,);return $this->db->insert($sessiondata, 1, 1);}
/** * 删除指定的session_id* * @param $id session* @return bool*/public function destroy($id) {return $this->db->delete(array('sessionid'=>$id));}
/*** 删除过期的 session* * @param $maxlifetime 存活期时间* @return bool*/public function gc($maxlifetime) {$expiretime = SYS_TIME - $maxlifetime;return $this->db->delete("`lastvisit`<$expiretime");}
}
?>

该session的使用方式:

private function _session_start() {$session_storage = 'session_'.pc_base::load_config('system','session_storage');$this->todo_session = pc_base::load_sys_class($session_storage);
}public function dlsLogin() {$this->_session_start();if (isset($_GET['dosubmit'])) {    $code = isset($_POST['code']) && trim($_POST['code']) ? trim($_POST['code']) : exit(format_ajax_out_json('-1', '请输入验证码'));if ($_SESSION['code'] != strtolower($code)) {exit(format_ajax_out_json('-1', "验证码错误!"));}
  //-------------------------省略中间代码-------------------------------  
  //注意$output['data']['area']数据为数组,其他为字符串,原生session能够存储数组,而session_mysql方法不能存储数组。
      $this->todo_session->write('area',$output['data']['area']);$this->todo_session->write('yhid',$output['data']['yhid']);exit(format_ajax_out_json($output['statusCode'], $output));}
}

  使用该session方式能很好的使用验证码+需要写入session的数据,但是该方法有个弊端。则:无法在session中存储数组。假设,你需要存入session的数据时数组,且数组的大小是不定的,而使用v9自带的session_mysql其实质是将session值存入数据库,在取的时候读取数据库,如果存一个数组在其中,读出来的数据则是一个"Array"字符串。

  经过研究,这里有两种解决方案。

  a、将数据库的字段的类型、大小改变(原本为varchar类型,且只能存储255个字符)。并将数组转换成一个json字符串,并使用session_mysql的方式存储。

  b、使用session_files方式从存储。

三)、v9  session_files

  这里需要注意的是,我们需要实现的目的是既能使用验证码又能使用session,且能用session存储数组。(不建议重新写一套验证码)

  v9  中,除了用数据库存储session还能用文件的方式。

session_files.class.php:

<?php
class session_files {function __construct() {$path = pc_base::load_config('system', 'session_n') > 0 ? pc_base::load_config('system', 'session_n').';'.pc_base::load_config('system', 'session_savepath')  : pc_base::load_config('system', 'session_savepath');ini_set('session.save_handler', 'files');session_save_path($path);session_start();}
}
?>

  由于要使用验证码,这里需要重新写一个api中的checkcode.php并且在form.class.php中添加一个方法。

新建api/checkcode_files.php

<?php
defined('IN_PHPCMS') or exit('No permission resources.'); pc_base::load_sys_class('session_files');
$checkcode = pc_base::load_sys_class('checkcode');
//之后代码省略------------------

form.class.php添加方法

//验证码 session_file存储方式
public static function checkcode_file($id = 'checkcode',$code_len = 4, $font_size = 20, $width = 130, $height = 50, $font = '', $font_color = '', $background = '') {return "<img id='$id' οnclick='this.src=this.src+\"&\"+Math.random()' src='".SITE_PROTOCOL.SITE_URL.WEB_PATH."api.php?op=checkcode_file&code_len=$code_len&font_size=$font_size&width=$width&height=$height&font_color=".urlencode($font_color)."&background=".urlencode($background)."'>";
}

前端调用:

{form::checkcode_file('code_img', '4', '14', 120, 26)}

  使用该方式在存储session读取session时与原生PHP中使用一样,直接使用$_SESSION。使用该方法,既能读出$_SESSION['code']值也能完美的解决在session中存储数组的问题。

========================

by llicat

转载需注明出处:http://www.cnblogs.com/llicat/

转载于:https://www.cnblogs.com/llicat/p/4785234.html

PHPCMS v9 二次开发_验证码结合Session开发相关推荐

  1. phpcms v9二次开发之模型类的应用(1)

    在<phpcms二次开发之模型类model.class.php>中讲到了模型类的建立方法,接下来我讲一下模型类的应用.       前段时间我基于phpcms v9开发了一个足球网.足球网 ...

  2. phpcms v9二次开发及使用中各种问题解决方案(一)

    phpcms v9二次开发及使用中各种问题解决方案(一)模板调用1.内容标签,序号123456789的调用?{pc:contentaction="lists"catid=" ...

  3. phpcms v9 二次开发 前台上传图片

    phpcms v9 二次开发 前台上传图片 1.在模板页,引用 js与css,两个文即可搞定 <script type="text/javascript" src=" ...

  4. Linux下驱动开发_块设备驱动开发(硬件上采用SD卡+SPI协议)

    一.前言 块设备主要为存储设备设计的框架. 在前面章节Linux下驱动开发_块设备驱动开发(内存模拟存储) 里介绍了块设备驱动编写思路,并且利用内存模拟了硬件存储,完成了块设备驱动开发测试.这一篇文章 ...

  5. android应用程序开发_抚顺小程序开发定制找谁,吉林小程序定制

    湖南庚午网络科技有限公司为您详细解读kpuZae抚顺小程序开发定制找谁的相关知识与详情,微信小法式,简称小法式,缩写XCX,英文名Mini Program,是一种不需要#安拆即可使用的应用,它实现了应 ...

  6. 简单Android app开发_如何简单快速开发外卖app?

    如何开发一个外卖app?app开发需要多少钱?随着美团.饿了么的外卖app的发展,对餐饮.生鲜果蔬.超市便利店行业来说,app成为必不可缺少的一部分.与其向第三方交纳一定不开发一个自己的外卖平台.也有 ...

  7. 如果成为一名高级安卓开发_什么是高级开发人员,我如何成为一名开发人员?

    如果成为一名高级安卓开发 Becoming a Senior Developer is something many of us strive for as we continue our code ...

  8. gwt前台开发_为GWT设置开发环境

    gwt前台开发 介绍 这是旨在用Java开发跨平台移动应用程序的系列文章的一部分 . 在此博客文章中,我们将了解GWT是什么,并为GWT设置开发环境. GWT是一个开源开发工具包,用于开发基于浏览器的 ...

  9. java云开发_快速入门云开发

    什么是云开发 这里引用官方的一段描述: 云开发(Tencent CloudBase,TCB)是云端一体化的后端云服务 ,采用 serverless 架构,免去了移动应用构建中繁琐的服务器搭建和运维.同 ...

最新文章

  1. 机器学习算法之决策树
  2. 《HTML5多媒体应用开发》——第2章 HTML5多媒体元素2.1 Web多媒体历史
  3. js获取select选中的内容
  4. 時鐘,天氣預報--js
  5. VBA学习_5:流程控制
  6. Android前端音视频数据接入GB28181平台意义
  7. 图像模糊处理(信息学奥赛一本通-T1128)
  8. python变量和对象的关系_Python变量与对象引用的区别
  9. android的底部弹出框炫酷的样式,Android自定义底部弹出框ButtomDialog
  10. 商业网站建设和运营的四度:Approachability、Usability、 Accessibility 和 Profitability...
  11. Guava学习之Splitter
  12. 怎么快速解决dns被劫持问题?
  13. latex 表格标题分行和居中
  14. SETi的Violeds技术解决方案可帮助阻止德尔塔变异病毒的传播
  15. Android返回上一页面的方式
  16. 从nmn临床研究最新消息背后,我认识到了w+nmn和nmn的区别重要性
  17. linux 下中文字体的支持
  18. python使用BeautifulSoup爬取2345电影网
  19. kotlin核心编程pdf下载_《Kotlin核心编程》 ——1.2.3 简单却不容易
  20. 单片机高级裸机编程(一)-- 数据驱动程序

热门文章

  1. Win32基础知识5 - Win32汇编语言006
  2. 阳光与阴谋:从投资者角度看理财周报-赛迪事件
  3. Leetcode 134. 加油站 解题思路及C++实现
  4. 分支结构||分支循环结构||使用原生js遍历对象
  5. 类型转换与采样 || SMOTE算法
  6. javascript (function(){})()
  7. BAT 批处理命令 - 获取时间并进行自定义年月日、时分秒格式实例演示
  8. oracle数据库impdp导入dmp文件功能演示,imp导入IMP-00038: Could not convert to environment character sets handle问题解决
  9. [学习笔记]matlab
  10. 平方剩余(二次剩余)