首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
29
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
138
篇与
的结果
2023-08-11
通过PHP单例模式与长连接减少MySql连接数
通过PHP单例模式与长连接减少MySql连接数此单例代码有问题,请参考下面的 在Mysql驱动的PHP网站中,MySql连接的一般都是利用脚本的结束来进行释放,在一些分层写的php网站中,若一个页面含有多个数据访问类,由于每个数据访问类都会有数据库的连接,导致这一个页面在脚本结束前会有多个数据库连接,在一些大型的页面连接可能多至数十上百,为此需要进行必要的控制,对于解释性的PHP语言,脚本是顺序执行的,也就是说数据库连接的利用同时只有一个,根据这个特点,可以用单例模式来进行改造。<?php class ConnecToDB { private static $instance; private function _constuct() { } //私有构造函数,防止外界构造新对象, public static function GetConnec() { if (!self::$instance instanceof self) { self::$instance =new self;//若当前对象实例不存在 } $temp=self::$instance; //获取当前单例 return $temp::Con() ; //调用对象私有方法连接 数据库 } //连接到数据库 private static function Con() { try { $connec=mysqli_connect("127.0.0.1", "root", "root"); //数据库地址和密码等 mysqli_select_db($connec, "dbname");//选择数据库 } catch (Exception $e) { echo $e->getMessage().'<br/>'; } return $connec; } } $db=new ConnecToDB(); $db->GetConnec();这是正确的单例代码<?php class Config1 {} class Config { /* * 必须先声明一个静态私有属性:用来保存当前类的实例 * 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享 * 2. 为什么必须是私有的?不允许外部直接访问,仅允许通过类方法控制方法 * 3. 为什么要有初始值null,因为类内部访问接口需要检测实例的状态,判断是否需要实例化 */ private static $instance = null; //保存用户的自定义配置参数 private $setting = []; //构造器私有化:禁止从类外部实例化 private function __construct(){} //克隆方法私有化:禁止从外部克隆对象 private function __clone(){} //因为用静态属性返回类实例,而只能在静态方法使用静态属性 //所以必须创建一个静态方法来生成当前类的唯一实例 public static function getInstance() { //检测当前类属性$instance是否已经保存了当前类的实例 if (self::$instance == null) { //如果没有,则创建当前类的实例 //self::$instance = new self(); self::$instance= new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME); self::$instance->set_charset('utf8'); } //如果已经有了当前类实例,就直接返回,不要重复创建类实例 return self::$instance; } //设置配置项 public function set($index, $value) { $this->setting[$index] = $value; } //读取配置项 public function get($index) { return $this->setting[$index]; } } //实例化Config类 $obj1 = Config::getInstance(); $obj2 = Config::getInstance(); var_dump($obj1,$obj2); $obj1->set('host','localhost'); echo $obj1->get('host');当然这个代码中,数据库的账号、密码等连接信息都是硬编码,可以通过改造GetConnec()函数注入相应的信息。通过这段脚本,就可以控制一个页面只有一次数据库连接。这就会减少mysql的连接数。但是虽然减少了单次请求的连接数,但是如果这个页面进行多次刷新的话,还是会生产大量mysql连接,降低性能,如图,页面进行多次刷新后,mysql连接数,出现很多:如何解决多次刷新情况下的大量连接呢,答案是用mysql长连接;我们把上面的代码的$connec=mysqli_connect("127.0.0.1", "root", "root"); //数据库地址和密码等 改为 $connec=mysqli_connect("p:127.0.0.1", "root", "root"); //数据库地址和密码等注意:上面的代码在IP地址前加了一个“p:”前缀,代表使用的是mysql长连接,修改完成后,我们再来多次刷新页面。如上图,只有2个连接了。解决成功。当然,除了用mysql的长连接外,还可以修改linux 内核参数的连接重用参数,也可以达到目的。用mysql长连接能大大提升性能,所以请务必使用mysql长连接。
2023年08月11日
16 阅读
0 评论
0 点赞
2023-08-10
PHP实现文件断点续传下载
PHP实现文件断点续传下载<?php //PHP 断点续传下载 function download($fileurl, $start = 0, $end = '') { $task_sourcefile = '/path/downfile.mp4'; //本地保存的文件 $sourceurl = $fileurl ; //要下载的远程文件 $tokenfile = 'downfile.token'; $isfileexist =$this->check_remote_file_exists($sourceurl); if (!$isfileexist) { $isfileexist2 =$this->check_remote_file_exists($sourceurl); if (!$isfileexist2) { throw new \Exception('远程文件不存在'); } } if (!is_dir(dirname($tokenfile))) { mkdir(dirname($tokenfile), 0777, true); } $sourcefilepath = dirname($task_sourcefile); if (!is_dir($sourcefilepath)) { @mkdir($sourcefilepath, 0777, true); } $ch = curl_init($sourceurl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, 'SyncTask'); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); //注意,超时一定要设置这个 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 3600); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300); curl_setopt($ch, CURLOPT_TIMEOUT, 600); //此选项,是下载超时时间,时间设置短的话,没有下载完,就会断开连接,然后再重新断点续传下载。如果设置过长,可能会发生由于网络原因产生的下载长时间卡住 的现象。请设置合理值。建议不要设置太长。 //curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100 * 1000); //超时毫秒 curl_setopt($ch, CURLOPT_BUFFERSIZE, 20971520); if ($end) { curl_setopt($ch, CURLOPT_RANGE, "$start-$end"); } else { curl_setopt($ch, CURLOPT_RANGE, "$start-"); } $flag=$tag = 0; curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $str) use (&$flag, $task_sourcefile, $end, $sourceurl, $tokenfile, $start, &$tag) { $len = strlen($str); $flag++; if ($flag==1) { $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); if ($length ==-1) { $tag = 2; return false; } if ($httpcode!=200 && $httpcode!=206) { $tag = 2; return false; } if ($start ==0) { $data= ['name'=>$sourceurl,'size'=>$length]; file_put_contents($tokenfile, <a class="wpal-linked-keyword" href="http://json.p2hp.com/" target="_blank">json</a>_encode($data, JSON_UNESCAPED_UNICODE)); } if ($end) { if ($end-$start!=$length) { $tag = 1; return false; } } } file_put_contents($task_sourcefile, $str, FILE_APPEND|LOCK_EX); return $len; }); $output = curl_exec($ch); if ($tag ==2 || $output===false) { curl_close($ch); clearstatcache(); download($fileurl, filesize($task_sourcefile), ''); } if ($tag ==1) { unlink($task_sourcefile); unlink($tokenfile); curl_close($ch); download($fileurl, 0, ''); return true; } $tokeninfo = json_decode(file_get_contents($tokenfile), true); $length = $tokeninfo['size']; sleep(1); clearstatcache();//这里要去除文件信息缓存 if ($length!= filesize($task_sourcefile)) { curl_close($ch); echo '下载出错:长度不长度不匹配~~'; clearstatcache(); download($fileurl, filesize($task_sourcefile), ''); } curl_close($ch); return true; } //run $download= download('http://www.test.com/333.mp4'); var_dump($download);
2023年08月10日
8 阅读
0 评论
0 点赞
2023-08-10
PHP获取远程http或ftp文件的md5值
PHP获取远程http或ftp文件的md5值获取本地文件的md5值:md5_file("/path/file.jpg");获取远程http文件的md5值:md5_file("https://www.baidu.com/img/bd_logo1.png")PHP获取远程ftp文件的md5值:md5_file("ftp://username:password@192.168.6.1/aa4c319f1b8197e381beeb8c45e6c68d.apk")如果远程文件很大的话,执行会非常费时,因为要先下载下来。
2023年08月10日
25 阅读
0 评论
0 点赞
2023-08-10
如何正确的用PHP进行url编码urlencode
如何正确的用PHP进行url编码urlencode<?php function myUrlEncode($string) { $entities = array('%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D'); $replacements = array('!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]"); return str_replace($entities, $replacements, rawurlencode($string)); } echo myUrlEncode('http://192.168.8.232/红尘情歌 高安.mp4'); //输出 http://192.168.8.232/%E7%BA%A2%E5%B0%98%E6%83%85%E6%AD%8C%20%E9%AB%98%E5%AE%89.mp4
2023年08月10日
14 阅读
0 评论
0 点赞
2023-08-10
PHP 用websocket实现客户端和服务器消息双向推送
PHP 用websocket实现客户端和服务器消息双向推送PHP 实现websockethtml代码<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>发送弹幕</title> <link href="https://cdn.bootcss.com/<a class="wpal-linked-keyword" href="https://bootstrap.p2hp.com/" target="_blank">bootstrap</a>/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-xs-1 col-sm-1 col-md-1 col-lg-1"> </div> <div class="col-xs-10 col-sm-10 col-md-10 col-lg-10"> <div class="form-group"> <p style="height:30px"></p> <div class="col-sm-2"> </div> <div class="col-sm-4"> <input type="text" class="form-control" id="barrage" name="barrage" placeholder="弹幕" value=""> </div> <div class="col-sm-4"> <button type="button" class="btn btn-primary" id="send">发送弹幕</button> </div> </div> <!-- 弹幕内容 --> <div class="form-group"> <p style="height:30px"></p> <textarea class="form-control" rows="20" id="content"></textarea> </div> </div> <div class="col-xs-1 col-sm-1 col-md-1 col-lg-1"> </div> </div> </div> </body> <script> $(document).ready(function () { var ws = new <a class="wpal-linked-keyword" href="https://websocket.p2hp.com/" target="_blank">WebSocket</a>("ws://127.0.0.1:9777"); ws.onopen = function () { console.log("握手成功"); } ws.onmessage = function (e) { var content = e.data; $('#content').append(content + "\n"); console.log(content); } ws.onerror = function () { console.log("error"); } $('#send').click(function (e) { e.preventDefault(); var barrage = $('#barrage').val(); ws.send(barrage); }); $('#barrage').bind('keypress', function (event) { if (event.keyCode == "13") { var barrage = $('#barrage').val(); ws.send(barrage); } }); }); </script> </html>PHP代码<?php class <a class="wpal-linked-keyword" href="https://socketio.p2hp.com/" target="_blank">Socket</a> { const BIND_NUM = 20; private $master; private $sockets = []; private $handshake = false; // 握手 public function __construct($address, $port) { try { // 创建 $this->master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); // 参数 socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1); socket_set_nonblock($this->master); // 绑定 socket_bind($this->master, $address, $port); // 监听 socket_listen($this->master, static::BIND_NUM); $this->sockets[] = $this->master; $pid = posix_getpid(); // 输出 $this->say("Server Started : " . date('Y-m-d H:i:s')); $this->say("Listening on : " . $address . " port " . $port); $this->say("Pid : " . $pid); $this->say("Master socket : " . $this->master . PHP_EOL); } catch (\Exception $e) { $this->error(); } while (true) { try { // 慢点 usleep(200000); $this->doServer(); } catch (\Exception $e) { $this->error(); } } } /** * 开始服务 */ public function doServer() { $write = $except = NULL; socket_select($this->sockets, $write, $except, NULL); //自动选择来消息的socket 如果是握手 自动选择主机 foreach ($this->sockets as $socket) { // 主机 if ($this->master == $socket) { $client = socket_accept($this->master); if ($client < 0) { $this->notice("socket_accept() failed"); continue; } else { $this->connect($client); } } else { // 非主机 $bytes = socket_recv($socket, $buffer, 2048, 0); if ($bytes == 0) { // 断开连接 $this->disConnect($socket); } else { if (!$this->handshake) { // 准备握手 $this->doHandShake($socket, $buffer); } else { // 发送消息 $buffer = $this->decode($buffer); $buffer='server say:'.$buffer; $this->send($socket, $buffer); } } } } } /** * 连接 * * @param $socket */ public function connect($socket) { array_push($this->sockets, $socket); $this->say("\n" . $socket . " CONNECTED!"); $this->say(date("Y-n-d H:i:s")); } /** * 断开连接 * * @param $socket */ public function disConnect($socket) { $index = array_search($socket, $this->sockets); socket_close($socket); $this->say($socket . " DISCONNECTED!"); if ($index >= 0) { array_splice($this->sockets, $index, 1); } } /** * 握手 * * @param $socket * @param $buffer * @return bool */ function doHandShake($socket, $buffer) { $this->say("\nRequesting handshake..."); $this->say($buffer); $key = ''; if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $buffer, $match)) { $key = $match[1]; } $this->say("Handshaking..."); $upgrade = "HTTP/1.1 101 Switching Protocol\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: " . $this->calcKey($key) . "\r\n\r\n"; //必须以两个回车结尾 $this->say($upgrade); socket_write($socket, $upgrade, strlen($upgrade)); $this->handshake = true; $this->say($key); $this->say("Done handshaking..."); return true; } /** * 基于websocket version 13 * * @param $key * @return string */ function calcKey($key) { $accept = base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); return $accept; } /** * 解密 * * @param $buffer * @return null|string */ function decode($buffer) { $len = $masks = $data = $decoded = null; $len = ord($buffer[1]) & 127; if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); } else if ($len === 127) { $masks = substr($buffer, 10, 4); $data = substr($buffer, 14); } else { $masks = substr($buffer, 2, 4); $data = substr($buffer, 6); } for ($index = 0; $index < strlen($data); $index++) { $decoded .= $data[$index] ^ $masks[$index % 4]; } return $decoded; } /** * 发送消息 * * @param $client * @param $msg */ function send($client, $msg) { $this->say("> " . $msg); $msg = $this->frame($msg); socket_write($client, $msg, strlen($msg)); $this->say("! " . strlen($msg)); } /** * 数据帧 * * @param $s * @return string */ function frame($s) { $a = str_split($s, 125); if (count($a) == 1) { return "\x81" . chr(strlen($a[0])) . $a[0]; } $ns = ""; foreach ($a as $o) { $ns .= "\x81" . chr(strlen($o)) . $o; } return $ns; } /** * 标准输出 * * @param string $msg */ public function say($msg = "") { echo $msg . PHP_EOL; } /** * 异常错误输出 */ public function error() { $error = socket_last_error(); $error_msg = socket_strerror($error); echo $error_msg . PHP_EOL; } /** * 普通错误输出 * * @param string $notice */ public function notice($notice = "") { echo $notice . PHP_EOL; } } new Socket('127.0.0.1', 9777);以上开多窗口可能有问题,下面这个没有问题https://www.cnblogs.com/jiangzuo/p/5896301.html
2023年08月10日
13 阅读
0 评论
0 点赞
1
...
19
20
21
...
28