当前位置 : 主页 > 网络编程 > PHP >

php 将sql结构拆分

来源:互联网 收集:自由互联 发布时间:2021-06-28
将sql结构拆分 ['table1'], "db1" = [], ]; //需要转化为大写的表 public static $table_big = ["AuthItemChild", "AuthItem", "AuthAssignment"]; public static $not_params = [ "db1" = [ "table1" = [""], ] ]; public function __construc
将sql结构拆分
  ['table1'],
            "db1" => [],
        ];

        //需要转化为大写的表
    public static $table_big = ["AuthItemChild", "AuthItem", "AuthAssignment"];
    public static $not_params
                             = [
            "db1" => [
                "table1"              => [""],
            ]
        ];

    public function __construct($db, $sql)
    {
        $this->database = $db;
        $this->old_sql  = $sql;
        $this->sql      = str_replace('`', "", strtolower($sql));
        $this->db       = Yii::app()->$db;
        $this->commend  = $this->db->createCommand();
    }

    public function strNpos($str, $find, $n)
    {
        $pos_val = 0;
        for ($i = 1; $i <= $n; $i++) {
            $pos     = strpos($str, $find);
            $str     = substr($str, $pos + 1);
            $pos_val = $pos + $pos_val + 1;
        }
        return $pos_val - 1;
    }

    public function getChildrenVal($sql)
    {
        $children = false;
        preg_match('/(s*(select)/i', $sql, $children_select);
        if ($children_select) {
            $select_pos   = strpos($sql, $children_select[0]);
            $children_all = substr($sql, $select_pos);
            $count        = substr_count($children_all, "(");
            if ($count == 1) {
                $end      = $this->strNpos($children_all, ")", 1);
                $children = substr($children_all, 0, $end + 1);
            } else {
                for ($i = 2; $i <= $count; $i++) {
                    $pos = $this->strNpos($children_all, "(", $i);
                    $r   = substr($children_all, 0, $pos + 1);
                    if (substr_count($r, ")") == ($i - 1)) {
                        $end      = $this->strNpos($children_all, ")", $i - 1);
                        $children = substr($children_all, 0, $end + 1);
                        break;
                    }
                }
                if ($children == false) {
                    $end      = $this->strNpos($children_all, ")", $count + 1);
                    $children = substr($children_all, 0, $end);
                }
            }
        }
        return $children;
    }


    //sql 拆解
    public function explainSql()
    {
        $sql      = $this->sql;
        $children = $this->getChildrenVal($sql);
        if ($children) {
            $children_data = $this->getChildrenData(trim(trim($children, ")"), "("));
            $sql           = str_replace($children, "(" . $children_data . ")", $sql);
        }
        $sql_from = explode("|", preg_replace('/from/', "|", $sql));
        if (count($sql_from) < 2) {
            $this->error = "查询错误";
        } else {
            //CString::echof($sql_from);exit;
            $sql_from[1]             = $this->explainLimit($sql_from[1]);
            $this->select            = str_replace("select", "", $sql_from[0]);
            $sql_from_where_array    = explode("|", preg_replace('/where/', "|", $sql_from[1]));
            $from                    = explode("|", preg_replace(['/(left|right)/', '/(join)/'], ["", "|"], $sql_from_where_array[0]));
            $this->where             = isset($sql_from_where_array[1]) ? $sql_from_where_array[1] : false;
            $this->table             = $this->formChange(array_shift($from));
            $this->join_string_array = $from;
        }
    }

    //大写表替换
    public function formChange($table)
    {
        $tab = self::$table_big;
        foreach ($tab as $v) {
            $table = preg_replace('/(' . $v . ')/i', $v, $table);
        }
        return $table;
    }

    /**
     * @desc 拆分limit  和 order by
     */
    public function explainLimit($sql)
    {
        $order_match = '/(order)s+(by)s+w+s*(?
 
  (desc|asc)?)(s*,s*w+)*s*k
  
   ?/'; preg_match($order_match, $sql, $order); if (count($order)) { $this->order = preg_replace('/(order)s+(by)/', "", $order[0]); $sql = preg_replace($order_match, "", $sql); } preg_match('/(limit)s+(d+)/', $sql, $limit); if (count($limit)) { $this->limit = preg_replace('/(limit)/', "", $limit[0]); $sql = preg_replace('/(limit)s+(d+)/', "", $sql); } $group_match = '/(group)s+(by)s+(w+)(s*,s*w+)*/'; preg_match($group_match, $sql, $group); if (count($group)) { $this->group = preg_replace('/(group)s+(by)/', "", $group[0]); $sql = preg_replace($group_match, "", $sql); } preg_match('/(having).*/', $sql, $having); if ($having) { $this->having = str_replace("having", "", $having[0]); $sql = str_replace($having[0], "", $sql); } return $sql; } public function joinToArray() { if ($this->join_string_array) { foreach ($this->join_string_array as $val) { if (trim($val)) { $this->join_array[] = explode("on", $val); } } } } //数据库检测 public function checkDb() { if (in_array($this->database, self::$db_array) == false) { $this->error = $this->database . "数据库没有权限"; } } //from 检测 public function checkTable() { $not_table = self::$not_db_table[$this->database]; $table = $this->getTable($this->table); if (in_array($table, $not_table)) { $this->error = $this->table . "表无权限查询"; } if ($this->join_array) { foreach ($this->join_array as $val) { $table = $this->getTable(trim($val[0])); $table = $this->getTable($table); if (in_array($table, $not_table)) { $this->error = $this->table . "表无权限查询"; } } } } //数据校验 public function checkAuth() { $this->checkDb(); $this->checkTable(); } //获取表名 public function getTable($table) { $table = str_replace('``', "", $table); preg_match("/S+/", $table, $select_table); return $select_table[0]; } public function getNotParams($table) { return isset(self::$not_params[$this->database][$table]) ? self::$not_params[$this->database][$table] : []; } //字段过滤 public function checkParams($data) { //table $table = $this->getTable($this->table); if ($table) { $now_params = $this->getNotParams($table); //关联表 if ($this->join_array) { foreach ($this->join_array as $val) { $table = $this->getTable(trim($val[0])); $params = $this->getNotParams($table); if ($params) { $now_params = array_merge($now_params, $params); } } } foreach ($data as $i => $detail) { if (isset($detail['id']) == false) { $data[$i]['id'] = ($this->select_page - 1) * $this->select_limit + 1 + $i; //$data[$i]['id'] = $i; } foreach ($detail as $key => $val) { if ($now_params) { foreach ($now_params as $not_val) { if ($key == $not_val) { unset($data[$i][$key]); } } } } } } $file_array = []; if ($this->select_page >= 2) { $file_array = array_fill(0, ($this->select_page - 1) * $this->select_limit, ["id" => 1]); } return array_merge($file_array, $data); } /** * @desc 获取子查询数据 */ public function getChildrenData($sql) { $return = ""; try { $offset = 0; while (true) { $base = new ZSelectSql($this->database, $sql); $base->explainSql(); //$base = clone $base_new; if ($base->table) $base->commend->from("{$base->table}"); if ($base->where) $base->commend->Where($base->where); if ($base->join_array) { foreach ($base->join_array as $val) { $base->commend->join(trim($val[0]), trim($val[1])); } } if ($base->group) $base->commend->group = $base->group; if ($base->select) $base->commend->select = $base->select; if ($base->having) $base->commend->having = $base->having; $base->commend->offset = $offset; $base->commend->limit = 1000; //CString::echof($base->commend->getText()); $data = $base->commend->queryAll(); if (empty($data) || (isset($data[0]) && empty($data[0]))) break; $offset = $offset + 1000; //CString::echof($data); foreach ($data as $children_val) { $children_val = array_values($children_val); $return = $return . $children_val[0] . ","; } } } catch (Exception $e) { //CString::echof($e->getMessage());exit; } return trim($return, ","); } //数据查询 public function search() { $count = 0; $data = []; $this->explainSql(); if ($this->error == false) $this->checkAuth(); if ($this->error == false) $this->joinToArray(); if ($this->error == false) { try { if ($this->table) $this->commend->from("{$this->table}"); if ($this->where) $this->commend->andWhere($this->where); if ($this->join_array) { foreach ($this->join_array as $val) { $this->commend->join(trim($val[0]), trim($val[1])); } } if ($this->order) $this->commend->order = $this->order; if ($this->group) $this->commend->group = $this->group; if ($this->select) $this->commend->select = $this->select; if ($this->having) $this->commend->having = $this->having; //查询总条数 $count = $this->getCount(); //若是总数大于分页数 if ($count >= $this->select_limit) { $offset = 0; if (isset($_GET['page'])) { $this->select_page = $_GET['page']; $offset = $_GET['page'] - 1; } if (($offset + 1) * $this->select_limit > $count) { $this->commend->limit = abs($offset * $this->select_limit - $count); } else { $this->commend->limit = $this->select_limit; } $this->commend->offset = $offset * $this->select_limit; } else { if (isset($_GET['page'])) { $this->commend->offset = ($_GET['page'] - 1) * $this->select_limit; } if ($this->limit) $this->commend->limit = $this->limit; } //CString::echof($this->commend->_query);exit; $data = $this->commend->queryAll(); if ($data) $data = $this->checkParams($data); } catch (Exception $e) { try { $table_sql = $this->getNotTab($this->sql); if (empty($old_sql)) { $data = $this->db->createCommand($this->old_sql)->queryAll(); $data = $this->checkParams($data); $this->select_limit = 1000; } else { $this->error = $table_sql[0] . "无查询权限"; } } catch (Exception $e) { $this->error = $e->getMessage(); } } } return new ArrayDataProvider($data, array( 'id' => 'id', "self_count" => $count, 'pagination' => array( 'pageSize' => $this->select_limit, 'pageVar' => 'page' ), )); } public function getNotTab($sql) { $r = ""; foreach (self::$not_db_table as $val) { foreach ($val as $v) { $r = $r . "|" . $v; } } $r = trim($r, "|"); preg_match('/(' . $r . ')/', $sql, $oll); return $oll; } //获取总条数 public function getCount() { $commend = clone $this->commend; $old = $commend->select; preg_match('/(sum|count)(/', $old, $oll); if (empty($oll)) { $commend->select = "count(*) as count_num"; $r = $commend->queryScalar(); } else { $r = count($commend->queryAll()); } if ($this->limit) $r = min($this->limit, $r); return $r; } }
  
 
网友评论