我试图在与数据库连接的 php 中创建一个用户类这是我到目前为止编写的类!
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','waw1@law.bau','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 结构。
我的问题是我应该使用登录/注销:
会话和cookie
mysql with table:sessions[uid|session|expire] 和 pcntl_fork 用于清理会话表中的过期会话,称为每次页面重新加载或类似的东西!
我正在考虑使用 ajax 进行登录并刷新
也欢迎任何其他建议。
提前致谢...