個人開發(fā)心得(PHP,JS,SQL)

做PHP開發(fā)也四五年了坤塞,期間遇到無數(shù)的坑,填坑的過程中能力也得到了提升〕喊觯現(xiàn)在通過文章的形式把PHP摹芙,JS,SQL中一些有趣的用法記錄下來宛瞄,希望對剛剛?cè)腴T的同學(xué)有所幫助浮禾,還望老鳥手下留情,勿噴坛悉,哈哈伐厌。如果寫的有錯誤,還望指正。
不定期更新
1.PHP中switch的另類用法
比如下面if elseif 的判斷,當(dāng)判斷條件太復(fù)雜的時候,感覺會比較亂(PS:個人覺得)

 if($a == 1){

 }elseif ($b == 2) {
    # code...
 }elseif($c == 3){

 }elseif ($d == 4) {
    # code...
 }else{
    
 }

那么通過switch也能實現(xiàn)if elseif相同的功能,一般印象中,switch語句只能判別指定變量的不同的值,貌似JAVA的switch語句只能判斷指定變量的值裸影。

switch(true){
    case $a == 1:
        #code
        break;
    case $b == 2:
        #code
        break;
    case $c == 3:
        #code
        break;
    case $d == 4:
        #code
        break;
    default:
        #code 
        break;
}

結(jié)語:記得js也能使用這種結(jié)構(gòu)挣轨,可能弱類型的語言的原因吧
2.MySQL where field in ()的另類寫法
一般我們寫where field in都是類似于這樣:

select * from table where id in (1,2,3)

不過實際情況中,會有一張表中的多個類似的字段設(shè)定的值一樣轩猩。
一般我們的寫法可能會這樣

select * from table where a = 1 or b = 1 or c = 1

那我們可以用where in來實現(xiàn)相同的目的

select * from table where 1 in (a,b,c)

PS:這類用法可能應(yīng)用場景不大卷扮。哈哈
3.PHP foreach循環(huán)語句中使用引用,簡化對數(shù)組單元的操作,比方賦值操作,更改原單元指定鍵值的值
先列一下一般的操作方法

foreach($array as $key => $row){
    $array[$key]['a'] = 1;
    $array[$key]['b'] = 2;
}

通過使用引用操作符&,我們可以這樣操作

foreach($array as &$row){
    $row['a'] = 1;
    $row['b'] = 2;
}

PS:算偷點懶吧均践,哈哈
4.Thinkphp3.2.3使用中的一個坑
thinkphp在國內(nèi)的粉絲還是很多的,框架也很成熟,不過用的過程中會有碰到一些比較尷尬的bug,今天開發(fā)中就遇到了這樣的一個坑.使用模型里自動驗證+自動完成組合使用時碰到的一個小bug,自動驗證+自動完成都使用動態(tài)綁定操作.代碼如下:

$validate = array(
                array("mobile","require","手機(jī)號必填"),
                array("mobile","/^1[34578]\d{9}$/","手機(jī)號碼格式錯誤",1,"regex",3),
                array("mobile","","該手機(jī)號已存在",1,"unique",1),
                array("pwd","require","密碼不能為空"),
                array("pwd","6,100","密碼長度不能少于6位",1,"length",1),
            );
$auto = array(
                array("pwd","md5",1,"function"),
                array("name","小明",1),
                array("create_time",I("server.REQUEST_TIME"),1),
            );
if(!M("User")->validate($validate)->auto($auto)->create()){
    #code
}

因為在validate中有個檢驗手機(jī)號是否唯一的條件,unique這步驗證會到用到Model類里的find操作,find操作后會清空Model中的屬性options,這樣就會導(dǎo)致模型的自動完成失效;
PS:所以有Model驗證操作中有用unique操作的,不要將自動驗證+自動完成合在一起操作,這樣會導(dǎo)致自動完成失效.不過在模型中定義了$_validate和$_auto屬性的不存在這個問題.

5.ThinkPHP3.2.3版本,憑自己的經(jīng)驗封裝一個分頁取數(shù)據(jù)的方法,其實就是為了偷個懶,少寫點代碼.
首先,先探究下Think\Model類中的select和count操作
select操作:

/**
     * 查詢數(shù)據(jù)集
     * 
     * @access public
     * @param array $options 表達(dá)式參數(shù)
     * @return mixed
     */
    public function select($options=array()) {
        $pk   =  $this->getPk();
        if(is_string($options) || is_numeric($options)) {
            // 根據(jù)主鍵查詢
            if(strpos($options,',')) {
                $where[$pk]     =  array('IN',$options);
            }else{
                $where[$pk]     =  $options;
            }
            $options            =  array();
            $options['where']   =  $where;
        }elseif (is_array($options) && (count($options) > 0) && is_array($pk)) {
            // 根據(jù)復(fù)合主鍵查詢
            $count = 0;
            foreach (array_keys($options) as $key) {
                if (is_int($key)) $count++; 
            } 
            if ($count == count($pk)) {
                $i = 0;
                foreach ($pk as $field) {
                    $where[$field] = $options[$i];
                    unset($options[$i++]);
                }
                $options['where']  =  $where;
            } else {
                return false;
            }
        } elseif(false === $options){ // 用于子查詢 不查詢只返回SQL
            return  $this->buildSql();
        }
        // 分析表達(dá)式
        $options    =  $this->_parseOptions($options);
        // 判斷查詢緩存
        if(isset($options['cache'])){
            $cache  =   $options['cache'];
            $key    =   is_string($cache['key'])?$cache['key']:md5(serialize($options));
            $data   =   S($key,'',$cache);
            if(false !== $data){
                return $data;
            }
        }
        $resultSet  = $this->db->select($options);
        if(false === $resultSet) {
            return false;
        }
        if(empty($resultSet)) { // 查詢結(jié)果為空
            return null;
        }

        if(is_string($resultSet)){
            return $resultSet;
        }

        $resultSet  =   array_map(array($this,'_read_data'),$resultSet);
        $this->_after_select($resultSet,$options);
        if(isset($options['index'])){ // 對數(shù)據(jù)集進(jìn)行索引
            $index  =   explode(',',$options['index']);
            foreach ($resultSet as $result){
                $_key   =  $result[$index[0]];
                if(isset($index[1]) && isset($result[$index[1]])){
                    $cols[$_key] =  $result[$index[1]];
                }else{
                    $cols[$_key] =  $result;
                }
            }
            $resultSet  =   $cols;
        }
        if(isset($cache)){
            S($key,$resultSet,$cache);
        }
        return $resultSet;
    }

count操作:

