2013-03-27 53 views
1

登录/退出/到期进出口试图创建数据库 这里连接在PHP用户类是我的课我至今写的!PHP - 与会话,Cookie或数据库

class db { 
    private function conn(){ 
     set_exception_handler(create_function('$e','db::db_error($e);')); 
     return new PDO('mysql:host=localhost;dbname=mydb','admin','pass'); //Persistent connection without closing conn: ....$user, $pass, array(PDO::ATTR_PERSISTENT=>true)); 
    } 
    public static function db_error($log){ 
     $mylog=$_SERVER['REMOTE_ADDR']." - ".$_SERVER['PHP_SELF']." - ".date("d/m/Y h:i:s")." - ".$log; 
     $showlog=$_SERVER['REMOTE_ADDR']." - Internal Server Error!"; 
     // $mylog > error information log on db or file! 
     exit($showlog); 
    } 
    public function dbconstruction(){ 
     $pdo=$this->conn(); 
     $pdo->query("CREATE TABLE IF NOT EXISTS `users` (
       `uid` text NOT NULL, 
       `sid` text NOT NULL, 
       `did` text NOT NULL, 
       `username` text NOT NULL, 
       `password` text NOT NULL, 
       `fullname` text NOT NULL, 
       `email` text NOT NULL, 
       `birthday` text NOT NULL, 
       `expire` text NOT NULL 
      ) DEFAULT CHARSET=latin1;"); 
     $pdo->query("CREATE TABLE IF NOT EXISTS `unverified` (
       `uid` text NOT NULL, 
       `token` text NOT NULL, 
       `expire` text NOT NULL 
      ) DEFAULT CHARSET=latin1;"); 
     $pdo->query("CREATE TABLE IF NOT EXISTS `sessions` (
       `uid` text NOT NULL, 
       `session` text NOT NULL, 
       `expire` text NOT NULL 
      ) DEFAULT CHARSET=latin1;"); 
     $pdo=null; 
     return true; 
    } 
    public function send($a,$t){ // usage: $db->send(array('username'=>'boss'),'users'); 
     if(empty($a)||count($a)<1){return false;} 
     $keys=array_keys($a); 
     $keys2=array_keys($a); 
     foreach($keys2 as &$k){$k=':'.$k;} // ":key" 
     $params=array_combine($keys2,array_values($a)); 
     $st=$this->conn()->prepare("INSERT INTO `$t`(".(count($keys)>1?implode(",",$keys):$keys[0]).") VALUES (".(count($keys2)>1?implode(",",$keys2):$keys2[0]).")"); 
     $st->execute($params); 
     if($st){$st=null;return true;} 
     $st=null; 
     return false; 
    } 
    public function receive($a,$t){ // usage: $db->receive(array('username'=>'boss'),'users'); 
     if(empty($a)||count($a)<1){return false;} 
     $keys=array_keys($a); 
     $keys2=array_keys($a); 
     foreach($keys as &$k){$k=$k.' = :'.$k;} // "key = :key" 
     foreach($keys2 as &$k){$k=':'.$k;} // ":key" 
     $params=array_combine($keys2,array_values($a)); 
     $st=$this->conn()->prepare("SELECT * FROM $t WHERE ".(count($keys)>1?implode(" AND ",$keys):$keys[0])); 
     $st->execute($params); 
     $result=$st->fetchAll(); 
     $st=null; 
     return $result; 
    } 
    public function remove($a,$t){ // usage: $db->remove(array('token'=>'boss'),'unverified'); 
     if(empty($a)||count($a)<1){return false;} 
     $keys=array_keys($a); 
     $keys2=array_keys($a); 
     foreach($keys as &$k){$k=$k.' = :'.$k;} // "key = :key" 
     foreach($keys2 as &$k){$k=':'.$k;} // ":key" 
     $params=array_combine($keys2,array_values($a)); 
     $st=$this->conn()->prepare("DELETE FROM $t WHERE ".(count($keys)>1?implode(" AND ",$keys):$keys[0]));//DELETE FROM `unverified` WHERE token = 'asd' 
     $st->execute($params); 
     $c=$st->rowCount(); 
     if($c>0){$st=null;return true;} 
     $st=null; 
     return false; 
    } 
    public function update($a,$b,$t){ // usage: $db->update(array('password'=>'boss'),array('uid'=>$uid),'users'); // update password where uid=$uid 
     if(empty($a)||count($a)<1||empty($b)||count($b)<1){return false;} 
     $a_keys=array_keys($a); 
     foreach($a_keys as &$k){$k=$k.'=?';} // "key=?" 
     $set_params=array_values($a);  
     $b_keys=array_keys($b); 
     foreach($b_keys as &$k){$k=$k.'=?';} // "key=?" 
     $where_params=array_values($b); 
     $params=array_merge($set_params,$where_params); 
     $set=(count($a_keys)>1?implode(", ",$a_keys):$a_keys[0]); 
     $where=(count($b_keys)>1?implode(" AND ",$b_keys):$b_keys[0]); 
     $st=$this->conn()->prepare("UPDATE $t SET $set WHERE $where"); 
     $st->execute($params); 
     $c=$st->rowCount(); 
     if($c>0){$st=null;return true;} 
     $st=null; 
     return false; 
    } 
    public function check($a,$t){ // usage: $db->check(array('username'=>'boss'),'users'); 
     if(empty($a)||empty($t)||count($a)<1){return false;} 
     $keys=array_keys($a); 
     $keys2=array_keys($a); 
     foreach($keys as &$k){$k=$k.' = :'.$k;} // "key = :key" 
     foreach($keys2 as &$k){$k=':'.$k;} // ":key" 
     $params=array_combine($keys2,array_values($a)); 
     $st=$this->conn()->prepare("SELECT * FROM $t WHERE ".(count($keys)>1?implode(" AND ",$keys):$keys[0])); 
     $st->execute($params); 
     $c=$st->rowCount(); 
     if($c>0){$st=null;return true;} 
     $st=null; 
     return false; 
    } 
} 

