この記事では、PHP での PDO の PHP カプセル化の例と、PDO の長い接続に関する関連知識を紹介します。名前が示すように、長い接続では常に接続が維持されます。通常の短い接続と比較すると、リンクは再接続されます。 -created with each request. 接続が長いと、作成プロセスが効果的に短縮され、保存パフォーマンスが向上すると言われています。みんなが助けてくれるといいですね!
##1. はじめに 最近、クラッシュログの保存を実現するスクリプトを書く必要がありますが、予想通りフレームワークから切り離されているので大丈夫です, データベース関連の操作を自分自身でカプセル化することしかできません。ここのブロガーは、データベースを操作するためにpdo をカプセル化することを選択しました。
php には初期には
mysql 拡張子がありましたが、後に欠落してしまいました。古すぎました
mysql の新機能が導入されたため、主キーが衰退しました。
php5 以降では、
mysqli 拡張機能を使用することをお勧めします。これは、
mysql 拡張機能の拡張バージョンであり、オブジェクト指向
MySQL インターフェイス、使いやすくなりました。欠点は、
mysql しか操作できず、十分な能力がないことです。
pdo 拡張機能もあります。これは最も豊富な拡張機能であり、さまざまなデータベースをサポートしています。重要なことは、セキュリティの点で他の 2 つの拡張機能よりも強力であることです。
prepared 前処理を使用すると、
sql インジェクションを効果的に防ぐことができます。したがって、ここのブロガーは
pdo 関連の操作をカプセル化することを選択しました。
$pdo = new PDO($dsn, $username, $passwd, [PDO::ATTR_PERSISTENT => true]);次の
PDO::ATTR_PERSISTENT => true は、長い接続を開くメソッドです。 。
参考博文地址:https://www.cnblogs.com/wpjamer/articles/7106389.html
一般的な結論は次のとおりです。apache
はプロセス プールを維持し、
apache をよりターゲットにしています。関数、
apache はデフォルトでプロセス プールを維持します。
mysql長い接続の後の接続は、
socet 接続として閉じられず、解放されていない接続として閉じられます。 1. 物事はプロセス プール/スレッド プールに入れられます。
また、
nginx では、長い接続は無効です。スクリプトの実行が終了すると、リソースは解放されますか?
ここの先輩方が既にテスト済みですので、先輩方のアドレスをお伝えしますので、興味のある方はご覧ください
参考博文地址:https://hacpai.com/article/1526490593632
php-fpm
は長時間の接続を実現できることが事実によって証明されていますが、プロセスがアイドル状態の場合、リソースの無駄が発生します。
php-fpm の構成ファイルでは、各サブプロセスのサービス リクエストの最大数を表す
pm.max_requests = 1000
たとえば、パラメータ
max_requests が非常に大きな値に設定されている場合、子プロセスは再起動するまでに何度も実行する必要があります。このリクエストでエラーまたはメモリ リークが発生した場合、この値は非常に大きな値に設定されますが、大きい値は不適切です。ただし、リクエストに問題がない場合、この値を小さい値に設定すると、頻繁に再起動が発生し、多くの
502
1000、テストにメモリ リークやその他の問題がない場合は、テストを大きくすることができます。
4. トランザクションに対する長い接続の影響
参考博文地址:https://www.zhihu.com/question/62603122
要約: ビジネスの同時実行性が比較的大きく、トランザクションがある場合、長い接続を使用することはお勧めできません。 。 5. 概要ブロガーは、継続的に検索を行っているうちに、長い接続で最高のパフォーマンスを達成するには接続プーリングを避けることができず、PHP があまり優れていないことに気づきました。接続プールの制限は確かに少し残念です。
一般的に、mysql
を使用して完璧な接続プールを構成することは一時的に不可能です。ビジネスがより複雑な場所では、試してみることをお勧めします。各接続はスレッドであるため、リソースを大量に浪費することになります。 如果是某些业务需要持续的数据库操作,比如提交日志接口等,那么是可以考虑打开长连接的,记得设置max_requests
来定量关闭php-fpm
连接,fpm
关闭之后也会自动释放mysql
的连接。
还有pm.max_spare_servers
设置服务器空闲时最大php-fpm
进程数量。
例如: pm.max_spare_servers = 25
如果空闲时,会检查进程数,多于25
个了,就会关闭几个,达到25
个的状态。
擅长swoole
的同学,可以参考这篇文章:
基于swoole扩展实现真正的PHP数据库连接池
首先这部分博主是参考了一个网友的封装,github
地址如下:
https://github.com/nadirvishun/php-pdo-class
这个网友基本的增删改查都封装好了,而且都有参数预处理,安全性还是可以的。不过既然作为一个基准的类,还是缺少一些东西。
例如重连函数:
/** * @params:重连函数,上限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); //需要将错误处理模式变成异常模式 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; } } }
这步原因是长连接会频繁的造成mysql gone away
错误,而这个错误是php
的warnings
级别错误,try..catch
根本就捕获不到,所以博主这里自定义错误处理函数来处理。
这部分是转化php
的warnings
错误为try..catch
可以捕获的error
错误,关于php
的报错机制以及错误处理这块,咱们下篇再讨论。
//自定义warnings处理函数set_error_handler('customException');//拿到warnngs错误之后,转化为error错误抛出,这样就可以被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 关闭数据库连接 */ public function destruct() { $this->pdo = null; }
public function query($sql = null, $param = null) { //检测连接是否活跃 $this->pdo_ping(); //判断之前是否有结果集 if (!empty($this->PDOStatement)) { $this->free(); } xxxxxxxxxx }
这四步完善之后,这个pdo的类还是可以用的,大家需要的话可以去百度云上下载。
链接: https://pan.baidu.com/s/1Siz_bKlhEIVNV99Y0zTzqw 提取码: ebqx
大家如果感兴趣的话,可以点击《PHP视频教程》进行更多关于PHP知识的学习。
以上がPDO インスタンスと PDO の長い接続をカプセル化する PHP の長所と短所の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。