编写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

 

你可能感兴趣的:(PHP)