工做日誌:

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 ?>
相關文章
相關標籤/搜索