//$user = new user; 
//echo $user->verifyemail('boss','2391cc263bdf0fcf6e69872608ee05fdde7dbdc4'); 
//echo $user->login('1234567','boss'); 
//echo $user->register('boss','ad min','1234567','[email protected]','1955'); 
//$db = new db; 
//echo $db->dbconstruction(); 
//print_r( $db->update(array('username'=>'thoi'),array('username'=>'asd'),'users') ); 


class user { // uid | sid | did | username | password | fullname | email | birthday 
    public $settings=array(
       'expire_cookie'=>'4m', // cookie expire time 
       'expire_account'=>'3M', // inactivity account expire time 
       'expire_verification'=>'1d' // unverified email account expire time 
      ); 
    public function register($username,$fullname,$password,$email,$birthday){ // to add : if is expired register it 
     if(empty($username)||empty($fullname)||empty($password)||empty($email)||empty($birthday) 
      ||!preg_match('/[a-z0-9\-_]{4,31}/i',$username) 
      ||!preg_match('/[a-z\s]{5,64}/i',$fullname) 
      ||!preg_match('/(.){7,25}/i',$password) 
      ||!preg_match('/([\w\-\._]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})/i',$email) 
      ||!preg_match('/(19|20)([0-9]{2})/i',$birthday) 
     ){return false;} 
     $username=strtolower($username); 
     $email=strtolower($email); 
     $db=new db; 
     if($db->check(array('username'=>$username),'users')===true){return 'registered username!';} 
     if($db->check(array('email'=>$email),'users')){return 'registered email!';} 
     $shadow = $this->shadow($password); 
     $id=$this->gen(md5($username.$fullname.$password.$email.$birthday.$shadow)); // $id['uid'] , $id['sid'] , $id['did'] 
     $register=$db->send(array('uid'=>$id['uid'],'sid'=>$id['sid'],'did'=>$id['did'],'username'=>$username,'password'=>$shadow,'fullname'=>$fullname,'email'=>$email,'birthday'=>$birthday,'expire'=>time_ahead($this->settings['expire_account'])),'users'); 
     if($register){ 
      $expire_verify=time_ahead($this->settings['expire_verification']); 
      $db->send(array('uid'=>$id['uid'],'token'=>$id['token'],'expire'=>$expire_verify),'unverified'); 
      // SEND EMAIL WITH url http://site.com/?u=$uid&t=$token OR http://site.com/verify to input manually token 
      return 'Success registration! Time to verify is until '.date('d/M/Y H:i:s',$expire_verify); 
     } 
     return false; 
    } 
    public function login($password,$user){ 
     if(empty($password)||empty($user)){return false;} 
     $user=strtolower($user); 
     $db=new db; 
     $user_check=$db->check(array('username'=>$user),'users'); 
     $email_check=$db->check(array('email'=>$user),'users'); 
     if(!$user_check&&!$email_check){return 'Invalid username/email';} 
     $user_details=$db->receive(array(($user_check?'username':'email')=>$user),'users')[0]; 
     if($this->pass_verify($password,$user_details['password'])){ //********** set some cookies with expire time_ahead('2h') 
      $uid=$user_details['uid']; 
      if($user_details['expire']<time()){ 
       if(!$this->remove_user($uid)){return 'int err!';} 
       return 'Account has been expired on '.date('d M Y h:i',$user_details['expire']).'! Click HERE to register!'; 
      }else{ 
       $db->update(array('expire'=>time_ahead($this->settings['expire_account'])),array('uid'=>$uid),'users'); 
       $session=$this->gen(md5($uid.'18.1"8-18\'18'))['session']; //$_SERVER["SSL_SESSION_ID"] if $ssl true 
       $expire=time_ahead($this->settings['expire_cookie']); 


       /* 
       session_set_cookie_params ($lifetime , $path , $domain , $secure , $httponly ); 
       setcookie('auth','sdaasdasa',time()+'120',WWW,DOMAIN,$GLOBALS['ssl'],true); 

       define('DOMAIN','example.com',true); 
       define('WWW',$_SERVER['DOCUMENT_ROOT'],true); 
       $ssl=((isset($_SERVER['HTTPS'])&&$_SERVER['HTTPS']=='on')?true:false); 

       session_set_cookie_params (20 , WWW , DOMAIN , $GLOBALS['ssl'] , true ); 
       session_name('auth'); 
       session_start(); 
       */ 
       // setcookie('auth',$session,$expire); <---- (-_-)! 


       if($db->send(array('uid'=>$uid,'session'=>$session,'expire'=>$expire),'sessions')){ 
        print 'session set!'; 
       } 
      } 
      $unverified=$db->check(array('uid'=>$uid),'unverified');//check if is in unverifided db 
      if($unverified){ 
       $expire_verify=$db->receive(array('uid'=>$uid),'unverified')[0]['expire']; 
       if($expire_verify<time()){ //expired verification via email! 
        if(!$this->remove_user($uid)){return 'int err!';} 
        return 'Verification has expired! Account has been deleted :('; 
       }else{ 
        //$rem=($expire_verify-time()); 
        return 'success login! Unverified account! Remaining time to verify your account is until '.date('d/M/Y H:i:s',$expire_verify).' !!!'; 
       } 
      }else{ 
       return 'success login! Verified account :)'; 
      } 
      return false; 
     }else{ 
      return 'invalid password!'; 
     } 
     return false; 
    } 
    public function verifyemail($user,$token){ 
     if(empty($token)||empty($user)){return false;} 
     $user=strtolower($user); 
     $db=new db; 
     $user_check=$db->check(array('username'=>$user),'users'); 
     $email_check=$db->check(array('email'=>$user),'users'); 
     if($user_check||$email_check){ 
      $uid=$db->receive(array(($user_check?'username':'email')=>$user),'users')[0]['uid']; 
      if(!$db->check(array('uid'=>$uid),'unverified')){return 'Already verified!';} 
      if($db->check(array('token'=>$token),'unverified')){ 
       $db->remove(array('token'=>$token),'unverified'); 
       return 'Verified successfully.'; 
      }else{return 'invalid token!';} 
     }else{return 'invalid user!';} 
     return false; 
    } 
    public function remove_user($uid){ 
     if(!empty($uid)){ 
      $db=new db; 
      $db->remove(array('uid'=>$uid),'users'); 
      $db->remove(array('uid'=>$uid),'unverified'); 
      return true; 
     } 
     return false; 
    } 
    public function gen($params){ // generate ids , USAGE gen('user123123123')['did'] 
     $a = $params.$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_HOST'].$_SERVER['HTTP_USER_AGENT']; 
     $r = array(
      'sid' => strtolower(sha1(uniqid(md5($a.time())))) , // secret id 
      'uid' => strtolower(sha1(md5(uniqid($a.time())))) , // public id 
      'did' => strtolower(sha1(md5(uniqid($a).time()))) , // download id 
      'token' => strtolower(sha1(md5(uniqid($a).(time()*29.06)))) , // token id for unverified accounts 
      'session' => strtolower(sha1(md5(uniqid($a).(time()*19.91)))) // login session id 
     ); 
     return $r; 
    } 
    private function shadow($i){ // usage shadow('mypass') 
     $s='';for($n=0;$n<16;$n++){$s.=chr(rand(1,128));} 
     $s='$1$'.md5($s).'$'; 
     return crypt($i,$s); 
    } 
    private function pass_verify($pass,$hash){ // usage if($this->pass_verify('Zmypass',$s)){echo 'yes';}else{echo 'no';} 
     return ((crypt($pass,$hash)==$hash)?true:false); 
    } 
} 

