首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
183 阅读
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
篇文章
累计收到
31
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2023-12-28
php redis的加锁与解锁
php redis的加锁与解锁这篇文章主要介绍了关于php redis的加锁与解锁,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下。php+redis 实现加锁与解锁操作业务背景:在房间棋牌游戏中需要用到锁来防止并发操作引起的 redis 数据脏读问题;例如添加用户进入房间的动作:并发的情况下,get RoomUsers 会有脏读现象;解决思路:加锁房间来实现 一个房间每次只允许一个客户端操作,其他并发客户端则等待;也就是-----堵塞锁;加锁:redis加锁方式有几种: incr、set、setnx、hSetnx,可以参考这篇文章: redis加锁的几种实现这里我用到 set 这种方式$roomId = $_GET['roomId']; $user = $_GET['user']; // '张三' $key = "LockRoom:{$roomId}"; $value = $roomId.uniqid(); $ex = 3; // 如果 $key 不存在的话,就设置 $key 的值为 $value,且有效期为 3s; // return TRUE / FALSE while(true){ $res = $this->redis->set($key, $value, ['nx', 'ex' => $ex]); if($res) { break; } usleep(5000); } // 将用户添加进房间 $roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五'] $roomUsers[] = $user; $this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']解锁:操作完当然要解锁了,不解锁起码要等待 3秒;解锁用 delete 删除 key; 但是这里有个坑,不能直接用 delete,因为假设 client01 获得了锁,在添加用户进入房间的过程中 时间超过了 3秒 ,这个时候client02 就会同样获得锁并且设置3S,然后当client01 操作完之后 delete key , 就把 client02 设置的锁删除了;这里推荐用 lua 代码执行删除,因为lua 执行具有原子性。// 将用户添加进房间 $roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五'] $roomUsers[] = $user; $this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三'] // lua 脚本解锁 // 先判断 key的值是否为 value, TRUE 才会删除, 所以 $value 的设计要有随机唯一性 $script = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end '; $this->redis->eval($script, array($key , $value), 1);具体还可以看看 这篇文章: 解锁 Redis 锁的正确姿势 还有php操作redis的文档:PhpRedis 里面有 set()、eval() 函数的解释注意:用 lua 脚本这里 php.ini 需要开放 shell_exec() 等系统函数以上代码仅作参考!!
2023年12月28日
8 阅读
0 评论
0 点赞
2023-12-28
php程序员学Swoole必要性
php程序员学Swoole必要性对于PHP程序员来说,Swoole是一个极具吸引力的技术,Swoole是一个针对PHP语言的高性能网络通信框架,它的存在使得PHP的网络编程能力得到了极大的提升。Swoole的原理是将常规的PHP模式转换成Swoole模式,实现底层IO的异步处理,通过EventLoop可以实现高效的异步、高并发的IO操作,大大提高了程序性能。课程地址(https://www.php.cn/course/1544.html)那么,PHP程序员为什么要学习Swoole呢?1.提高性能随着互联网的快速发展,服务器的性能要求也越来越高,而Swoole是目前最为优秀的PHP高性能网络编程框架之一,它可以大幅度提升PHP服务器的性能。PHP用户只需要按照Swoole的规范来编写代码,最终运行在Swoole的服务上,即可得到大幅提升的性能,从而使PHP程序员在企业中更有竞争力。2.支持高并发Swoole采用异步非阻塞I/O处理,可以让我们最大化地利用服务器资源,实现高并发的支持。在同等硬件条件下,使用Swoole开发的服务器可以比传统PHP服务器提供更高的并发处理能力,有效提升应用的整体性能。3.支持协程Swoole中支持协程,在处理并发问题方面非常有优势。协程是一种非常轻量级的线程,一个进程可以创建上万个协程,不会像进程和线程一样消耗大量的资源。在Swoole的框架中,协程被充分利用,可以在一个协程中让出CPU的控制权给其他代码,比如IO操作,网络请求等,以此来充分利用服务器资源。4.大量组件库扩展除了提供高性能的异步编程能力,Swoole还自带一些常见的组件库,基本可以满足开发常用的应用,如MySQL、Redis、WebSocket、Process等,使开发者无需重复造轮子,大幅度提高了开发效率。总之,对于PHP程序员来说,掌握Swoole,能够在开发Web应用和后台服务的时候,极大地提高程序的性能、并发能力和可靠性,大幅提升开发者的职业竞争力,是一项非常有用的技能。所以,作为PHP程序员,我们不能错过这个机会,要认真学习和使用Swoole,并将其应用到实际的开发中去。今天给大家带来了我们的Swoole入门到实战课程课程1《swoole从入门到精通(第一季)》本课程共有11章,47节课程,为你从安装到使用全方位讲解swoole。课程地址:https://www.php.cn/course/1544.html长按二维码进入购买地址课程2:Swoole实战课程《swoole项目实战(第二季)》本课程有三个swoole实战:swoole实战电影院选座实时展示swoole实战视频直播弹幕swoole实战多进程消息队列协程爬取链家房产信息课程地址:https://www.php.cn/course/1545.html其他课程PHP+Swoole实现物联网开发
2023年12月28日
24 阅读
0 评论
0 点赞
2023-12-28
环境安装相关文章
php快如闪电的安装PHP8.2套件(centos stream9) 快速安装php8.2套件(ubuntu 20.04 focal)
2023年12月28日
7 阅读
0 评论
0 点赞
2023-12-28
一个PHP实现的轻量级简单爬虫
一个PHP实现的轻量级简单爬虫最近需要收集资料,在浏览器上用另存为的方式实在是很麻烦,而且不利于存储和检索。所以自己写了一个小爬虫,在网上爬东西,迄今为止,已经爬了近百万张网页。现在正在想办法着手处理这些数据。爬虫的结构:爬虫的原理其实很简单,就是分析下载的页面,找出其中的连接,然后再下载这些链接,再分析再下载,周而复始。在数据存储方面,数据库是首选,便于检索,而 开发语言,只要支持正则表达式就可以了,数据库我选择了mysql,所以,开发脚本我选择了php。它支持perl兼容正则表达式,连接mysql很方 便,支持http下载,而且windows系统和linux系统都可以部署。正则表达式:正则表达式是处理文字的基本工具,要取出html中的链接和图片,使用的正则表达式如下。代码如下:"#<a1+href=(['\"])(.+)\1#isU" 处理链接"#<img[^>]+src=(['\"])(.+)\\1#isU" 处理图片其他问题: 写爬虫还需要注意的一个问题是,对于已经下载过的url,不能重复进行下载,而有些网页的链接会形成环路,所以需要处理这个问题,我的处理方法是计算已经 处理的url的MD5 值,并存入数据库,这样就可以检验是否已经下载过。当然还有更好的算法,有兴趣的话,可以在网上找一下。相关协议: 爬虫也有自己的协议,有个robots.txt文件定义了那些是网站允许遍历的,但是由于我的时间有限,没有实现这个功能。其他说明: php支持类编程,我写的爬虫主要的类. 1.url处理web_site_info,主要用处理url,分析域名等。2.数据库操作mysql_insert.php,处理和数据库相关的操作。3.历史记录处理,记录已经处理的url。4.爬虫类。存在的问题和不足这个爬虫在小数据量的情况下,运行良好,但是在大数据量的情况下,历史记录处理类的效率就不是很高,通过在数据库结构中,对相关字段进行了索引,速度有了 提高,但是需要不断得读取数据,可能和php本身的array实现有关系,如果一次加载10万条历史记录,速度非常慢。不支持多线程,每次只能处理一个url。php运行本身有内存使用量限制 使用的时候,先在mysql中创建net_spider数据库,然后用db.sql创建相关表。再在config.php中设置mysql 的用户名口令。最后 代码如下:php -f spider.php 深度(数值) url就可以开始工作。代码如下: php -f spider.php 20现在感觉下来,其实做个爬虫没那么复杂,难的是数据的存储和检索。我现在的数据库,最大一个数据表已经15G,正在想办处理这些数据,mysql进 行查询已经感觉有点力不从心了。这点上还真佩服google<?php加载页面function curl_get($url){$ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HEADER,1); $result=curl_exec($ch); $code=curl_getinfo($ch,CURLINFO_HTTP_CODE); if($code!='404' && $result){ return $result; } curl_close($ch);}获取页面url链接function get_page_urls($spider_page_result,$base_url){ $get_url_result=preg_match_all("/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\]*).*?>/",$spider_page_result,$out); if($get_url_result){return $out[1];}else{return;}}相对路径转绝对路径function xdtojd($base_url,$url_list){ if(is_array($url_list)){ foreach($url_list as $url_item){if(preg_match("/^(http:\/\/|https:\/\/|javascript:)/",$url_item)){ $result_url_list[]=$url_item; }else { if(preg_match("/^\//",$url_item)){ $real_url = $base_url.$url_item; }else{ $real_url = $base_url."/".$url_item; } #$real_url = 'http://www.sumpay.cn/'.$url_item; $result_url_list[] = $real_url; }} return $result_url_list; }else{ return; }}删除其他站点urlfunction other_site_url_del($jd_url_list,$url_base){ if(is_array($jd_url_list)){ foreach($jd_url_list as $all_url){echo $all_url; if(strpos($all_url,$url_base)===0){ $all_url_list[]=$all_url; } } return $all_url_list; }else{ return; }}删除相同URLfunction url_same_del($array_url){ if(is_array($array_url)){ $insert_url=array(); $pizza=file_get_contents("/tmp/url.txt"); if($pizza){ $pizza=explode("\r\n",$pizza); foreach($array_url as $array_value_url){ if(!in_array($array_value_url,$pizza)){ $insert_url[]=$array_value_url; } } if($insert_url){ foreach($insert_url as $key => $insert_url_value){ #这里只做了参数相同去重处理 $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); foreach($pizza as $pizza_value){ $update_pizza_value=preg_replace('/=[^&]*/','=leesec',$pizza_value); if($update_insert_url==$update_pizza_value){ unset($insert_url[$key]); continue; } } } } }else{ $insert_url=array(); $insert_new_url=array(); $insert_url=$array_url; foreach($insert_url as $insert_url_value){ $update_insert_url=preg_replace('/=[^&]*/','=leesec',$insert_url_value); $insert_new_url[]=$update_insert_url; } $insert_new_url=array_unique($insert_new_url); foreach($insert_new_url as $key => $insert_new_url_val){ $insert_url_bf[]=$insert_url[$key]; } $insert_url=$insert_url_bf; } return $insert_url;}else{return; }}$current_url=$argv[1];$fp_puts = fopen("/tmp/url.txt","ab");//记录url列表 $fp_gets = fopen("/tmp/url.txt","r");//保存url列表 $url_base_url=parse_url($current_url);if($url_base_url['scheme']==""){ $url_base="http://".$url_base_url['host'];}else{ $url_base=$url_base_url['scheme']."://".$url_base_url['host'];}do{ $spider_page_result=curl_get($current_url); #var_dump($spider_page_result); $url_list=get_page_urls($spider_page_result,$url_base); #var_dump($url_list); if(!$url_list){ continue; } $jd_url_list=xdtojd($url_base,$url_list); #var_dump($jd_url_list); $result_url_arr=other_site_url_del($jd_url_list,$url_base); var_dump($result_url_arr); $result_url_arr=url_same_del($result_url_arr); #var_dump($result_url_arr); if(is_array($result_url_arr)){$result_url_arr=array_unique($result_url_arr); foreach($result_url_arr as $new_url) { fputs($fp_puts,$new_url."\r\n"); }}}while ($current_url = fgets($fp_gets,1024));//不断获得url preg_match_all("/<a1+href=\"'[\"']1+>/",$spider_page_result,$out);echo a hrefvar_dump($out[1]);?>> ↩\"' ↩
2023年12月28日
5 阅读
0 评论
0 点赞
2023-12-28
composer相关文章
教你发布自己的composer包(步骤详解)
2023年12月28日
6 阅读
0 评论
0 点赞
1
...
28
29
30
...
112