zoukankan      html  css  js  c++  java
  • PHPCMS v9 二次开发_验证码结合Session开发

    本文主要讲解了在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' onclick='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/

  • 相关阅读:
    感悟
    业务员如何听懂采购要吃回扣的暗语或者动作?
    回扣应该怎么给——某人的经验
    采购回扣的六种主要方式以及控制方法
    跟曹操学做事
    销售话术,一说就能“套”人,总有一款适合你
    感悟
    创业公司CEO:在公司猝死之前,我先猝死了!
    Python--实例变量
    Python--发送邮件
  • 原文地址:https://www.cnblogs.com/llicat/p/4785234.html
Copyright © 2011-2022 走看看