/**
     * 利用__call方法實現(xiàn)一些特殊的Model方法
     * 
     * @access public
     * @param string $method 方法名稱
     * @param array $args 調(diào)用參數(shù)
     * @return mixed
     */
    public function __call($method,$args) {
        if(in_array(strtolower($method),$this->methods,true)) {
            // 連貫操作的實現(xiàn)
            $this->options[strtolower($method)] =   $args[0];
            return $this;
        }elseif(in_array(strtolower($method),array('count','sum','min','max','avg'),true)){
            // 統(tǒng)計查詢的實現(xiàn)
            $field =  isset($args[0])?$args[0]:'*';
            return $this->getField(strtoupper($method).'('.$field.') AS tp_'.$method);
        }elseif(strtolower(substr($method,0,5))=='getby') {
            // 根據(jù)某個字段獲取記錄
            $field   =   parse_name(substr($method,5));
            $where[$field] =  $args[0];
            return $this->where($where)->find();
        }elseif(strtolower(substr($method,0,10))=='getfieldby') {
            // 根據(jù)某個字段獲取記錄的某個值
            $name   =   parse_name(substr($method,10));
            $where[$name] =$args[0];
            return $this->where($where)->getField($args[1]);
        }elseif(isset($this->_scope[$method])){// 命名范圍的單獨調(diào)用支持
            return $this->scope($method,$args[0]);
        }else{
            E(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
            return;
        }
    }

發(fā)現(xiàn)count操作實際是調(diào)用類的方法getField

/**
     * 獲取一條記錄的某個字段值
     * 
     * @access public
     * @param string $field  字段名
     * @param string $spea  字段數(shù)據(jù)間隔符號 NULL返回數(shù)組
     * @return mixed
     */
    public function getField($field,$sepa=null) {
        $options['field']       =   $field;
        $options                =   $this->_parseOptions($options);
        // 判斷查詢緩存
        if(isset($options['cache'])){
            $cache  =   $options['cache'];
            $key    =   is_string($cache['key'])?$cache['key']:md5($sepa.serialize($options));
            $data   =   S($key,'',$cache);
            if(false !== $data){
                return $data;
            }
        }        
        $field                  =   trim($field);
        if(strpos($field,',') && false !== $sepa) { // 多字段
            if(!isset($options['limit'])){
                $options['limit']   =   is_numeric($sepa)?$sepa:'';
            }
            $resultSet          =   $this->db->select($options);
            if(!empty($resultSet)) {
                $_field         =   explode(',', $field);
                $field          =   array_keys($resultSet[0]);
                $key1           =   array_shift($field);
                $key2           =   array_shift($field);
                $cols           =   array();
                $count          =   count($_field);
                foreach ($resultSet as $result){
                    $name   =  $result[$key1];
                    if(2==$count) {
                        $cols[$name]   =  $result[$key2];
                    }else{
                        $cols[$name]   =  is_string($sepa)?implode($sepa,array_slice($result,1)):$result;
                    }
                }
                if(isset($cache)){
                    S($key,$cols,$cache);
                }
                return $cols;
            }
        }else{   // 查找一條記錄
            // 返回數(shù)據(jù)個數(shù)
            if(true !== $sepa) {// 當(dāng)sepa指定為true的時候 返回所有數(shù)據(jù)
                $options['limit']   =   is_numeric($sepa)?$sepa:1;
            }
            $result = $this->db->select($options);
            if(!empty($result)) {
                if(true !== $sepa && 1==$options['limit']) {
                    $data   =   reset($result[0]);
                    if(isset($cache)){
                        S($key,$data,$cache);
                    }            
                    return $data;
                }
                foreach ($result as $val){
                    $array[]    =   $val[$field];
                }
                if(isset($cache)){
                    S($key,$array,$cache);
                }                
                return $array;
            }
        }
        return null;
    }

通過分析代碼我們發(fā)現(xiàn),select操作和count操作最后都是通過$this->db->select($options)這段代碼從數(shù)據(jù)庫里獲取數(shù)據(jù)的.而這個$options局部變量都是通過$this->_parseOptions($options);這個方法賦值的.
發(fā)現(xiàn)了這個共同點,那么我們就開始封裝一個分頁取數(shù)據(jù),返回總條數(shù)和指定的分頁數(shù)據(jù):
(1)定義一個BaseModel類繼承自Think\Model的基類

namespace Common\Model;
use Think\Model;
class BaseModel extends Model{

}

(2)實現(xiàn)分頁取數(shù)據(jù)的方法

namespace Common\Model;
use Think\Model;
class BaseModel extends Model{
        /**
     *
     * 默認(rèn)獲取數(shù)據(jù)表10條記錄每次
     * @param $print_return
     * 默認(rèn)分頁取數(shù)據(jù) @param $needLimit
     * @return array
     */
    public function getList($needLimit = true,$print_return = false){
        $options = $this->options;
        $options['alias'] = isset($this->options['alias']) ? $this->options['alias'] : 'a';
        if(isset($this->options['order']) && !empty($this->options['order'])){
            $options['order'] = $this->options['order'];
        }else{
            if(in_array('create_time',$this->fields)){
                $options['order'] = $options['alias'].".create_time desc";
            }
        }
        /*沒限制分頁,則默認(rèn)每次取10條*/
        if($needLimit){
            if(empty($this->options['page']) && empty($this->options['limit'])){
                $pindex = max(1,intval(I('p',1)));
                $psize = C('PER_PAGE');
                $limit = intval($pindex-1)*$psize.','.$psize;
                $this->limit($limit);
                $options['limit'] = $this->options['limit'];
            }
        }
        $this->options = $options;
        //統(tǒng)計數(shù)據(jù)不需要ORDER
        unset($this->options['order']);
        $total = $this->count();
        $this->options = $options;
        $rows = $this->select();
        $return = array(
            'total' => $total,
            'rows' => $rows,
            'list' => $rows,
            'status' => 1,
            'page' => max(1,intval(I('p',1))),
            //'sql' => APP_DEBUG ? $this->_sql() : '',
            'pages' => $total % C('PER_PAGE') == 0 ? $total / C('PER_PAGE') : ceil($total / C('PER_PAGE'))
        );
        //需要打印結(jié)果時
        if($print_return){
            var_dump($return);
        }
        return $return;
    }
}

(3):開始在控制器里使用這個封裝好的類
不能直接使用D的助手函數(shù)直接實例化BaseModel,因為會找不到這個base這個表,所以如果用D方法就需要你操作的表的Model繼承自BaseModel;
或者可以自行封裝一個M方法差不多的助手函數(shù),只不過實例化的時候是實例化BaseModel而不是Think\Model;
下面我用User這個來示例:

public function index(){
    $data = D("User")->field($field)->where($where)->join()->order("uid desc")->limit("1,10")->getList();
}

$data中包含滿足條件的總數(shù)和對應(yīng)分頁的數(shù)據(jù)
PS:封裝的時候默認(rèn)給被操作的主表設(shè)置了一個別名(a)為了兼容join操作,所以取主表字段或者設(shè)置主表字段條件的時候需要在字段前加個a,從表的別名根據(jù)自己的實際情況來設(shè).

6.Javascript簡化Ajax提交數(shù)據(jù)的封裝
比如,有時我們需要用Ajax提交的數(shù)據(jù)在一個表單中,而這個表單里有很多字段并且這些字段都需要提交到服務(wù)器,如果我們一個一個取組裝這些數(shù)據(jù),那么這個代碼量就會很大,也有可能產(chǎn)生遺漏的問題.
既然問題已經(jīng)提出來了,那么我們就來解決這個問題.
先了解下Jquery中封裝的$.ajax(),$.get(),$.post()的方法介紹,提交數(shù)據(jù)的格式支持a=1&b=2&c=3和Object對象形式兩種.
對象形式如下:

{
  a:1,
  b:2,
  c:3
}

使用簡便方法前,需要給指定的form標(biāo)簽設(shè)置一個ID(例如:id="form"),第一種數(shù)據(jù)格式我們可以直接使用Jquery自帶的方法serialize()方法得到;
代碼如下:

var form = $("#form").serialize();

而第二種方法則需要自己封裝一個方法,這個網(wǎng)上有很多,下面貼一個我自己平時常用的一段封裝好的代碼:

<script>
(function($){
    $.fn.serializeJSON = function()
    {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };
})(jQuery);
</script>

上述代碼一定要寫在引入Jquery類庫文件之后,否則會報錯.
使用方法如下:

<script>
var form = $("#form").serializeJSON();
</script>

得到表單的數(shù)據(jù)為以表單元素name為建,value為值的數(shù)據(jù).
應(yīng)用到Ajax中:

<script type="text/javascript">
    var form = $("#form").serialize();
        //var form = $("#form").serializeJSON();
    $.ajax({
        url:"",
        dataType:"json",
        data:form,
        success:function(res){
            #code
        }
    });
    $.post("",form,function(res){
        #code
    });
    $.get("",form,function(res){
        #code
    });
</script>

這樣就能簡化封裝ajax需要提交的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晤锹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子彤委,更是在濱河造成了極大的恐慌鞭铆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焦影,死亡現(xiàn)場離奇詭異车遂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)斯辰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門舶担,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彬呻,你說我怎么就攤上這事衣陶”澹” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵剪况,是天一觀的道長教沾。 經(jīng)常有香客問我,道長拯欧,這世上最難降的妖魔是什么详囤? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任财骨,我火速辦了婚禮镐作,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隆箩。我一直安慰自己该贾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布捌臊。 她就那樣靜靜地躺著杨蛋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪理澎。 梳的紋絲不亂的頭發(fā)上逞力,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音糠爬,去河邊找鬼寇荧。 笑死,一個胖子當(dāng)著我的面吹牛执隧,可吹牛的內(nèi)容都是我干的揩抡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼镀琉,長吁一口氣:“原來是場噩夢啊……” “哼峦嗤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屋摔,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤烁设,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钓试,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體装黑,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年亚侠,在試婚紗的時候發(fā)現(xiàn)自己被綠了曹体。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝烂,死狀恐怖箕别,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤串稀,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布除抛,位于F島的核電站,受9級特大地震影響母截,放射性物質(zhì)發(fā)生泄漏到忽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一清寇、第九天 我趴在偏房一處隱蔽的房頂上張望喘漏。 院中可真熱鬧,春花似錦华烟、人聲如沸翩迈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽负饲。三九已至,卻和暖如春喂链,著一層夾襖步出監(jiān)牢的瞬間返十,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工椭微, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留洞坑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓赏表,卻偏偏與公主長得像检诗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瓢剿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫逢慌、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評論 4 62
  • Swift版本點擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,365評論 7 249
  • 年少大志入朝堂忙菠, 欲施抱負(fù)心血熱。 經(jīng)幾年纺弊, 計無施得牛欢; 歷幾歲, 無數(shù)坎坷淆游。 兩鬢斑白傍睹, 心意不再隔盛, 愿漂泊, ...
    九八盧聰閱讀 142評論 0 0
  • 有點兒難為編劇了拾稳。 多米尼克·托雷托的親妹夫不能再上了吮炕,一下少了兩個主要角色。原本還可以那這個妹妹說事兒访得,這下不行...
    黑白片1979閱讀 425評論 0 0