0

我有一个通过spl_autoload_register. 它很好地包含和初始化类,但是当涉及到我的数据库类时存在问题。

这是连接类(DbConnect.php):

   static $db_host =  '';
   static $db_user =  '';
   static $db_pswd =  '';
   static $db_name =  '';

   class database_DbConnect
     {
        private static $instance;
        public $db;

        /* Singleton */
        public static function singleton(){ 
            if (!isset(self::$instance)){ 
                $c              = __CLASS__; 
                self::$instance = new $c; 
            } 
            return self::$instance; 
        } 

        public function __clone() { trigger_error('Cloning not allowed.', E_USER_ERROR); }         
        public function __wakeup() { trigger_error('Unserializing is not allowed.', E_USER_ERROR); }

        /* Database initialisation */
        private function __construct()
        { 
            global $db_host, $db_user, $db_pswd, $db_name; 

            try { 
                @$this->db = new mysqli($db_host, $db_user, $db_pswd, $db_name); 

                if(mysqli_connect_error()){ 
                    throw new Exception('Database error:' . mysqli_connect_error()); 
                }
            } 
            catch( Exception $e ) { 
                print $e->getMessage(); 
            } 

            $this->db->set_charset('utf8'); 
        } 

        function __destruct() { $this->db->close(); } 

     }

和数据库类(Db.php):

   require_once('DbConnect.php');

   class database_Db
     {
         public $db;
         public $stmt = NULL;
         public $error;

         public function __construct(){
            $DB_connect       = database_DbConnect::singleton();
            $this->db = $DB_connect->db;
         }

         function __destruct(){
            if($this->stmt != NULL) $this->stmt->close();
         }

         function __call($func, $arg_array){

            switch($func){
                case 'num_rows':
                    if($arg_array != NULL){
                        $this->execute_query($arg_array);
                        $num_rows = $this->execute_result_info();

                        return $num_rows['num_rows'];
                    }

                    $result = $this->execute_num_rows();
                    return $result;
                break;
                case 'insert_id':
                    if($arg_array != NULL){
                        $this->execute_query($arg_array);
                        $num_rows = $this->execute_result_info();

                        return $num_rows['insert_id'];
                    }

                    $result = $this->execute_num_rows();
                    return $result;
                break;
                case 'query':
                    $this->execute_query($arg_array);
                    $result = $this->execute_result_array();
                    return $result;
                break;
            }

         }

         function __get($v){
            $num_rows = $this->execute_result_info();
            return $num_rows[$v];
         }

         private function execute_query($arg_array = NULL){
            //determine the types of arguments 

            $sql_query=array_shift($arg_array); // the first element is returned to sql_query and then removed 

            $types = null;

            foreach ($arg_array as $v) 
                { 
                switch ($v) 
                    { 
                    case is_string($v): 
                        $types.='s'; 

                        break; 

                    case is_int($v): 
                        $types.='i'; 

                        break; 

                    case is_double($v): 
                        $types.='d'; 

                        break; 
                    } 
                } 

            // prepare the query 
            print mysqli_connect_error(); 
            $this->stmt = $this->db->prepare($sql_query);

            // binding parameters if has any 
            try 
                { 

                $bind = null;

                if (isset($arg_array[0])) 
                    { 
                    array_unshift($arg_array, $types); 
                    $bind= call_user_func_array(array($this->stmt,'bind_param'),$this->makeValuesReferenced($arg_array)); 
                    }
                    else {
                        $this->has_arguments = false;
                    } 

                if ($bind) 
                    { 
                    $time_start=microtime(true); 
                    $this->stmt->execute(); 
                    $this->stmt->store_result(); 
                    $time_end=microtime(true); 
                    $time    =$time_end - $time_start; 
                    /*$this->log[]=array 
                        ( 
                        "query" => $sql_query, 
                        "time"  => $time 
                        ); */
                    } 
                else 
                    { 
                    throw new Exception('Binding error:' . $this->db->error); 
                    } 
                } 
            catch( Exception $e ) 
                { 
                print $e->getMessage(); 
                } 
            } 

        private function execute_result_info() 
            { 
            if ($this->stmt->affected_rows > 0) 
                { 
                $num_rows=$this->stmt->affected_rows; 
                } 
            else 
                { 
                $num_rows=$this->stmt->num_rows(); 
                } 

            $result['num_rows'] =$num_rows; 
            $result['insert_id']=$this->stmt->insert_id; 

            return $result; 
            } 

        private function execute_result_array() 
            {

            $result_fields  =   array();
            $result         =   array();

            try 
                { 
                if ($this->stmt->error) 
                    { 
                    throw new Exception('MySQLi STMT error:' . $this->stmt->error); 
                    } 

                $result_metadata=@$this->stmt->result_metadata(); 
                } 
            catch( Exception $e ) 
                { 
                print $e->getMessage(); 
                } 

            if (is_object($result_metadata)) 
                { 
                while ($field=$result_metadata->fetch_field()) 
                    { 
                    array_unshift($result_fields, $field->name); 
                    $params[]=&$row[$field->name]; 
                    } 

                call_user_func_array(array($this->stmt,'bind_result'),$params); 

                while ($this->stmt->fetch()) 
                    { 
                    $c = array();
                    foreach ($row as $key => $val) 
                        { 
                        $c[$key]=$val; 

                        } 

                    $result[]=$c; 
                    } 

                return $result; 
                } 
            elseif ($this->stmt->errno == 0) 
                { 
                return true; 
                } 
            else 
                { 
                return $this->stmt->errno; 
                } 
            }

        private function makeValuesReferenced($arr){
            $refs = array();
            foreach($arr as $key => $value)
                $refs[$key] = &$arr[$key];
            return $refs;
        }


     }

初始化类工作正常,但每当我进行数据库查询时,它都会失败:

$markerQuery = "SELECT ID, lat, lng, title FROM profiles WHERE lat <> ? AND lng <> ? ";
$markerResult = $Database->query($markerQuery,'','');

我收到以下错误:

警告:call_user_func_array() 期望参数 1 是有效的回调,第一个数组成员不是 Db.php 第 114 行中的有效类名或对象

绑定错误:未选择数据库

注意:尝试在第 169 行获取 Db.php 中非对象的属性

4

1 回答 1

0

该错误非常明确。在

call_user_func_array(array($this->stmt,'bind_result'),$params);

该变量$this->stmt不是有效的回调(这意味着它不是一个类)。做一个var_dump()或那个变量,你会发现原因。

于 2012-07-17T00:52:23.707 回答