编写php拓展实例--slime项目(用户登录会话类)

 

    最近公司换了yaf框架,突然对用c实现php拓展感兴趣了,如果一个功能已经很稳定很成熟而且用的地方很多,那么我们就可以尝试用拓展实现(不一定每种情况都可以写成拓展),写成拓展后就不用每次用都包含一下,工具类直接随php启动加载进内存里。

    我这次是把用户会话加密类写成了php的拓展,用户类是基于des加密的,主要实现了,

  1. isLogin //判断是否登录
  2. setLogin //就是种个加密的cookie
  3. getUid
  4. getUsername 

我给这个项目起名slime(史莱姆),勇者斗恶龙里的小怪,黏黏的。。。。。。

ok,先来看下php的实现,因为我们是php -> c,所以先看下php的实现,其实就是很普通用户类

 1 <?php
 2 class Session_DES
 3 {
 4     var $key;
 5     var $iv; //偏移量
 6     
 7     function Session_DES( $key="AAAAAAAA", $iv="BBBBBBBB") {
 8     //key长度8例如:1234abcd
 9         $this->key = $key;
10         if( $iv == "" ) {
11             $this->iv = $key; //默认以$key 作为 iv
12         } else {
13             $this->iv = $iv; //mcrypt_create_iv ( mcrypt_get_block_size (MCRYPT_DES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM );
14         }
15     }
16     
17     function encrypt($str) {
18     //加密,返回大写十六进制字符串
19         $size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC );
20         $str = $this->pkcs5Pad ( $str, $size );
21         return strtoupper( bin2hex( mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv ) ) );
22     }
23     
24     function decrypt($str) {
25     //解密
26         $strBin = $this->hex2bin( strtolower( $str ) );
27         $str = mcrypt_cbc( MCRYPT_DES, $this->key, $strBin, MCRYPT_DECRYPT, $this->iv );
28         $str = $this->pkcs5Unpad( $str );
29         return $str;
30     }
31     
32     function hex2bin($hexData) {
33         $binData = "";
34         for($i = 0; $i < strlen ( $hexData ); $i += 2) {
35             $binData .= chr ( hexdec ( substr ( $hexData, $i, 2 ) ) );
36         }
37         return $binData;
38     }
39 
40     function pkcs5Pad($text, $blocksize) {
41         $pad = $blocksize - (strlen ( $text ) % $blocksize);
42         return $text . str_repeat ( chr ( $pad ), $pad );
43     }
44     
45     function pkcs5Unpad($text) {
46         $pad = ord ( $text {strlen ( $text ) - 1} );
47         if ($pad > strlen ( $text ))
48             return false;
49         if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad)
50             return false;
51         return substr ( $text, 0, - 1 * $pad );
52     }    
53 }

