這篇文章主要介紹了PHP如何封裝pdo,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在清遠(yuǎn)等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站建設(shè)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需網(wǎng)站策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),營銷型網(wǎng)站建設(shè),成都外貿(mào)網(wǎng)站建設(shè)公司,清遠(yuǎn)網(wǎng)站建設(shè)費(fèi)用合理。
最近需要寫腳本來實(shí)現(xiàn)崩潰日志的入庫,不出所料又是脫離于框架的,那么行吧,咱們只能自己封裝數(shù)據(jù)庫相關(guān)操作了。這里選擇了封裝pdo
操作數(shù)據(jù)庫相關(guān)。
眾所周知的,php
在早期的時(shí)候是帶有MySQL
擴(kuò)展的,但是后來由于過于古老缺失了mysql
的新特性,因此主鍵沒落。
從php5
開始,更建議大家使用mysqli
擴(kuò)展,這個(gè)是mysql
擴(kuò)展的增強(qiáng)版,是一個(gè)面向?qū)ο蟮?code>MySQL接口,更容易使用。缺點(diǎn)是只能操作mysql
,不夠強(qiáng)大。
還有就是pdo
擴(kuò)展了,這個(gè)是最豐富的的一個(gè)擴(kuò)展,支持多種數(shù)據(jù)庫,重要的是,在安全上是比其他兩種擴(kuò)展都要強(qiáng)的,通過使用prepared
預(yù)處理更是有效的防止sql
注入。因此,博主這里選擇了封裝pdo
相關(guān)的操作。
長連接顧名思義就是一直保持連接,相對(duì)于平時(shí)的短連接,每次請(qǐng)求都會(huì)重新創(chuàng)建鏈接來說,長連接可以有效的減少創(chuàng)建的過程,可以更好的節(jié)省性能。
在操作上是在連接數(shù)據(jù)庫的時(shí)候,多加一個(gè)參數(shù):
$pdo = new PDO($dsn, $username, $passwd, [PDO::ATTR_PERSISTENT => true]);
后面的PDO::ATTR_PERSISTENT => true
就是開啟長連接的方法。
博主在搜索長連接相關(guān)知識(shí)的時(shí)候,看到一篇文章,結(jié)論是長連接僅適用于apache,不適用于nginx
,這是真的嗎?
參考博文地址:https://www.cnblogs.com/wpjamer/articles/7106389.html
大致結(jié)論是:長連接更多的是針對(duì)于apache
的,因?yàn)?code>apache維護(hù)一個(gè)進(jìn)程池,開啟了apache mpm
功能之后,apache
會(huì)默認(rèn)維持一個(gè)進(jìn)程池,mysql
長連接之后的連接,并沒有作為socet
連接關(guān)閉,而是作為一個(gè)不釋放的東西,放進(jìn)了進(jìn)程池/線程池里面去。
而對(duì)于nginx
來說,長連接是無效的,腳本執(zhí)行結(jié)束則釋放資源?
這里前輩已經(jīng)測試過了,咱們給出前輩的地址,大家有興趣的可以看看
參考博文地址:https://hacpai.com/article/1526490593632
結(jié)論:
事實(shí)證明php-fpm
是可以實(shí)現(xiàn)長連接的,只是如果該進(jìn)程空閑的話,會(huì)造成資源浪費(fèi)。
php-fpm
的配置文件可以考慮設(shè)置pm.max_requests = 1000
,代表每一個(gè)子進(jìn)程的最大請(qǐng)求服務(wù)數(shù)量,如果超過了這個(gè)值,該子進(jìn)程會(huì)被自動(dòng)重啟。
比如max_requests
這個(gè)參數(shù),如果設(shè)置很大的話,那這個(gè)子進(jìn)程要運(yùn)行很多次才會(huì)重啟,假如這個(gè)請(qǐng)求發(fā)生了錯(cuò)誤或者內(nèi)存泄漏,那么這個(gè)值設(shè)置很大是不合適的。但如果請(qǐng)求沒有問題,這個(gè)值設(shè)置小的話就會(huì)頻繁的重啟,這樣也會(huì)碰到不少502
的問題,所以要仁者見仁,智者見智的設(shè)置了,這里初始化設(shè)置1000
,如果測試沒有內(nèi)存泄漏等問題,可以再大一些。
參考博文地址:https://www.zhihu.com/question/62603122
總結(jié):如果業(yè)務(wù)并發(fā)比較大且?guī)в惺聞?wù),不建議使用長連接的方式。
博主在不斷的搜索中,發(fā)現(xiàn)長連接要發(fā)揮出最佳性能始終是避不開連接池這點(diǎn)的,而php恰恰又不能很好的實(shí)現(xiàn)連接池,這點(diǎn)確實(shí)是有點(diǎn)小遺憾。
整體來說在php
中是暫時(shí)無法配置和mysql
的完美連接池的,在業(yè)務(wù)比較復(fù)雜的地方,還是謹(jǐn)慎試用長連接,每個(gè)連接都是1個(gè)線程,會(huì)造成大量的資源浪費(fèi)。
如果是某些業(yè)務(wù)需要持續(xù)的數(shù)據(jù)庫操作,比如提交日志接口等,那么是可以考慮打開長連接的,記得設(shè)置max_requests
來定量關(guān)閉php-fpm
連接,fpm
關(guān)閉之后也會(huì)自動(dòng)釋放mysql
的連接。
還有pm.max_spare_servers
設(shè)置服務(wù)器空閑時(shí)最大php-fpm
進(jìn)程數(shù)量。
例如: pm.max_spare_servers = 25
如果空閑時(shí),會(huì)檢查進(jìn)程數(shù),多于25
個(gè)了,就會(huì)關(guān)閉幾個(gè),達(dá)到25
個(gè)的狀態(tài)。
擅長swoole
的同學(xué),可以參考這篇文章:
基于swoole擴(kuò)展實(shí)現(xiàn)真正的PHP數(shù)據(jù)庫連接池
首先這部分博主是參考了一個(gè)網(wǎng)友的封裝,github
地址如下:
https://github.com/nadirvishun/php-pdo-class
這個(gè)網(wǎng)友基本的增刪改查都封裝好了,而且都有參數(shù)預(yù)處理,安全性還是可以的。不過既然作為一個(gè)基準(zhǔn)的類,還是缺少一些東西。
例如重連函數(shù):
/** * @params:重連函數(shù),上限3次 * @date:2020/3/18 * @time:17:03 */ public function customConnect() { try { $this->pdo = new PDO($this->config['dsn'], $this->config['username'], $this->config['password'], $this->config['params']); $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //需要將錯(cuò)誤處理模式變成異常模式 return true; } catch (Exception $e) { if (stripos($e->getMessage(), 'MySQL server has gone away') !== false || stripos($e->getMessage(),' bytes failed with errno=10053') !==false) { $this->close(); $this->tryNums++; if ($this->tryNums > 3) { return false; } self::customConnect(); } else { $this->throw_exception($e->getMessage()); return false; } } }
這步原因是長連接會(huì)頻繁的造成mysql gone away
錯(cuò)誤,而這個(gè)錯(cuò)誤是php
的warnings
級(jí)別錯(cuò)誤,try..catch
根本就捕獲不到,所以博主這里自定義錯(cuò)誤處理函數(shù)來處理。
這部分是轉(zhuǎn)化php
的warnings
錯(cuò)誤為try..catch
可以捕獲的error
錯(cuò)誤,關(guān)于php
的報(bào)錯(cuò)機(jī)制以及錯(cuò)誤處理這塊,咱們下篇再討論。
//自定義warnings處理函數(shù)set_error_handler('customException');//拿到warnngs錯(cuò)誤之后,轉(zhuǎn)化為error錯(cuò)誤拋出,這樣就可以被try..catch捕獲function customException( $error_no, $error_msg, $error_file, $error_line){ throw new \Exception($error_msg,0,null); //throw new \Exception($error_msg);}
/** * destruct 關(guān)閉數(shù)據(jù)庫連接 */ public function destruct() { $this->pdo = null; }
public function query($sql = null, $param = null) { //檢測連接是否活躍 $this->pdo_ping(); //判斷之前是否有結(jié)果集 if (!empty($this->PDOStatement)) { $this->free(); } xxxxxxxxxx }
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“PHP如何封裝pdo”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!