function time_ahead($t,$c=true){ 
    if(preg_match('/(\d+)([y|M|d|h|m|s])/',$t,$ti)){ 
     switch($ti[2]){//1year=365.242144days <-maya says so 
      case'y':$r=60*60*24*30.43684991666667*12*$ti[1];break; 
      case'M':$r=60*60*24*30.43684991666667*$ti[1];break; 
      case'd':$r=60*60*24*$ti[1];break; 
      case'h':$r=60*60*$ti[1];break; 
      case'm':$r=60*$ti[1];break; 
      case's':$r=$ti[1];break; 
     } 
     return ($c?time()+$r:$r); 
    } 
    return false; 
} 

你可以在dbconstruct func中看到db结构里面的代码。

我的问题是我应该使用的登录/注销:

  • 会议和饼干

  • 的MySQL与表:会话[UID |会议|过期]与pcntl_fork清理过期会话内部会话表每次调用页面重新加载或类似的东西!

即时通讯思想使得登录使用Ajax与刷新

任何其他建议也欢迎。
在此先感谢...

回答

1

我的建议是:使用会话。

会话仅使用1个Cookie:PHPSESSID。所有会话数据都存储在服务器端(因此不可篡改)。

使用session_set_save_handler重写PHP在哪里存储它的会话数据。让它将数据存储在MySQL表中。

在会话表中没有uid作为字段。即使未经身份验证的客人也可以进行会话。 uid是会话数据的一部分。而不是uid你会想要sess_id,即。会话的ID。另一个原因是,一个用户可以有两会,你不希望这些干涉,因为这会破坏你做出有关会议是如何工作的设想。

expire是好的,用它来实现垃圾收集的回调。

辅修:考虑使用替代utf8_general_cilatin1