url配置頁面:data\config\config.ini.phpphp
<form id="register_form" method="post" action="<?php echo SHOP_SITE_URL;?>/index.php?act=login&op=usersave">
這裏:
SHOP_SITE_URL = "http://localhost/shop"
$layout = layout/home_layout.phphtml
$layout_file = D:/wamp/www/shop/templates/default/layout/home_layout.phpajax
$page_name = registersql
$php_errormsg = $php_errormsg數據庫
$tpl_dir = home/數組
$tpl_file = D:/wamp/www/shop/templates/default/home/register.php緩存
private static function control(){ //two yuming if ($GLOBALS['setting_config']['enabled_subdomain'] == '1' && $_GET['act'] == 'index' && $_GET['op'] == 'index'){ $store_id = subdomain(); if ($store_id > 0) $_GET['act'] = 'show_store'; } $act_file = realpath(BASE_PATH.'/control/'.$_GET['act'].'.php');//BASE_PATH=d:/wamp/www/shop $class_name = $_GET['act'].'Control'; //act = asccode ==> AsccodeControl if (!@include($act_file)){//$act_file = D:\wamp\www\shop\control\seccode.php if (C('debug')) { throw_exception("Base Error: access file isn't exists!"); } else { showMessage('抱歉!您訪問的頁面不存在','','html','error'); } } if (class_exists($class_name)){//載入act_file文件後就能夠檢查類是否存在 $main = new $class_name(); $function = $_GET['op'].'Op'; if (method_exists($main,$function)){//類存在再檢查函數是否存在 $main->$function(); }elseif (method_exists($main,'indexOp')){ $main->indexOp(); }else { $error = "Base Error: function $function not in $class_name!"; throw_exception($error); } }else { $error = "Base Error: class $class_name isn't exists!"; throw_exception($error); } }
function setNcCookie($name, $value, $expire='3600', $path='', $domain='', $secure=false){ if (empty($path)) $path = '/'; if (empty($domain)) $domain = SUBDOMAIN_SUFFIX ? SUBDOMAIN_SUFFIX : ''; $name = defined('COOKIE_PRE') ? COOKIE_PRE.$name : strtoupper(substr(md5(MD5_KEY),0,4)).'_'.$name; $expire = intval($expire)?intval($expire):(intval(SESSION_EXPIRE)?intval(SESSION_EXPIRE):3600); $result = setcookie($name, $value, time()+$expire, $path, $domain, $secure); $_COOKIE[$name] = $value; }
<form id="register_form" method="post" action="<?php echo SHOP_SITE_URL;?>/index.php?act=login&op=usersave">
文件:control/login.php
類: loginControm
方法:usersaveOp
public function usersaveOp() { //重複註冊驗證 if (processClass::islock('reg')){ showDialog(Language::get('nc_common_op_repeat'),'index.php'); } Language::read("home_login_register"); $lang = Language::getLangContent(); $model_member = Model('member'); $model_member->checkloginMember(); $result = chksubmit(true,C('captcha_status_login'),'num'); if ($result !== false){ if ($result === -11){ showDialog($lang['invalid_request']); }elseif ($result === -12){ showDialog($lang['login_usersave_wrong_code']); } } if(C('ucenter_status')) { /** * Ucenter處理 */ $model_ucenter = Model('ucenter'); $uid = $model_ucenter->addUser(trim($_POST['user_name']),trim($_POST['password']),trim($_POST['email'])); if($uid<1) showMessage($lang['login_usersave_regist_fail'],'','html','error'); $register_info['member_id'] = $uid; } $register_info = array(); $register_info['username'] = $_POST['user_name']; $register_info['password'] = $_POST['password']; $register_info['password_confirm'] = $_POST['password_confirm']; $register_info['email'] = $_POST['email']; $member_info = $model_member->register($register_info); if(!isset($member_info['error'])) { $model_member->createSession($member_info); processClass::addprocess('reg'); $this->mergecart(); // cookie中的cart存入數據庫 Model('cart')->mergecart($member_info,$_SESSION['store_id']); // cookie中的瀏覽記錄存入數據庫 Model('goods_browse')->mergebrowse($_SESSION['member_id'],$_SESSION['store_id']); $_POST['ref_url'] = (strstr($_POST['ref_url'],'logout')=== false && !empty($_POST['ref_url']) ? $_POST['ref_url'] : 'index.php?act=member&op=home'); showDialog(str_replace('site_name',C('site_name'),$lang['login_usersave_regist_success_ajax']),$_POST['ref_url'],'succ',$synstr,3); } else { showDialog($member_info['error']); } }
<?php /** * 會員模型 * * * * */ defined('shun_in') or exit('Access Invalid!'); class memberModel extends Model { public function __construct(){ parent::__construct('member'); } /** * 會員詳細信息(查庫) * @param array $condition * @param string $field * @return array */ public function getMemberInfo($condition, $field = '*', $master = false) { return $this->table('member')->field($field)->where($condition)->master($master)->find(); } /** * 取得會員詳細信息(優先查詢緩存) * 若是未找到,則緩存全部字段 * @param int $member_id * @param string $field 須要取得的緩存鍵值, 例如:'*','member_name,member_sex' * @return array */ public function getMemberInfoByID($member_id, $fields = '*') { $member_info = rcache($member_id, 'member', $fields); if (empty($member_info)) { $member_info = $this->getMemberInfo(array('member_id'=>$member_id),'*',true); wcache($member_id, $member_info, 'member'); } return $member_info; } /** * 會員列表 * @param array $condition * @param string $field * @param number $page * @param string $order */ public function getMemberList($condition = array(), $field = '*', $page = 0, $order = 'member_id desc', $limit = '') { return $this->table('member')->where($condition)->page($page)->order($order)->limit($limit)->select(); } /** * 會員數量 * @param array $condition * @return int */ public function getMemberCount($condition) { return $this->table('member')->where($condition)->count(); } /** * 編輯會員 * @param array $condition * @param array $data */ public function editMember($condition, $data) { $update = $this->table('member')->where($condition)->update($data); if ($update && $condition['member_id']) { dcache($condition['member_id'], 'member'); } return $update; } /** * 登陸時建立會話SESSION * * @param array $member_info 會員信息 */ public function createSession($member_info = array(),$reg = false) { if (empty($member_info) || !is_array($member_info)) return ; $_SESSION['is_login'] = '1'; $_SESSION['member_id'] = $member_info['member_id']; $_SESSION['member_name']= $member_info['member_name']; $_SESSION['member_email']= $member_info['member_email']; $_SESSION['is_buy'] = isset($member_info['is_buy']) ? $member_info['is_buy'] : 1; $_SESSION['avatar'] = $member_info['member_avatar']; $seller_info = Model('seller')->getSellerInfo(array('member_id'=>$_SESSION['member_id'])); $_SESSION['store_id'] = $seller_info['store_id']; if (trim($member_info['member_qqopenid'])){ $_SESSION['openid'] = $member_info['member_qqopenid']; } if (trim($member_info['member_sinaopenid'])){ $_SESSION['slast_key']['uid'] = $member_info['member_sinaopenid']; } if (!$reg) { //添加會員積分 $this->addPoint($member_info); //添加會員經驗值 $this->addExppoint($member_info); } if(!empty($member_info['member_login_time'])) { $update_info = array( 'member_login_num'=> ($member_info['member_login_num']+1), 'member_login_time'=> TIMESTAMP, 'member_old_login_time'=> $member_info['member_login_time'], 'member_login_ip'=> getIp(), 'member_old_login_ip'=> $member_info['member_login_ip'] ); $this->editMember(array('member_id'=>$member_info['member_id']),$update_info); } setNcCookie('cart_goods_num','',-3600); } /** * 獲取會員信息 * * @param array $param 會員條件 * @param string $field 顯示字段 * @return array 數組格式的返回結果 */ public function infoMember($param, $field='*') { if (empty($param)) return false; //獲得條件語句 $condition_str = $this->getCondition($param); $param = array(); $param['table'] = 'member'; $param['where'] = $condition_str; $param['field'] = $field; $param['limit'] = 1; $member_list = Db::select($param); $member_info = $member_list[0]; if (intval($member_info['store_id']) > 0){ $param = array(); $param['table'] = 'store'; $param['field'] = 'store_id'; $param['value'] = $member_info['store_id']; $field = 'store_id,store_name,grade_id'; $store_info = Db::getRow($param,$field); if (!empty($store_info) && is_array($store_info)){ $member_info['store_name'] = $store_info['store_name']; $member_info['grade_id'] = $store_info['grade_id']; } } return $member_info; } /** * 註冊 */ public function register($register_info) { // 註冊驗證 $obj_validate = new Validate(); $obj_validate->validateparam = array( array("input"=>$register_info["username"], "require"=>"true", "message"=>'用戶名不能爲空'), array("input"=>$register_info["password"], "require"=>"true", "message"=>'密碼不能爲空'), array("input"=>$register_info["password_confirm"],"require"=>"true", "validator"=>"Compare","operator"=>"==","to"=>$register_info["password"],"message"=>'密碼與確認密碼不相同'), array("input"=>$register_info["email"], "require"=>"true", "validator"=>"email", "message"=>'電子郵件格式不正確'), ); $error = $obj_validate->validate(); if ($error != ''){ return array('error' => $error); } // 驗證用戶名是否重複 $check_member_name = $this->getMemberInfo(array('member_name'=>$register_info['username'])); if(is_array($check_member_name) and count($check_member_name) > 0) { return array('error' => '用戶名已存在'); } // 驗證郵箱是否重複 $check_member_email = $this->getMemberInfo(array('member_email'=>$register_info['email'])); if(is_array($check_member_email) and count($check_member_email)>0) { return array('error' => '郵箱已存在'); } // 會員添加 $member_info = array(); $member_info['member_name'] = $register_info['username']; $member_info['member_passwd'] = $register_info['password']; $member_info['member_email'] = $register_info['email']; $insert_id = $this->addMember($member_info); if($insert_id) { //添加會員積分 if (C('points_isuse')){ Model('points')->savePointsLog('regist',array('pl_memberid'=>$insert_id,'pl_membername'=>$register_info['username']),false); } // 添加默認相冊 $insert['ac_name'] = '買家秀'; $insert['member_id'] = $insert_id; $insert['ac_des'] = '買家秀默認相冊'; $insert['ac_sort'] = 1; $insert['is_default'] = 1; $insert['upload_time'] = TIMESTAMP; $this->table('sns_albumclass')->insert($insert); $member_info['member_id'] = $insert_id; $member_info['is_buy'] = 1; return $member_info; } else { return array('error' => '註冊失敗'); } } /** * 註冊商城會員 * * @param array $param 會員信息 * @return array 數組格式的返回結果 */ public function addMember($param) { if(empty($param)) { return false; } try { $this->beginTransaction(); $member_info = array(); $member_info['member_id'] = $param['member_id']; $member_info['member_name'] = $param['member_name']; $member_info['member_passwd'] = md5(trim($param['member_passwd'])); $member_info['member_email'] = $param['member_email']; $member_info['member_time'] = TIMESTAMP; $member_info['member_login_time'] = TIMESTAMP; $member_info['member_old_login_time'] = TIMESTAMP; $member_info['member_login_ip'] = getIp(); $member_info['member_old_login_ip'] = $member_info['member_login_ip']; $member_info['member_truename'] = $param['member_truename']; $member_info['member_qq'] = $param['member_qq']; $member_info['member_sex'] = $param['member_sex']; $member_info['member_avatar'] = $param['member_avatar']; $member_info['member_qqopenid'] = $param['member_qqopenid']; $member_info['member_qqinfo'] = $param['member_qqinfo']; $member_info['member_sinaopenid'] = $param['member_sinaopenid']; $member_info['member_sinainfo'] = $param['member_sinainfo']; $insert_id = $this->table('member')->insert($member_info); if (!$insert_id) { throw new Exception(); } $insert = $this->addMemberCommon(array('member_id'=>$insert_id)); if (!$insert) { throw new Exception(); } $this->commit(); return $insert_id; } catch (Exception $e) { $this->rollback(); return false; } } /** * 會員登陸檢查 * */ public function checkloginMember() { if($_SESSION['is_login'] == '1') { @header("Location: index.php"); exit(); } } /** * 檢查會員是否容許舉報商品 * */ public function isMemberAllowInform($member_id) { $condition = array(); $condition['member_id'] = $member_id; $member_info = $this->getMemberInfo($condition,'inform_allow'); if(intval($member_info['inform_allow']) === 1) { return true; } else { return false; } } /** * 取單條信息 * @param unknown $condition * @param string $fields */ public function getMemberCommonInfo($condition = array(), $fields = '*') { return $this->table('member_common')->where($condition)->field($fields)->find(); } /** * 插入擴展表信息 * @param unknown $data * @return Ambigous <mixed, boolean, number, unknown, resource> */ public function addMemberCommon($data) { return $this->table('member_common')->insert($data); } /** * 編輯會員擴展表 * @param unknown $data * @param unknown $condition * @return Ambigous <mixed, boolean, number, unknown, resource> */ public function editMemberCommon($data,$condition) { return $this->table('member_common')->where($condition)->update($data); } /** * 添加會員積分 * @param unknown $member_info */ public function addPoint($member_info) { if (!C('points_isuse') || empty($member_info)) return; //一天內只有第一次登陸贈送積分 if(trim(@date('Y-m-d',$member_info['member_login_time'])) == trim(date('Y-m-d'))) return; //加入隊列 $queue_content = array(); $queue_content['member_id'] = $member_info['member_id']; $queue_content['member_name'] = $member_info['member_name']; QueueClient::push('addPoint',$queue_content); } /** * 添加會員經驗值 * @param unknown $member_info */ public function addExppoint($member_info) { if (empty($member_info)) return; //一天內只有第一次登陸贈送經驗值 if(trim(@date('Y-m-d',$member_info['member_login_time'])) == trim(date('Y-m-d'))) return; //加入隊列 $queue_content = array(); $queue_content['member_id'] = $member_info['member_id']; $queue_content['member_name'] = $member_info['member_name']; QueueClient::push('addExppoint',$queue_content); } /** * 取得會員安全級別 * @param unknown $member_info */ public function getMemberSecurityLevel($member_info = array()) { $tmp_level = 0; if ($member_info['member_email_bind'] == '1') { $tmp_level += 1; } if ($member_info['member_mobile_bind'] == '1') { $tmp_level += 1; } if ($member_info['member_paypwd'] != '') { $tmp_level += 1; } return $tmp_level; } /** * 得到會員等級 * @param bool $show_progress 是否計算其當前等級進度 * @param int $exppoints 會員經驗值 * @param array $cur_level 會員當前等級 */ public function getMemberGradeArr($show_progress = false,$exppoints = 0,$cur_level = ''){ $member_grade = C('member_grade')?unserialize(C('member_grade')):array(); //處理會員等級進度 if ($member_grade && $show_progress){ $is_max = false; if ($cur_level === ''){ $cur_gradearr = $this->getOneMemberGrade($exppoints, false, $member_grade); $cur_level = $cur_gradearr['level']; } foreach ($member_grade as $k=>$v){ if ($cur_level == $v['level']){ $v['is_cur'] = true; } $member_grade[$k] = $v; } } return $member_grade; } /** * 將條件數組組合爲SQL語句的條件部分 * * @param array $conditon_array * @return string */ private function getCondition($conditon_array){ $condition_sql = ''; if($conditon_array['member_id'] != '') { $condition_sql .= " and member_id= '" .intval($conditon_array['member_id']). "'"; } if($conditon_array['member_name'] != '') { $condition_sql .= " and member_name='".$conditon_array['member_name']."'"; } if($conditon_array['member_passwd'] != '') { $condition_sql .= " and member_passwd='".$conditon_array['member_passwd']."'"; } //是否容許舉報 if($conditon_array['inform_allow'] != '') { $condition_sql .= " and inform_allow='{$conditon_array['inform_allow']}'"; } //是否容許購買 if($conditon_array['is_buy'] != '') { $condition_sql .= " and is_buy='{$conditon_array['is_buy']}'"; } //是否容許發言 if($conditon_array['is_allowtalk'] != '') { $condition_sql .= " and is_allowtalk='{$conditon_array['is_allowtalk']}'"; } //是否容許登陸 if($conditon_array['member_state'] != '') { $condition_sql .= " and member_state='{$conditon_array['member_state']}'"; } if($conditon_array['friend_list'] != '') { $condition_sql .= " and member_name IN (".$conditon_array['friend_list'].")"; } if($conditon_array['member_email'] != '') { $condition_sql .= " and member_email='".$conditon_array['member_email']."'"; } if($conditon_array['no_member_id'] != '') { $condition_sql .= " and member_id != '".$conditon_array['no_member_id']."'"; } if($conditon_array['like_member_name'] != '') { $condition_sql .= " and member_name like '%".$conditon_array['like_member_name']."%'"; } if($conditon_array['like_member_email'] != '') { $condition_sql .= " and member_email like '%".$conditon_array['like_member_email']."%'"; } if($conditon_array['like_member_truename'] != '') { $condition_sql .= " and member_truename like '%".$conditon_array['like_member_truename']."%'"; } if($conditon_array['in_member_id'] != '') { $condition_sql .= " and member_id IN (".$conditon_array['in_member_id'].")"; } if($conditon_array['in_member_name'] != '') { $condition_sql .= " and member_name IN (".$conditon_array['in_member_name'].")"; } if($conditon_array['member_qqopenid'] != '') { $condition_sql .= " and member_qqopenid = '{$conditon_array['member_qqopenid']}'"; } if($conditon_array['member_sinaopenid'] != '') { $condition_sql .= " and member_sinaopenid = '{$conditon_array['member_sinaopenid']}'"; } return $condition_sql; } /** * 得到某一會員等級 * @param int $exppoints * @param bool $show_progress 是否計算其當前等級進度 * @param array $member_grade 會員等級 */ public function getOneMemberGrade($exppoints,$show_progress = false,$member_grade = array()){ if (!$member_grade){ $member_grade = C('member_grade')?unserialize(C('member_grade')):array(); } if (empty($member_grade)){//若是會員等級設置爲空 $grade_arr['level'] = -1; $grade_arr['level_name'] = '暫無等級'; return $grade_arr; } $exppoints = intval($exppoints); $grade_arr = array(); if ($member_grade){ foreach ($member_grade as $k=>$v){ if($exppoints >= $v['exppoints']){ $grade_arr = $v; } } } //計算提高進度 if ($show_progress == true){ if (intval($grade_arr['level']) >= (count($member_grade) - 1)){//若是已達到頂級會員 $grade_arr['downgrade'] = $grade_arr['level'] - 1;//下一級會員等級 $grade_arr['downgrade_name'] = $member_grade[$grade_arr['downgrade']]['level_name']; $grade_arr['downgrade_exppoints'] = $member_grade[$grade_arr['downgrade']]['exppoints']; $grade_arr['upgrade'] = $grade_arr['level'];//上一級會員等級 $grade_arr['upgrade_name'] = $member_grade[$grade_arr['upgrade']]['level_name']; $grade_arr['upgrade_exppoints'] = $member_grade[$grade_arr['upgrade']]['exppoints']; $grade_arr['less_exppoints'] = 0; $grade_arr['exppoints_rate'] = 100; } else { $grade_arr['downgrade'] = $grade_arr['level'];//下一級會員等級 $grade_arr['downgrade_name'] = $member_grade[$grade_arr['downgrade']]['level_name']; $grade_arr['downgrade_exppoints'] = $member_grade[$grade_arr['downgrade']]['exppoints']; $grade_arr['upgrade'] = $member_grade[$grade_arr['level']+1]['level'];//上一級會員等級 $grade_arr['upgrade_name'] = $member_grade[$grade_arr['upgrade']]['level_name']; $grade_arr['upgrade_exppoints'] = $member_grade[$grade_arr['upgrade']]['exppoints']; $grade_arr['less_exppoints'] = $grade_arr['upgrade_exppoints'] - $exppoints; $grade_arr['exppoints_rate'] = round(($exppoints - $member_grade[$grade_arr['level']]['exppoints'])/($grade_arr['upgrade_exppoints'] - $member_grade[$grade_arr['level']]['exppoints'])*100,2); } } return $grade_arr; } }
9 class Model{ 10 11 protected $name = ''; 12 protected $table_prefix = ''; 13 protected $init_table = null; 14 protected $table_name = ''; 15 protected $options = array(); 16 protected $pk = 'id'; 17 protected $db = null; 18 protected $fields = array(); 19 protected $unoptions = true; //是否清空參數項,默認清除 20 21 public function __construct($table = null){ 22 if (!is_null($table)){ 23 $this->table_name = $table; 24 $this->tableInfo($table); 25 } 26 $this->table_prefix = DBPRE; 27 if (!is_object($this->db)){ 28 $this->db = new ModelDb(); 29 } 30 } 31 32 /** 33 * 刪除表主鍵緩存 34 */ 35 public static function dropTablePkArrayCache() 36 { 37 dkcache('field/_pk'); 38 } 39 40 /** 41 * 生成表結構信息 42 * 43 * @param string $table 44 * @return 45 */ 46 public function tableInfo($table) 47 { 48 if (empty($table)) return false; 49 //只取主鍵,find(2)等自動匹配主鍵時使用 50 51 if (C('cache_open')) { 52 $this->fields = rkcache('field/_pk', __CLASS__ . '::fetchTablePkArray'); 53 } else { 54 if (file_exists(BASE_DATA_PATH.'/cache/fields/_pk.php')){ 55 $this->fields = require(BASE_DATA_PATH.'/cache/fields/_pk.php'); 56 } else { 57 $_pk_array = self::fetchTablePkArray(); 58 F('_pk', $_pk_array, 'cache/fields'); 59 $this->fields = $_pk_array; 60 } 61 } 62 63 return $this->fields[$table]; 64 } 65 66 public static function fetchTablePkArray() 67 { 68 $full_table = Db::showTables(); 69 $_pk_array = array(); 70 $count = strlen(C('tablepre')); 71 foreach ($full_table as $v_table) { 72 $v = array_values($v_table); 73 if (substr($v[0],0,$count) != C('tablepre')) continue; 74 $tb = preg_replace('/^'.C('tablepre').'/', '', $v[0]); 75 $fields = DB::showColumns($tb); 76 foreach ((array)$fields as $k=>$v) { 77 if($v['primary']) { 78 $_pk_array[$tb] = $k;break; 79 } 80 } 81 } 82 return $_pk_array; 83 } 84 85 public function __call($method,$args) { 86 if(in_array(strtolower($method),array('table','order','where','on','limit','having','group','lock','master','distinct','index','attr','key'),true)) { 87 $this->options[strtolower($method)] = $args[0]; 88 if (strtolower($method) == 'table'){ 89 if (strpos($args[0],',') !== false){ 90 $args[0] = explode(',',$args[0]); 91 $this->table_name = ''; 92 foreach ((array)$args[0] as $value) { 93 $this->tableInfo($value); 94 } 95 }else{ 96 $this->table_name = $args[0];$this->fields = array();$this->tableInfo($args[0]); 97 } 98 } 99 return $this; 100 }elseif(in_array(strtolower($method),array('page'),true)){ 101 if ($args[0] == null){ 102 return $this; 103 }elseif(!is_numeric($args[0]) || $args[0] <= 0){ 104 $args[0] = 10; 105 } 106 107 if (is_numeric($args[1]) && $args[1] > 0){ 108 //page(2,30)形式,傳入了每頁顯示數據和總記錄數 109 if ($args[0] > 0){ 110 $this->options[strtolower($method)] = $args[0]; 111 pagecmd('setEachNum', $args[0]); 112 $this->unoptions = false; 113 pagecmd('setTotalNum', $args[1]); 114 return $this; 115 }else{ 116 $args[0] = 10; 117 } 118 } 119 $this->options[strtolower($method)] = $args[0]; 120 pagecmd('setEachNum', $args[0]); 121 $this->unoptions = false; 122 pagecmd('setTotalNum', $this->get_field('COUNT(*) AS nc_count')); 123 return $this; 124 }elseif(in_array(strtolower($method),array('min','max','count','sum','avg'),true)){ 125 $field = isset($args[0])?$args[0]:'*'; 126 return $this->get_field(strtoupper($method).'('.$field.') AS nc_'.$method); 127 }elseif(strtolower($method)=='count1'){ 128 $field = isset($args[0])?$args[0]:'*'; 129 $options['field'] = ('count('.$field.') AS nc_count'); 130 $options = $this->parse_options($options); 131 $options['limit'] = 1; 132 $result = $this->db->select($options); 133 if(!empty($result)) { 134 return reset($result[0]); 135 } 136 }elseif(strtolower(substr($method,0,6))=='getby_') { 137 $field = substr($method,6); 138 $where[$field] = $args[0]; 139 return $this->where($where)->find(); 140 }elseif(strtolower(substr($method,0,7))=='getfby_') { 141 $name = substr($method,7); 142 $where[$name] =$args[0]; 143 //getfby_方法只返回第一個字段值 144 if (strpos($args[1],',') !== false){ 145 $args[1] = substr($args[1],0,strpos($args[1],',')); 146 } 147 return $this->where($where)->get_field($args[1]); 148 }else{ 149 $error = 'Model Error: Function '.$method.' is not exists!'; 150 throw_exception($error); 151 return; 152 } 153 } 154 /** 155 * 查詢 156 * 157 * @param array/int $options 158 * @return null/array 159 */ 160 public function select($options=array()) { 161 if(is_string($options) || is_numeric($options)) { 162 // 默認根據主鍵查詢 163 $pk = $this->get_pk(); 164 if(strpos($options,',')) { 165 $where[$pk] = array('IN',$options); 166 }else{ 167 $where[$pk] = $this->fields[$this->table_name]['_pk_type'] == 'int' ? intval($options) : $options; 168 } 169 $options = array(); 170 $options['where'] = $where; 171 } 172 $options = $this->parse_options($options); 173 if ($options['limit'] !== false) { 174 if (empty($options['where']) && empty($options['limit'])){ 175 //若是無條件,默認檢索30條數據 176 $options['limit'] = 30; 177 }elseif ($options['where'] !== true && empty($options['limit'])){ 178 //若是帶WHERE,但無LIMIT,最多隻檢索1000條記錄 179 $options['limit'] = 1000; 180 } 181 } 182 183 $resultSet = $this->db->select($options); 184 185 if(empty($resultSet)) { 186 return array(); 187 } 188 if ($options['key'] != '' && is_array($resultSet)){ 189 $tmp = array(); 190 foreach ($resultSet as $value) { 191 $tmp[$value[$options['key']]] = $value; 192 } 193 $resultSet = $tmp; 194 } 195 return $resultSet; 196 } 197 198 /** 199 * 取得第N列內容 200 * 201 * @param array/int $options 202 * @return null/array 203 */ 204 public function getfield($col = 1) { 205 if (intval($col)<=1) $col = 1; 206 $options = $this->parse_options(); 207 if (empty($options['where']) && empty($options['limit'])){ 208 //若是無條件,默認檢索30條數據 209 $options['limit'] = 30; 210 }elseif ($options['where'] !== true && empty($options['limit'])){ 211 //若是帶WHERE,但無LIMIT,最多隻檢索1000條記錄 212 $options['limit'] = 1000; 213 } 214 215 $resultSet = $this->db->select($options); 216 if(false === $resultSet) { 217 return false; 218 } 219 if(empty($resultSet)) { 220 return null; 221 } 222 $return = array(); 223 $cols = array_keys($resultSet[0]); 224 foreach ((array)$resultSet as $k => $v) { 225 $return[$k] = $v[$cols[$col-1]]; 226 } 227 return $return; 228 } 229 230 protected function parse_options($options=array()) { 231 if(is_array($options)) $options = array_merge($this->options,$options); 232 if(!isset($options['table'])){ 233 $options['table'] =$this->getTableName(); 234 }elseif(false !== strpos(trim($options['table'],', '),',')){ 235 foreach(explode(',', trim($options['table'],', ')) as $val){ 236 $tmp[] = $this->getTableName($val).' AS `'.$val.'`'; 237 } 238 $options['table'] = implode(',',$tmp); 239 }else{ 240 $options['table'] =$this->getTableName($options['table']); 241 } 242 if ($this->unoptions === true){ 243 $this->options = array(); 244 }else{ 245 $this->unoptions = true; 246 } 247 return $options; 248 } 249 250 public function get_field($field,$sepa=null) { 251 $options['field'] = $field; 252 $options = $this->parse_options($options); 253 if(strpos($field,',')) { // 多字段 254 $resultSet = $this->db->select($options); 255 if(!empty($resultSet)) { 256 $_field = explode(',', $field); 257 $field = array_keys($resultSet[0]); 258 $move = $_field[0]==$_field[1]?false:true; 259 $key = array_shift($field); 260 $key2 = array_shift($field); 261 $cols = array(); 262 $count = count($_field); 263 foreach ($resultSet as $result){ 264 $name = $result[$key]; 265 if($move) { // 刪除鍵值記錄 266 unset($result[$key]); 267 } 268 if(2==$count) { 269 $cols[$name] = $result[$key2]; 270 }else{ 271 $cols[$name] = is_null($sepa)?$result:implode($sepa,$result); 272 } 273 } 274 return $cols; 275 } 276 }else{ 277 $options['limit'] = 1; 278 $result = $this->db->select($options); 279 if(!empty($result)) { 280 return reset($result[0]); 281 } 282 } 283 return null; 284 } 285 286 /** 287 * 返回一條記錄 288 * 289 * @param string/int $options 290 * @return null/array 291 */ 292 public function find($options=null) { 293 if(is_numeric($options) || is_string($options)) { 294 $where[$this->get_pk()] = $options; 295 $options = array(); 296 $options['where'] = $where; 297 }elseif(!empty($options)) { 298 return false; 299 } 300 $options['limit'] = 1; 301 $options = $this->parse_options($options); 302 $result = $this->db->select($options); 303 if(empty($result)) { 304 return array(); 305 } 306 return $result[0]; 307 } 308 /** 309 * 刪除 310 * 311 * @param array $options 312 * @return bool/int 313 */ 314 public function delete($options=array()) { 315 if(is_numeric($options) || is_string($options)) { 316 // 根據主鍵刪除記錄 317 $pk = $this->get_pk(); 318 if(strpos($options,',')) { 319 $where[$pk] = array('IN', $options); 320 }else{ 321 $where[$pk] = $this->fields['_pk_type'] == 'int' ? intval($options) : $options; 322 $pkValue = $options; 323 } 324 $options = array(); 325 $options['where'] = $where; 326 } 327 $options = $this->parse_options($options); 328 $result = $this->db->delete($options); 329 if(false !== $result) { 330 return true; 331 // $data = array(); 332 // if(isset($pkValue)) $data[$pk] = $pkValue; 333 } 334 return $result; 335 } 336 /** 337 * 更新 338 * 339 * @param array $data 340 * @param array $options 341 * @return boolean 342 */ 343 public function update($data='',$options=array()) { 344 if(empty($data)) return false; 345 // 分析表達式 346 $options = $this->parse_options($options); 347 if(!isset($options['where'])) { 348 // 若是存在主鍵,自動做爲更新條件 349 if(isset($data[$this->get_pk()])) { 350 $pk = $this->get_pk(); 351 $where[$pk] = $data[$pk]; 352 $options['where'] = $where; 353 $pkValue = $data[$pk]; 354 unset($data[$pk]); 355 }else{ 356 return false; 357 } 358 } 359 $result = $this->db->update($data,$options); 360 if(false !== $result) { 361 return true; 362 } 363 return $result; 364 } 365 366 /** 367 * 插入 368 * 369 * @param array $data 370 * @param bool $replace 371 * @param array $options 372 * @return mixed int/false 373 */ 374 public function insert($data='', $replace=false, $options=array()) { 375 if(empty($data)) return false; 376 $options = $this->parse_options($options); 377 $result = $this->db->insert($data,$options,$replace); 378 if(false !== $result ) { 379 $insertId = $this->getLastId(); 380 if($insertId) { 381 return $insertId; 382 } 383 } 384 return $result; 385 } 386 387 /** 388 * 批量插入 389 * 390 * @param array $dataList 391 * @param array $options 392 * @param bool $replace 393 * @return boolean 394 */ 395 public function insertAll($dataList,$options=array(),$replace=false){ 396 if(empty($dataList)) return false; 397 // 分析表達式 398 $options = $this->parse_options($options); 399 // 寫入數據到數據庫 400 $result = $this->db->insertAll($dataList,$options,$replace); 401 if(false !== $result ) return true; 402 return $result; 403 } 404 405 /** 406 * 直接SQL查詢,返回查詢結果 407 * 408 * @param string $sql 409 * @return array 410 */ 411 public function query($sql){ 412 return DB::getAll($sql); 413 } 414 415 /** 416 * 執行SQL,用於 更新、寫入、刪除操做 417 * 418 * @param string $sql 419 * @return 420 */ 421 public function execute($sql){ 422 return DB::execute($sql); 423 } 424 425 /** 426 * 開始事務 427 * 428 * @param string $host 429 */ 430 public static function beginTransaction($host = 'master'){ 431 Db::beginTransaction($host); 432 } 433 434 /** 435 * 提交事務 436 * 437 * @param string $host 438 */ 439 public static function commit($host = 'master'){ 440 Db::commit($host); 441 } 442 443 /** 444 * 回滾事務 445 * 446 * @param string $host 447 */ 448 public static function rollback($host = 'master'){ 449 Db::rollback($host); 450 } 451 452 /** 453 * 清空表 454 * 455 * @return boolean 456 */ 457 public function clear(){ 458 if (!$this->table_name && !$this->options['table']) return false; 459 $options = $this->parse_options(); 460 return $this->db->clear($options); 461 } 462 463 /** 464 * 取得表名 465 * 466 * @param string $table 467 * @return string 468 */ 469 protected function getTableName($table = null){ 470 if (is_null($table)){ 471 $return = '`'.$this->table_prefix.$this->table_name.'`'; 472 }else{ 473 $return = '`'.$this->table_prefix.$table.'`'; 474 } 475 return $return; 476 } 477 /** 478 * 取得最後插入的ID 479 * 480 * @return int 481 */ 482 public function getLastId() { 483 return $this->db->getLastId(); 484 } 485 /** 486 * 指定查詢字段 支持字段排除 487 * 488 * @param mixed $field 489 * @param boolean $except 490 * @return Model 491 */ 492 public function field($field,$except=false){ 493 if(true === $field) {// 獲取所有字段 494 $fields = $this->getFields(); 495 $field = $fields?$fields:'*'; 496 }elseif($except) {// 字段排除 497 if(is_string($field)) { 498 $field = explode(',',$field); 499 } 500 $fields = $this->getFields(); 501 $field = $fields?array_diff($fields,$field):$field; 502 } 503 $this->options['field'] = $field; 504 return $this; 505 } 506 /** 507 * 取得數據表字段信息 508 * 509 * @return mixed 510 */ 511 public function getFields(){ 512 if($this->fields) { 513 $fields = $this->fields; 514 unset($fields['_autoinc'],$fields['_pk'],$fields['_type']); 515 return $fields; 516 } 517 return false; 518 } 519 520 /** 521 * 組裝join 522 * 523 * @param string $join 524 * @return Model 525 */ 526 public function join($join) { 527 if (false !== strpos($join,',')){ 528 foreach (explode(',',$join) as $key=>$val) { 529 if (in_array(strtolower($val),array('left','inner','right'))){ 530 $this->options['join'][] = strtoupper($val).' JOIN'; 531 }else{ 532 $this->options['join'][] = 'LEFT JOIN'; 533 } 534 } 535 }elseif (in_array(strtolower($join),array('left','inner','right'))){ 536 $this->options['join'][] = strtoupper($join).' JOIN'; 537 } 538 return $this; 539 } 540 541 /** 542 * 取得主鍵 543 * 544 * @return string 545 */ 546 public function get_pk() { 547 return isset($this->fields[$this->table_name])?$this->fields[$this->table_name]:$this->pk; 548 } 549 550 /** 551 * 檢查非數據字段 552 * 553 * @param array $data 554 * @return array 555 */ 556 protected function chk_field($data) { 557 if(!empty($this->fields[$this->table_name])) { 558 foreach ($data as $key=>$val){ 559 if(!in_array($key,$this->fields[$this->table_name],true)){ 560 unset($data[$key]); 561 } 562 } 563 } 564 return $data; 565 } 566 567 public function setInc($field, $step=1) { 568 return $this->set_field($field,array('exp',$field.'+'.$step)); 569 } 570 571 public function setDec($field,$step=1) { 572 return $this->set_field($field,array('exp',$field.'-'.$step)); 573 } 574 575 public function set_field($field,$value='') { 576 if(is_array($field)) { 577 $data = $field; 578 }else{ 579 $data[$field] = $value; 580 } 581 return $this->update($data); 582 } 583 584 /** 585 * 顯示分頁連接 586 * 587 * @param int $style 分頁風格 588 * @return string 589 */ 590 public function showpage($style = null){ 591 return pagecmd('show',$style); 592 } 593 594 /** 595 * 獲取分頁總數 596 * 597 * @return string 598 */ 599 public function gettotalnum(){ 600 return pagecmd('gettotalnum'); 601 } 602 603 /** 604 * 獲取總頁數 605 * 606 * @return string 607 */ 608 public function gettotalpage(){ 609 return pagecmd('gettotalpage'); 610 } 611 /** 612 * 清空MODEL中的options、table_name屬性 613 * 614 */ 615 public function cls(){ 616 $this->options = array(); 617 $this->table_name = ''; 618 return $this; 619 } 620 621 public function checkActive($host = 'master') { 622 $this->db->checkActive($host); 623 } 624 625 } 626 627 628 /** 629 * 完成模型SQL組裝 630 * 631 */ 632 class ModelDb{ 633 634 protected $comparison = array('eq'=>'=','neq'=>'<>','gt'=>'>','egt'=>'>=','lt'=>'<','elt'=>'<=','notlike'=>'NOT LIKE','like'=>'LIKE','in'=>'IN','not in'=>'NOT IN'); 635 // 查詢表達式 636 protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%INDEX%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%'; 637 638 639 public function select($options=array()) { 640 // static $_cache = array(); 641 $sql = $this->buildSelectSql($options); 642 if ($options['cache'] !== false){ 643 $key = is_string($cache['cache_key']) ? $cache['cache_key'] : md5($sql); 644 if (isset($_cache[$key])){ 645 return $_cache[$key]; 646 } 647 } 648 $result = DB::getAll($sql,($options['lock'] === true || $options['master'] === true || defined('TRANS_MASTER')) ? 'master' : 'slave'); 649 // if ($options['cache'] !== false && !isset($_cache[$key])){ 650 // $_cache[$key] = $result; 651 // } 652 return $result; 653 } 654 655 public function buildSelectSql($options=array()) { 656 if (is_numeric($options['page'])){ 657 $page = pagecmd('obj'); 658 if ($options['limit'] !== 1){ 659 $options['limit'] = $page->getLimitStart().",".$page->getEachNum(); 660 } 661 } 662 $sql = $this->parseSql($this->selectSql,$options); 663 $sql .= $this->parseLock(isset($options['lock'])?$options['lock']:false); 664 return $sql; 665 } 666 667 public function parseSql($sql,$options=array()){ 668 $sql = str_replace( 669 array('%TABLE%','%DISTINCT%','%FIELD%','%JOIN%','%WHERE%','%GROUP%','%HAVING%','%ORDER%','%LIMIT%','%UNION%','%INDEX%'), 670 array( 671 $this->parseTable($options), 672 $this->parseDistinct(isset($options['distinct'])?$options['distinct']:false), 673 $this->parseField(isset($options['field'])?$options['field']:'*'), 674 $this->parseJoin(isset($options['on'])?$options:array()), 675 $this->parseWhere(isset($options['where'])?$options['where']:''), 676 $this->parseGroup(isset($options['group'])?$options['group']:''), 677 $this->parseHaving(isset($options['having'])?$options['having']:''), 678 $this->parseOrder(isset($options['order'])?$options['order']:''), 679 $this->parseLimit(isset($options['limit'])?$options['limit']:''), 680 $this->parseUnion(isset($options['union'])?$options['union']:''), 681 $this->parseIndex(isset($options['index'])?$options['index']:'') 682 ),$sql); 683 return $sql; 684 } 685 686 protected function parseUnion(){ 687 return ''; 688 } 689 690 protected function parseLock($lock=false) { 691 if(!$lock) return ''; 692 return ' FOR UPDATE '; 693 } 694 695 protected function parseIndex($value){ 696 return empty($value) ? '':' USE INDEX ('.$value.') '; 697 } 698 699 protected function parseValue($value) { 700 if(is_string($value) || is_numeric($value)) { 701 $value = '\''.$this->escapeString($value).'\''; 702 }elseif(isset($value[0]) && is_string($value[0]) && strtolower($value[0]) == 'exp'){ 703 $value = $value[1]; 704 }elseif(is_array($value)) { 705 $value = array_map(array($this, 'parseValue'),$value); 706 }elseif(is_null($value)){ 707 $value = 'NULL'; 708 } 709 return $value; 710 } 711 712 protected function parseField($fields) { 713 if(is_string($fields) && strpos($fields,',')) { 714 $fields = explode(',',$fields); 715 } 716 if(is_array($fields)) { 717 //字段別名定義 718 $array = array(); 719 foreach ($fields as $key=>$field){ 720 if(!is_numeric($key)) 721 $array[] = $this->parseKey($key).' AS '.$this->parseKey($field); 722 else 723 $array[] = $this->parseKey($field); 724 } 725 $fieldsStr = implode(',', $array); 726 }elseif(is_string($fields) && !empty($fields)) { 727 $fieldsStr = $this->parseKey($fields); 728 }else{ 729 $fieldsStr = '*'; 730 } 731 return $fieldsStr; 732 } 733 734 protected function parseTable($options) { 735 if ($options['on']) return null; 736 $tables = $options['table']; 737 if(is_array($tables)) {// 別名定義 738 $array = array(); 739 foreach ($tables as $table=>$alias){ 740 if(!is_numeric($table)) 741 $array[] = $this->parseKey($table).' '.$this->parseKey($alias); 742 else 743 $array[] = $this->parseKey($table); 744 } 745 $tables = $array; 746 }elseif(is_string($tables)){ 747 $tables = explode(',',$tables); 748 array_walk($tables, array(&$this, 'parseKey')); 749 // if (strpos($options['table'],',') === false){ 750 // $tables = $options['table'].' AS '.$options['table']; 751 // } 752 // $tables = explode(',',$tables); 753 } 754 755 return implode(',',$tables); 756 } 757 758 protected function parseWhere($where) { 759 $whereStr = ''; 760 if(is_string($where)) { 761 $whereStr = $where; 762 }elseif(is_array($where)){ 763 if(isset($where['_op'])) { 764 // 定義邏輯運算規則 例如 OR XOR AND NOT 765 $operate = ' '.strtoupper($where['_op']).' '; 766 unset($where['_op']); 767 }else{ 768 $operate = ' AND '; 769 } 770 foreach ($where as $key=>$val){ 771 // $whereStr .= '( '; 772 // if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){ 773 // $error = 'Model Error: args '.$key.' is wrong!'; 774 // throw_exception($error); 775 // } 776 // $key = trim($key); 777 // $whereStr .= $this->parseWhereItem($this->parseKey($key),$val); 778 // $whereStr .= ' )'.$operate; 779 $whereStrTemp = ''; 780 if(0===strpos($key,'_')) { 781 // 解析特殊條件表達式 782 // $whereStr .= $this->parseThinkWhere($key,$val); 783 }else{ 784 // 查詢字段的安全過濾 785 if(!preg_match('/^[A-Z_\|\&\-.a-z0-9]+$/',trim($key))){ 786 throw_exception($error); 787 } 788 // 多條件支持 789 $multi = is_array($val) && isset($val['_multi']); 790 $key = trim($key); 791 if(strpos($key,'|')) { // 支持 name|title|nickname 方式定義查詢字段 792 $array = explode('|',$key); 793 $str = array(); 794 foreach ($array as $m=>$k){ 795 $v = $multi?$val[$m]:$val; 796 $str[] = '('.$this->parseWhereItem($this->parseKey($k),$v).')'; 797 } 798 $whereStrTemp .= implode(' OR ',$str); 799 }elseif(strpos($key,'&')){ 800 $array = explode('&',$key); 801 $str = array(); 802 foreach ($array as $m=>$k){ 803 $v = $multi?$val[$m]:$val; 804 $str[] = '('.$this->parseWhereItem($this->parseKey($k),$v).')'; 805 } 806 $whereStrTemp .= implode(' AND ',$str); 807 }else{ 808 $whereStrTemp .= $this->parseWhereItem($this->parseKey($key),$val); 809 } 810 } 811 if(!empty($whereStrTemp)) { 812 $whereStr .= '( '.$whereStrTemp.' )'.$operate; 813 } 814 } 815 $whereStr = substr($whereStr,0,-strlen($operate)); 816 } 817 return empty($whereStr)?'':' WHERE '.$whereStr; 818 } 819 820 // where子單元分析 821 protected function parseWhereItem($key,$val) { 822 $whereStr = ''; 823 if(is_array($val)) { 824 if(is_string($val[0])) { 825 if(preg_match('/^(EQ|NEQ|GT|EGT|LT|ELT|NOTLIKE|LIKE)$/i',$val[0])) { // 比較運算 826 $whereStr .= $key.' '.$this->comparison[strtolower($val[0])].' '.$this->parseValue($val[1]); 827 }elseif('exp'==strtolower($val[0])){ // 使用表達式 828 // $whereStr .= ' ('.$key.' '.$val[1].') '; 829 $whereStr .= $val[1]; 830 }elseif(preg_match('/IN/i',$val[0])){ // IN 運算 831 if(isset($val[2]) && 'exp'==$val[2]) { 832 $whereStr .= $key.' '.strtoupper($val[0]).' '.$val[1]; 833 }else{ 834 if (empty($val[1])){ 835 $whereStr .= $key.' '.strtoupper($val[0]).'(\'\')'; 836 }elseif(is_string($val[1]) || is_numeric($val[1])) { 837 $val[1] = explode(',',$val[1]); 838 $zone = implode(',',$this->parseValue($val[1])); 839 $whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')'; 840 }elseif(is_array($val[1])){ 841 $zone = implode(',',$this->parseValue($val[1])); 842 $whereStr .= $key.' '.strtoupper($val[0]).' ('.$zone.')'; 843 } 844 } 845 }elseif(preg_match('/BETWEEN/i',$val[0])){ 846 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; 847 if($data[0] && $data[1]) { 848 $whereStr .= ' ('.$key.' '.strtoupper($val[0]).' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]).' )'; 849 } elseif ($data[0]) { 850 $whereStr .= $key.' '.$this->comparison['gt'].' '.$this->parseValue($data[0]); 851 } elseif ($data[1]) { 852 $whereStr .= $key.' '.$this->comparison['lt'].' '.$this->parseValue($data[1]); 853 } 854 }elseif(preg_match('/TIME/i',$val[0])){ 855 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; 856 if($data[0] && $data[1]) { 857 $whereStr .= ' ('.$key.' BETWEEN '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1] + 86400 -1).' )'; 858 } elseif ($data[0]) { 859 $whereStr .= $key.' '.$this->comparison['gt'].' '.$this->parseValue($data[0]); 860 } elseif ($data[1]) { 861 $whereStr .= $key.' '.$this->comparison['lt'].' '.$this->parseValue($data[1] + 86400); 862 } 863 }else{ 864 $error = 'Model Error: args '.$val[0].' is error!'; 865 throw_exception($error); 866 } 867 }else { 868 $count = count($val); 869 if(in_array(strtoupper(trim($val[$count-1])),array('AND','OR','XOR'))) { 870 $rule = strtoupper(trim($val[$count-1])); 871 $count = $count -1; 872 }else{ 873 $rule = 'AND'; 874 } 875 for($i=0;$i<$count;$i++) { 876 if (is_array($val[$i])){ 877 if (is_array($val[$i][1])){ 878 $data = implode(',',$val[$i][1]); 879 }else{ 880 $data = $val[$i][1]; 881 } 882 }else{ 883 $data = $val[$i]; 884 } 885 if('exp'==strtolower($val[$i][0])) { 886 $whereStr .= '('.$key.' '.$data.') '.$rule.' '; 887 }else{ 888 $op = is_array($val[$i])?$this->comparison[strtolower($val[$i][0])]:'='; 889 if(preg_match('/IN/i',$op)){ 890 $whereStr .= '('.$key.' '.$op.' ('.$this->parseValue($data).')) '.$rule.' '; 891 }else{ 892 $whereStr .= '('.$key.' '.$op.' '.$this->parseValue($data).') '.$rule.' '; 893 } 894 895 } 896 } 897 $whereStr = substr($whereStr,0,-4); 898 } 899 }else { 900 $whereStr .= $key.' = '.$this->parseValue($val); 901 } 902 return $whereStr; 903 } 904 905 protected function parseLimit($limit) { 906 return !empty($limit)? ' LIMIT '.$limit.' ':''; 907 } 908 909 protected function parseJoin($options = array()) { 910 $joinStr = ''; 911 if (false === strpos($options['table'],',')) return null; 912 $table = explode(',',$options['table']); 913 $on = explode(',',$options['on']); 914 $join = $options['join']; 915 $joinStr .= $table[0]; 916 for($i=0;$i<(count($table)-1);$i++){ 917 $joinStr .= ' '.($join[$i]?$join[$i]:'LEFT JOIN').' '.$table[$i+1].' ON '.($on[$i]?$on[$i]:''); 918 } 919 return $joinStr; 920 } 921 922 public function delete($options=array()) { 923 $sql = 'DELETE '.$this->parseAttr($options).' FROM ' 924 .$this->parseTable($options) 925 .$this->parseWhere(isset($options['where'])?$options['where']:'') 926 .$this->parseOrder(isset($options['order'])?$options['order']:'') 927 .$this->parseLimit(isset($options['limit'])?$options['limit']:''); 928 if (stripos($sql,'where') === false && $options['where'] !== true){ 929 //防止條件傳錯,刪除全部記錄 930 return false; 931 } 932 return DB::execute($sql); 933 } 934 935 public function update($data,$options) { 936 $sql = 'UPDATE ' 937 .$this->parseAttr($options) 938 .$this->parseTable($options) 939 .$this->parseSet($data) 940 .$this->parseWhere(isset($options['where'])?$options['where']:'') 941 .$this->parseOrder(isset($options['order'])?$options['order']:'') 942 .$this->parseLimit(isset($options['limit'])?$options['limit']:''); 943 if (stripos($sql,'where') === false && $options['where'] !== true){ 944 //防止條件傳錯,更新全部記錄 945 return false; 946 } 947 return DB::execute($sql); 948 } 949 950 public function parseAttr($options){ 951 if (isset($options['attr'])){ 952 if (in_array(isset($options['attr']),array('LOW_PRIORITY','QUICK','IGNORE','HIGH_PRIORITY','SQL_CACHE','SQL_NO_CACHE'))){ 953 return $options['attr'].' '; 954 } 955 }else{ 956 return ''; 957 } 958 } 959 960 public function lockAttr($options){ 961 if (isset($options['attr'])){ 962 if (in_array($options['attr'],array('FOR UPDATE'))){ 963 return ' '.$options['attr'].' '; 964 } 965 }else{ 966 return ''; 967 } 968 } 969 970 /** 971 * 清空表 972 * 973 * @param array $options 974 * @return boolean 975 */ 976 public function clear($options){ 977 $sql = 'TRUNCATE TABLE '.$this->parseTable($options); 978 return DB::execute($sql); 979 } 980 public function insert($data,$options=array(),$replace=false) { 981 $values = $fields = array(); 982 foreach ($data as $key=>$val){ 983 $value = $this->parseValue($val); 984 if(is_scalar($value)) { 985 $values[] = $value; 986 $fields[] = $this->parseKey($key); 987 } 988 } 989 $sql = ($replace?'REPLACE ':'INSERT ').$this->parseAttr($options).' INTO '.$this->parseTable($options).' ('.implode(',', $fields).') VALUES ('.implode(',', $values).')'; 990 return DB::execute($sql); 991 } 992 993 public function getLastId() { 994 return DB::getLastId(); 995 } 996 997 /** 998 * 批量插入 999 * 1000 * @param unknown_type $datas 1001 * @param unknown_type $options 1002 * @param unknown_type $replace 1003 * @return unknown 1004 */ 1005 public function insertAll($datas,$options=array(),$replace=false) { 1006 if(!is_array($datas[0])) return false; 1007 $fields = array_keys($datas[0]); 1008 array_walk($fields, array($this, 'parseKey')); 1009 $values = array(); 1010 foreach ($datas as $data){ 1011 $value = array(); 1012 foreach ($data as $key=>$val){ 1013 $val = $this->parseValue($val); 1014 if(is_scalar($val)) { 1015 $value[] = $val; 1016 } 1017 } 1018 $values[] = '('.implode(',', $value).')'; 1019 } 1020 $sql = ($replace?'REPLACE':'INSERT').' INTO '.$this->parseTable($options).' ('.implode(',', $fields).') VALUES '.implode(',',$values); 1021 return DB::execute($sql); 1022 } 1023 1024 protected function parseOrder($order) { 1025 if(is_array($order)) { 1026 $array = array(); 1027 foreach ($order as $key=>$val){ 1028 if(is_numeric($key)) { 1029 $array[] = $this->parseKey($val); 1030 }else{ 1031 $array[] = $this->parseKey($key).' '.$val; 1032 } 1033 } 1034 $order = implode(',',$array); 1035 } 1036 return !empty($order)? ' ORDER BY '.$order:''; 1037 } 1038 1039 protected function parseGroup($group) { 1040 return !empty($group)? ' GROUP BY '.$group:''; 1041 } 1042 1043 protected function parseHaving($having) { 1044 return !empty($having)? ' HAVING '.$having:''; 1045 } 1046 1047 protected function parseDistinct($distinct) { 1048 return !empty($distinct)? ' DISTINCT '.$distinct.',' :''; 1049 } 1050 1051 protected function parseSet($data) { 1052 foreach ($data as $key=>$val){ 1053 $value = $this->parseValue($val); 1054 if(is_scalar($value)) 1055 $set[] = $this->parseKey($key).'='.$value; 1056 } 1057 return ' SET '.implode(',',$set); 1058 } 1059 1060 public function escapeString($str) { 1061 $str = addslashes(stripslashes($str));//從新加斜線,防止從數據庫直接讀取出錯 1062 return $str; 1063 } 1064 1065 protected function parseKey(&$key) { 1066 return $key; 1067 } 1068 1069 public function checkActive($host) { 1070 Db::ping($host); 1071 } 1072 } 1073 ?>