- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章php封装pdo实例以及pdo长连接的优缺点总结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
最近需要写脚本来实现崩溃日志的入库,不出所料又是脱离于框架的,那么行吧,咱们只能自己封装数据库相关操作了。博主这里选择了封装pdo操作数据库相关.
众所周知的,php在早期的时候是带有mysql扩展的,但是后来由于过于古老缺失了mysql的新特性,因此主键没落.
从php5开始,更建议大家使用mysqli扩展,这个是mysql扩展的增强版,是一个面向对象的MySQL接口,更容易使用。缺点是只能操作mysql,不够强大.
还有就是pdo扩展了,这个是最丰富的的一个扩展,支持多种数据库,重要的是,在安全上是比其他两种扩展都要强的,通过使用prepared预处理更是有效的防止sql注入。因此,博主这里选择了封装pdo相关的操作.
长连接顾名思义就是一直保持连接,相对于平时的短连接,每次请求都会重新创建链接来说,长连接可以有效的减少创建的过程,可以更好的节省性能.
在操作上是在连接数据库的时候,多加一个参数:
1
|
$pdo
=
new
PDO(
$dsn
,
$username
,
$passwd
, [PDO::ATTR_PERSISTENT => true]);
|
后面的PDO::ATTR_PERSISTENT => true 就是开启长连接的方法.
博主在搜索长连接相关知识的时候,看到一篇文章,结论是长连接仅适用于apache,不适用于nginx,这是真的吗?
参考文章:http://www.zzvips.com/article/21945.html 。
大致结论是:长连接更多的是针对于apache的,因为apache维护一个进程池,开启了apache mpm功能之后,apache会默认维持一个进程池,mysql长连接之后的连接,并没有作为socet连接关闭,而是作为一个不释放的东西,放进了进程池/线程池里面去.
而对于nginx来说,长连接是无效的,脚本执行结束则释放资源?
这里前辈已经测试过了,咱们给出前辈的地址,大家有兴趣的可以看看 。
结论: 事实证明php-fpm是可以实现长连接的,只是如果该进程空闲的话,会造成资源浪费.
php-fpm的配置文件可以考虑设置pm.max_requests = 1000,代表每一个子进程的最大请求服务数量,如果超过了这个值,该子进程会被自动重启.
比如max_requests这个参数,如果设置很大的话,那这个子进程要运行很多次才会重启,假如这个请求发生了错误或者内存泄漏,那么这个值设置很大是不合适的。但如果请求没有问题,这个值设置小的话就会频繁的重启,这样也会碰到不少502的问题,所以要仁者见仁,智者见智的设置了,这里初始化设置1000,如果测试没有内存泄漏等问题,可以再大一些.
参考博文地址:https://www.zhihu.com/question/62603122 。
总结: 如果业务并发比较大且带有事务,不建议使用长连接的方式.
博主在不断的搜索中,发现长连接要发挥出最佳性能始终是避不开连接池这点的,而php恰恰又不能很好的实现连接池,这点确实是有点小遗憾.
整体来说在php中是暂时无法配置和mysql的完美连接池的,在业务比较复杂的地方,还是谨慎试用长连接,每个连接都是1个线程,会造成大量的资源浪费.
如果是某些业务需要持续的数据库操作,比如提交日志接口等,那么是可以考虑打开长连接的,记得设置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 。
这个网友基本的增删改查都封装好了,而且都有参数预处理,安全性还是可以的。不过既然作为一个基准的类,还是缺少一些东西.
例如重连函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/**
* @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的报错机制以及错误处理这块,咱们下篇再讨论.
1
2
3
|
//自定义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);}
|
1
2
3
4
5
6
7
|
/**
* destruct 关闭数据库连接
*/
public
function
destruct()
{
$this
->pdo = null;
}
|
1
2
3
4
5
6
7
8
9
|
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封装pdo实例以及pdo长连接的优缺点总结的文章就介绍到这了,更多相关php封装pdo实例及pdo长连接优缺点分析内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://www.php.cn/php-ask-486222.html 。
最后此篇关于php封装pdo实例以及pdo长连接的优缺点总结的文章就讲到这里了,如果你想了解更多关于php封装pdo实例以及pdo长连接的优缺点总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我知道这个问题可能已经被问过,但我检查了所有这些,我认为我的情况有所不同(请友善)。所以我有两个数据集,第一个是测试数据集,第二个是我保存在数据框中的预测(预测值,这就是没有数据列的原因)。我想合并两
在 .loc 方法的帮助下,我根据同一数据框中另一列中的值来识别 Panda 数据框中某一列中的值。 下面给出了代码片段供您引用: var1 = output_df['Player'].loc[out
当我在 Windows 中使用 WinSCP 通过 Ubuntu 连接到 VMware 时,它提示: The server rejected SFTP connection, but it lis
我正在开发一个使用 xml web 服务的 android 应用程序。在 wi-fi 网络中连接时工作正常,但在 3G 网络中连接时失败(未找到 http 404)。 这不仅仅发生在设备中。为了进行测
我有一个XIB包含我的控件的文件,加载到 Interface Builder(Snow Leopard 上的 Xcode 4.0.2)中。 文件的所有者被设置为 someClassController
我在本地计算机上管理 MySQL 数据库,并通过运行以下程序通过 C 连接到它: #include #include #include int main(int argc, char** arg
我不知道为什么每次有人访问我网站上的页面时,都会打开一个与数据库的新连接。最终我到达了大约 300 并收到错误并且页面不再加载。我认为它应该工作的方式是,我将 maxIdle 设置为 30,这意味着
希望清理 NMEA GPS 中的 .txt 文件。我当前的代码如下。 deletes = ['$GPGGA', '$GPGSA', '$GPGSV', '$PSRF156', ] searchquer
我有一个 URL、一个用户名和一个密码。我想在 C# .Net WinForms 中建立 VPN 连接。 你能告诉我从哪里开始吗?任何第三方 API? 代码示例将受到高度赞赏... 最佳答案 您可以像
有没有更好的方法将字符串 vector 转换为字符 vector ,字符串之间的终止符为零。 因此,如果我有一个包含以下字符串的 vector "test","my","string",那么我想接收一
我正在编写一个库,它不断检查 android 设备的连接,并在设备连接、断开连接或互联网连接变慢时给出回调。 https://github.com/muddassir235/connection_ch
我的操作系统:Centos 7 + CLOUDLINUX 7.7当我尝试从服务器登录Mysql时 [root@server3 ~]# Mysql -u root -h localhost -P 330
我收到错误:Puma 发现此错误:无法打开到本地主机的 TCP 连接:9200(连接被拒绝 - 连接(2)用于“本地主机”端口 9200)(Faraday::ConnectionFailed)在我的
请给我一些解决以下错误的方法。 这是一个聊天应用....代码和错误如下:: conversations_controller.rb def create if Conversation.bet
我想将两个单元格中的数据连接到一个单元格中。我还想只组合那些具有相同 ID 的单元格。 任务 ID 名称 4355.2 参与者 4355.2 领袖 4462.1 在线 4462.1 快速 4597.1
我经常需要连接 TSQL 中的字段... 使用“+”运算符时 TSQL 强制您处理的两个问题是 Data Type Precedence和 NULL 值。 使用数据类型优先级,问题是转换错误。 1)
有没有在 iPad 或 iPhone 应用程序中使用 Facebook 连接。 这个想法是登录这个应用程序,然后能够看到我的哪些 facebook 用户也在使用该应用程序及其功能。 最佳答案 是的。
我在连接或打印字符串时遇到了一个奇怪的问题。我有一个 char * ,可以将其设置为字符串文字的几个值之一。 char *myStrLiteral = NULL; ... if(blah) myS
对于以下数据 - let $x := "Yahooooo !!!! Select one number - " let $y := 1 2 3 4 5 6 7 我想得到
我正在看 UDEMY for perl 的培训视频,但是视频不清晰,看起来有错误。 培训展示了如何使用以下示例连接 2 个字符串: #!usr/bin/perl print $str = "Hi";
我是一名优秀的程序员,十分优秀!