【问题标题】:Does CodeIgniter support named query binding?CodeIgniter 是否支持命名查询绑定?
【发布时间】:2012-07-16 23:52:31
【问题描述】:

我查看了 CI 的手册,发现它支持这种查询绑定:

$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this->db->query($sql, array(3, 'live', 'Rick')); 

不过我更喜欢 PDO 风格:

$sql = "SELECT * FROM some_table WHERE id = :id AND status = :status  AND author = :author";

通过这种方式绑定可以更灵活,顺序无关紧要。

CI 是否支持这种绑定?

【问题讨论】:

    标签: php sql codeigniter


    【解决方案1】:

    默认情况下 Codeigniter 不支持命名绑定。

    因为命名绑定的可读性更高,所以我“破解”了数据库类,以便它接受命名或未命名的绑定。

    如果有人对“黑客”感兴趣,请告诉我,我会上传到某个地方

    【讨论】:

    • 我也有兴趣看到这个。
    【解决方案2】:

    我扩展了 CI_Model 以通过名称执行参数查询。

    class MY_Model extends CI_Model{
    
        protected $db;
        private $sql;
        private $bind_marker;
    
        public function __construct() {
            $this->load->database($this->setConfigCliente());
            $CI =& get_instance();
            $this->db = $CI->db;
            $this->bind_marker = $this->db->bind_marker;
            parent::__construct();
        }
    
    
        public function setConfigCliente() {
    //        $db['hostname'] = 'localhost';
    //        $db['dsn'] = "mysql:host=localhost;dbname=".$this->getDbName();
            $db['hostname'] = "mysql:host=localhost;dbname=".$this->getDbName();
            $db['username'] = 'root';
            $db['password'] = 'pass#######';
            $db['database'] = $this->getDbName();
    //        $db['dbdriver'] = 'mysqli';
            $db['dbdriver'] = 'pdo';
            $db['dbprefix'] = '';
            $db['pconnect'] = TRUE;
            $db['db_debug'] = TRUE;
            $db['cache_on'] = FALSE;
            $db['cachedir'] = '';
            $db['char_set'] = 'utf8';
            $db['dbcollat'] = 'utf8_general_ci';
            $db['swap_pre'] = '';
            $db['autoinit'] = TRUE;
            $db['stricton'] = FALSE;
    
            return $db;
    
    
        }
    
        final protected function query($sql, $bind=false, $return_object = true){
            $this->sql = $sql;
            if(is_array($bind) and count($bind)>0){
                $bind = $this->process_bind($bind);
            }
            $query = $this->db->query($this->sql, $bind, $return_object);
            return $query;
        }
    
        private function process_bind($bind){
            $bindOrder = null;
            $bindList = null;
    
            $pattern = "/[^']:[A-Za-z0-9_]+[^']/";
            $preg = preg_match_all($pattern, $this->sql, $matches, PREG_OFFSET_CAPTURE);
            if($preg !== 0 and $preg !== false){
                foreach($matches[0] as $key=>$val){
                    $bindOrder[$key] = trim($val[0]);
                }
                foreach($bindOrder as $field){
                    $this->sql = str_replace($field, $this->bind_marker, $this->sql);
                    $bindList[] = $bind[$field];
                }
            }else{
                $bindList = $bind;
            }
    
            return $bindList;
        }
    
        private function getDbName(){
            /*
             * LISTA DE NOME DE BANCO SEGUNDO O SUBDOMINIO.
             */
    
            //AMIG
            $sub['amig']['dbName'] = 'amig';
            $sub['10']['dbName'] = 'amig';
    
            //SISTEMA.ARKSYS
            $sub['sistema']['dbName'] = 'sistema';
            $sub['code']['dbName'] = 'sistema';
    
    
            $host = explode('.', $_SERVER['HTTP_HOST']);
            $subDom = $host[0];
            if(isset($sub[$subDom])){
                return $sub[$subDom]['dbName'];
            }else{
                return null;
            }
    
        }
    
    
    }
    

    示例用法:

    class Login_usuarios extends MY_Model {
    
        public function __construct() {
            parent::__construct();
        }
    
        public function get_login_dados($email, $senha) {
    
            $sql = "
            SELECT
                u.usu_id,
                u.usu_nome,
                u.usu_alterar_senha,
                u.usu_situacao,
                (SELECT log_data FROM log_usuario_acesso l WHERE l.usu_id = u.usu_id ORDER BY l.log_data DESC LIMIT 1) AS data_ultimo_acesso,
                (SELECT
                    p.par_nome_fantasia
                FROM 
                    sys_parametros p
                WHERE
                    p.par_id = 1) as par_nome_fantasia
            FROM 
                cad_usuarios u
            WHERE
                u.usu_email = :usu_email
            AND
                u.usu_senha = :usu_senha
            AND
                u.usu_situacao <> :usu_situacao";
    
            $bind[':usu_senha'] = $senha;
            $bind[':usu_email'] = $email;
            $bind[':usu_situacao'] = 'Descartado';
    
            $query = $this->query($sql, $bind);
    
            return $query->result_array();
        }
    }
    

    仅由“:”标识的参数

    【讨论】:

      【解决方案3】:

      您可以使用命名查询绑定。让我举个例子。

      $sql = 'SELECT @column FROM @table LIMIT @limit';
      $this->db->bind('@column', 'username');
      $this->db->bind('@table', 'users');
      $this->db->bind('@limit', 10);
      $query = $this->db->query($sql);  
      

      query binding

      【讨论】:

      • 实际上它不起作用。您自己在 CI 中尝试过吗?
      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 2012-09-26
      • 2013-10-08
      • 1970-01-01
      相关资源
      最近更新 更多