php折騰類比實現ORM-2

來源:互聯網
上載者:User
前面我們已經完成了orm最核心部分–拼湊字串,接下來我們需要執行拼湊完成的sql語句。這裡只完成了insert操作 折騰(二)-與pdo進行組合,實現執行拼湊完成的sql語句

我們先建立兩張表 user

類型 長度 小數點 允許空值
user_id int 11 0 false
user_name varchar 20 0 false
user_pwd varchar 32 0 false
order
類型 長度 小數點 允許空值
order_id int 11 0 false
user_id int 11 0 false
order_price decimal 5 2 false
執行insert後的效果



與pdo組合之後的代碼如下,所示,有興趣可以研究下:

<?phpini_set('display_errors',1);ini_set('error_reporting',E_ALL);$map=function ($items) {    if (!is_array($items)) {        return $items;    } else {        $result="";        foreach ($items[1] as $item) {            if ($result!="")                $result.=",";            $result.=$item.$this->_aliastb($item);//類似news,news_class 添加到form後面        }        return $items[0].$result;    }};class orm{    public $sql=array(        "select"=>"select ",        "from"=>array("from ",array()),        "where"=>" where ",        "orderby"=>" order by ",        "insertinto"=>"insert into ",//insert操作        "insertfields"=>"",        "values"=>" values"    );    public $errorCode="";//錯誤碼    public $sql_bak=[];    public function __construct()    {        $this->sql_bak=$this->sql;        $this->db=new PDO("mysql:host=127.0.0.1;dbname=testOrm","root","hello2016");//初始化資料庫連接    }    public function select()    {        $fields=func_get_args();        foreach ($fields as $field) {            if (is_array($field)) {                $get_key=key($field);//擷取數組的key,其實就是表的名字,還需要在欄位前面加上表首碼                $this->__add(__FUNCTION__, $this->_aliastb($get_key).'.'.$field[$get_key]);            } else {                $this->__add(__FUNCTION__, $field);            }        }        return $this;    }    //插入資料    public function insert() {        $params=func_get_args();//擷取可變參數        $fields=[];        $fields_values=[];        $callback=[];        foreach ($params as $param) {            if (is_array($param)) {//代表要拼接的是欄位和值                foreach ($param as $item) {                    //取出欄位名                    $field=key($item);                    //取出欄位的值                    $field_value=$item[$field];                    //把上面的欄位和欄位值插入相對應的數組                    $fields[]=$field;                    //拼湊字串的時候,判斷是否是字串,如果是字串則要加上單引號                    if (is_string($field_value)) {                        $field_value="'".$field_value."'";                    }                    $fields_values[]=$field_value;                }                //處理完參數之後,構造要插入欄位的拼湊                $this->__add("insertfields", '('.implode($fields,',').')');                $this->__add("values", '('.implode($fields_values,',').')');            }            //如果是字串說明傳的是表名            if (is_string($param)) {                $this->__add("insertinto", $param);            }            if(is_bool($param) && $param) //如果傳過來的參數是 布爾型,且為true,則預設開啟事務            {                $this->db->beginTransaction();            }            if (is_callable($param)) {                $callback[]=$param;            }        }        if(count($callback)>0)        {            $this->exec();//如果有匿名函數,則先執行SQL            $this->clearConfig();  //恢複配置到最開始狀態,防止執行其他SQL時產生衝突。大家可以把SQL儲存到 某個類屬性中            foreach($callback as $call)//最後統一執行各個回呼函數            {                $call=Closure::bind($call,$this);//這樣在匿名函數中就可以使用$this ,且這個$this就是orm對象                $call();//手工調用 匿名函數,這就是回調            }        }        return $this;    }    //避免sql語句相互幹擾    function clearConfig()//恢複到原有配置    {        $this->sql=$this->sql_bak;    }    //排序    function orderby($str, $order)    {        $order=' '.$order;        if (is_array($str)) {            $tb=key($str);            $this->__add(__FUNCTION__, $this->_aliastb($tb).'.'.$str[$tb].$order);        } else {            $this->__add(__FUNCTION__, $str.$order);        }        return $this;    }    //給表加別名    public function _aliastb($tbName) {        return ' _'.$tbName;    }    public function from($tableName)//處理from過程    {        if (is_array($tableName)) {//是數組的話就是代表多張表關聯            if (count($tableName)!=2) return $this;//參數值類似[["name"=>classid""],["name_class"]=>"id"],小於2滅有意義            $tb1=current($tableName);            $tb2=next($tableName);            //第一步,把表的key值作為from參數進行處理            $tb1_key=key($tb1);            $tb1_value=$tb1[$tb1_key];            $tb2_key=key($tb2);            $tb2_value=$tb2[$tb2_key];            $this->__add(__FUNCTION__, $tb1_key);            $this->__add(__FUNCTION__, $tb2_key);            //第二步,拼湊where條件            $whereString=' _'.$tb1_key.'.'.$tb1_value.'='."_".$tb2_key.'.'.$tb2_value;            $this->where($whereString);            return $this;        } else { //字串則表示單張表查詢            $this->__add(__FUNCTION__, $tableName);            return $this;        }    }    public function where($str) {        $this->__add(__FUNCTION__, $str, " and ");        return $this;    }    public function  __add($key,  $str,  $spliter=",")//實現字串的累加    {        //調用不存在的方法,直接返回        if(!array_key_exists($key, $this->sql))   return ;        if (is_array($this->sql[$key])) {            //如果已經存在該項表明我們不做什麼處理            if (!in_array($str, $this->sql[$key][1])) {                $this->sql[$key][1][]=$str;            }        } else {            //如果是字串,直接進行字串累加//            if (trim($this->sql[$key])!=$key)            if (preg_replace('/\s/', '', $this->sql[$key])!=$key && preg_replace("/\s/", '', $this->sql[$key])!="")                $this->sql[$key].=$spliter;            $this->sql[$key].=$str;        }    }    public function __toString()    {        global $map;        $map=Closure::bind($map ,$this);        //        $filter=function ($value, $key) {//            if(!is_string($value)) return true;            if(is_array($value)) {                if(count($value[1])>0) return true;                return false;            }            //如果是Null 字元串也不參與累加            if(preg_replace("/\s/", '', $value)==$key || preg_replace("/\s/", "", $value )=="")                return false;            return true;        };        $this->sql=array_filter($this->sql, $filter, ARRAY_FILTER_USE_BOTH );        $res=array_map($map, array_values($this->sql));//        $this->sql=$this->sql_bak;        return implode(array_values($res), ' ');//把新的數組重新構建成一個字串    }    public function exec()    {        //測試執行方法        $sql=strval($this); //會自動調用 _tostring方法        $stmt=$this->db->prepare($sql);        if(!$stmt->execute())//執行失敗,        {            if($this->db->inTransaction()) //判斷是否開啟了事務            {                $this->db->rollBack();//執行復原            }            $this->errorCode=$stmt->errorCode();            echo "執行Sql".$sql.'出錯,錯誤碼:'.$this->errorCode.",錯誤資訊:".$stmt->errorInfo()[2];        }        return $this;    }    function getLastInsertID() //擷取上一條SQL執行情況    {        return $this->db->lastInsertId();    }    function getAll() //擷取全部取出的結果    {        return $this->db->fetchAll();    }    function commit()    {        //提交事務        if($this->db->inTransaction())            $this->db->commit();    }}    $orm=new orm();    echo $orm->insert(true,[        ['user_name'=>"seven"],        ['user_pwd'=>md5('123')]    ],"user",function(){        $userid=$this->getLastInsertID(); //擷取使用者註冊後的自增ID        $this->insert([            ['user_id'=>intval($userid)],            ['order_price'=>100],        ],"orders",function(){            if($this->errorCode=="")            {                $this->commit();                echo "sucess!";            }            else            {                echo "fail!";            }        });    });

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.