再来看Session_User

 

  1 <?php
  2 define ('BACK_AUTH_NAME','xxxx'); //用到的cookie名
  3 class Session_User { 
  4     static $obj;
  5     private $uid;
  6     private $username;
  7     private $chineseName;
  8     public $auth_name = BACK_AUTH_NAME;
  9     private $login_url = null;
 10     public $domain = null;
 11     
 12     private function  __construct($login_url = null, $domain = null){
 13         $host = $_SERVER["HTTP_HOST"];
 14         if (!$login_url) {
 15             $this->login_url = "http://{$host}/login";
 16         }
 17         else {
 18             $this->login_url = $login_url;
 19         }
 20         
 21         if (!$domain) {
 22             $domain = $_SERVER["SERVER_NAME"];
 23             $this->domain = $domain;
 24         }
 25         
 26         if (empty ( $_COOKIE [$this->auth_name] )) {
 27             return;
 28         }
 29         
 30         list ( $uid, $username, $ua, $tm, $chineseName ) = @$this->decodeAuth ($_COOKIE [$this->auth_name]);
 31 
 32         
 33         //ua检验
 34         if (empty ( $uid ) || $ua !== md5($_SERVER ['HTTP_USER_AGENT'])) {
 35             return;
 36         }
 37 
 38         //TODO:过期时间检验
 39         
 40         $this->uid = $uid;
 41         $this->username = $username;
 42         $this->chineseName = $chineseName;
 43     }
 44     
 45     static public function instance($login_url = null, $domain = null){
 46         if(self::$obj)
 47             return self::$obj;
 48         else{
 49             self::$obj = new Session_User($login_url, $domain);
 50         }
 51         return self::$obj;
 52     }
 53 
 54     
 55     /**
 56      * 用户是否登陆
 57      * */
 58     public function isLogin(){
 59         if(! empty($this->uid))
 60             return true; 
 61         else
 62             return false;
 63     }
 64     /**
 65      * 
 66      * 跳转到登录页面
 67      * @param unknown_type $forward
 68      * @param unknown_type $exit
 69      */
 70     public function requireLogin($forward = '', $exit = true){
 71         if(! $this->isLogin()){
 72             if($forward === null)
 73             {
 74                 header("location: " . $this->login_url);
 75                 
 76             }
 77             else
 78             {
 79                 if(empty($forward))
 80                 {
 81                     $forward = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
 82                 }
 83                 $forward = urlencode($forward);
 84                 header("location: ". $this->login_url . "?forward=$forward");
 85             }
 86             if($exit)
 87                 exit;
 88         }
 89     }
 90     /**
 91      * 
 92      *设置登录状态
 93      * @param unknown_type $uid
 94      * @param unknown_type $username
 95      * @param unknown_type $ua
 96      * @param unknown_type $outtime
 97      */
 98     
 99     public function setLogin($uid, $username, $ua = null,$outtime = null, $chineseName = null){
100         if(empty($ua)){
101             $ua = $_SERVER['HTTP_USER_AGENT'];
102         }
103         
104         $str = $this->encodeAuth($uid, $username, $ua, $chineseName);
105         setcookie($this->auth_name,urlencode($str),$outtime,'/',$this->domain);
106     }
107     /**
108      * 用户退出
109       */
110     public function setLogout(){
111         setcookie($this->auth_name,'',-1,'/',$this->domain);
112     }
113     
114     public function __get($key){
115         if('uid' == $key){
116             return $this->uid;
117         }elseif ('username' == $key) {
118             return $this->username;
119         }elseif ('chineseName' == $key) {
120             return $this->chineseName;
121         }
122         return ;
123     }
124     
125     public  function getUid(){
126         return $this->uid;
127     }    
128     
129     public function getUserName(){
130         return $this->username;
131     }    
132     
133     public function getChineseName(){
134         return $this->chineseName;
135     }
136 
137     /**
138      * 生成加密的登陆cookie
139      */
140     private function  encodeAuth($uid,$username,$ua,$chineseName=null){
141         $tm = time();
142         $ua = md5($ua);
143         $info = "$uid\t$username\t$ua\t$tm\t$chineseName";
144         $des = new Session_DES();
145         $str = $des->encrypt($info);
146         return $str;
147     }
148 
149     /**
150      * 解析加密cookie 
151      */
152     private function decodeAuth($str){
153         $des = new Session_DES();
154         $info = explode("\t",@$des->decrypt($str));
155         if(is_array($info)){
156             return $info;
157         }else{
158             return array();
159         }
160     }
161     
162     public function auth($controller,$action)
163     {
164         if(!in_array($controller,$conArr)){
165             return false;
166         }
167         if(!in_array($action,$actArr)){
168             return false;
169         }
170         return true;
171     }
172 }
View Code

结合上面两段代码,分离出来其实得到的会话类(常常做的就是把一样的的跟不一样的分离出来),只需要3个变量两个是des用到的iv偏移量,key加密秘钥,跟cookie名,然后我们就可以写我们的拓展了,其中踩到了很多坑,一些makefile,config.w4等小语法,lib依赖,总之还是学到了很多

代码地址:https://github.com/lietdai/ldclass

 

posted @ 2014-04-12 13:08  l4wl137  阅读(1362)  评论(0编辑  收藏  举报