首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
138 阅读
2
php接口优化 使用curl_multi_init批量请求
130 阅读
3
2024年备考系统架构设计师
102 阅读
4
《从菜鸟到大师之路 ElasticSearch 篇》
101 阅读
5
PHP 文件I/O
89 阅读
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
累计撰写
785
篇文章
累计收到
7
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
785
篇与
的结果
2023-08-09
PHP编程中的锁
PHP编程中的锁最近看了《理解Linux进程》这本开源书,链接。该书描述了linux中的进程概念,对锁和进程间通信(IPC)有一些总结。不过该书的描述语言是golang, 平时用的比较少,就想对应概念找找php中的接口。文件锁全名叫 advisory file lock, 书中有提及。 这类锁比较常见,例如 mysql, php-fpm 启动之后都会有一个pid文件记录了进程id,这个文件就是文件锁。这个锁可以防止重复运行一个进程,例如在使用crontab时,限定每一分钟执行一个任务,但这个进程运行时间可能超过一分钟,如果不用进程锁解决冲突的话两个进程一起执行就会有问题。使用PID文件锁还有一个好处,方便进程向自己发停止或者重启信号。例如重启php-fpm的命令为kill -USR2 cat /usr/local/php/var/run/php-fpm.pid发送USR2信号给pid文件记录的进程,信号属于进程通信,会另开一个篇幅。php的接口为flock,文档比较详细。先看一下定义,bool flock ( resource $handle , int $operation [, int &$wouldblock ] ).$handle是文件系统指针,是典型地由 fopen() 创建的 resource(资源)。这就意味着使用flock必须打开一个文件。$operation 是操作类型。&$wouldblock 如果锁是阻塞的,那么这个变量会设为1.需要注意的是,这个函数默认是阻塞的,如果想非阻塞可以在 operation 加一个 bitmask LOCK_NB. 接下来测试一下。$pid_file = "/tmp/process.pid";$pid = posix_getpid();$fp = fopen($pid_file, 'w+');if(flock($fp, LOCK_EX | LOCK_NB)){echo "got the lock \n"; ftruncate($fp, 0); // truncate file fwrite($fp, $pid); fflush($fp); // flush output before releasing the lock sleep(300); // long running process flock($fp, LOCK_UN); // 释放锁定} else {echo "Cannot get pid lock. The process is already up \n";}fclose($fp);保存为 process.php,运行php process.php &, 此时再次运行php process.php,就可以看到错误提示。flock也有共享锁,LOCK_SH.互斥锁和读写锁sync模块中的MutexMutex是一个组合词,mutual exclusion。用pecl安装一下sync模块, pecl install sync。 文档中的SyncMutex只有两个方法,lock 和 unlock, 我们就直接上代码测试吧。没有用IDE写,所以cs异常丑陋,请无视。$mutex = new SyncMutex("UniqueName");for($i=0; $i<2; $i++){$pid = pcntl_fork(); if($pid <0){ die("fork failed"); }elseif ($pid>0){ echo "parent process \n"; }else{ echo "child process {$i} is born. \n"; obtainLock($mutex, $i); }}while (pcntl_waitpid(0, $status) != -1) {$status = pcntl_wexitstatus($status); echo "Child $status completed\n"; }function obtainLock ($mutex, $i){echo "process {$i} is getting the mutex \n"; $res = $mutex->lock(200); sleep(1); if (!$res){ echo "process {$i} unable to lock mutex. \n"; }else{ echo "process {$i} successfully got the mutex \n"; $mutex->unlock(); } exit();}保存为mutex.php, run php mutex.php, output isparent process parent process child process 1 is born. process 1 is getting the mutex child process 0 is born. process 0 is getting the mutex process 1 successfully got the mutex Child 0 completedprocess 0 unable to lock mutex. Child 0 completed这里子进程0和1不一定谁在前面。但是总有一个得不到锁。这里SyncMutex::lock(int $millisecond)的参数是 millisecond, 代表阻塞的时长, -1 为无限阻塞。sync模块中的读写锁SyncReaderWriter的方法类似,readlock, readunlock, writelock, writeunlock,成对出现即可,没有写测试代码,应该和Mutex的代码一致,把锁替换一下就可以。sync模块中的Event感觉和golang中的Cond比较像,wait()阻塞,fire()唤醒Event阻塞的一个进程。有一篇好文介绍了Cond, 可以看出Cond就是锁的一种固定用法。SyncEvent也一样。php文档中的例子显示,fire()方法貌似可以用在web应用中。上测试代码for($i=0; $i<3; $i++){$pid = pcntl_fork(); if($pid <0){ die("fork failed"); }elseif ($pid>0){ //echo "parent process \n"; }else{ echo "child process {$i} is born. \n"; switch ($i) { case 0: wait(); break; case 1: wait(); break; case 2: sleep(1); fire(); break; } }}while (pcntl_waitpid(0, $status) != -1) {$status = pcntl_wexitstatus($status); echo "Child $status completed\n"; }function wait(){$event = new SyncEvent("UniqueName"); echo "before waiting. \n"; $event->wait(); echo "after waiting. \n"; exit();}function fire(){$event = new SyncEvent("UniqueName"); $event->fire(); exit();}这里故意少写一个fire(), 所以程序会阻塞,证明了 fire() 一次只唤醒一个进程。pthreads模块貌似也看到了Mutex, Cond, Pool. 没来得及看,看完再补充。信号量sync模块中的信号量SyncSemaphore文档中显示,它和Mutex的不同之处,在于Semaphore一次可以被多个进程(或线程)得到,而Mutex一次只能被一个得到。所以在SyncSemaphore的构造函数中,有一个参数指定信号量可以被多少进程得到。public SyncSemaphore::__construct ([ string $name [, integer $initialval [, bool $autounlock ]]] ) 就是这个$initialval (initial value)$lock = new SyncSemaphore("UniqueName", 2);for($i=0; $i<2; $i++){$pid = pcntl_fork(); if($pid <0){ die("fork failed"); }elseif ($pid>0){ echo "parent process \n"; }else{ echo "child process {$i} is born. \n"; obtainLock($lock, $i); }}while (pcntl_waitpid(0, $status) != -1) {$status = pcntl_wexitstatus($status); echo "Child $status completed\n"; }function obtainLock ($lock, $i){echo "process {$i} is getting the lock \n"; $res = $lock->lock(200); sleep(1); if (!$res){ echo "process {$i} unable to lock lock. \n"; }else{ echo "process {$i} successfully got the lock \n"; $lock->unlock(); } exit();}这时候两个进程都能得到锁。sysvsem模块中的信号量sem_get 创建信号量sem_remove 删除信号量(一般不用)sem_acquire 请求得到信号量sem_release 释放信号量。和 sem_acquire 成对使用。$key = ftok('/tmp', 'c');$sem = sem_get($key);for($i=0; $i<2; $i++){$pid = pcntl_fork(); if($pid <0){ die("fork failed"); }elseif ($pid>0){ //echo "parent process \n"; }else{ echo "child process {$i} is born. \n"; obtainLock($sem, $i); }}while (pcntl_waitpid(0, $status) != -1) {$status = pcntl_wexitstatus($status); echo "Child $status completed\n"; }sem_remove($sem); // finally remove the semfunction obtainLock ($sem, $i){echo "process {$i} is getting the sem \n"; $res = sem_acquire($sem, true); sleep(1); if (!$res){ echo "process {$i} unable to get sem. \n"; }else{ echo "process {$i} successfully got the sem \n"; sem_release($sem); } exit();}这里有一个问题,sem_acquire()第二个参数$nowait默认为false,阻塞。我设为了true,如果得到锁失败,那么后面的sem_release会报警告 PHP Warning: sem_release(): SysV semaphore 4 (key 0x63000081) is not currently acquired in /home/jason/sysvsem.php on line 33, 所以这里的release操作必须放在得到锁的情况下执行,前面的几个例子中没有这个问题,没得到锁执行release也不会报错。当然最好还是成对出现,确保得到锁的情况下再release。此外,ftok这个方法的参数有必要说明下,第一个 必须是existing, accessable的文件, 一般使用项目中的文件,第二个是单字符字符串。返回一个int。输出为parent process parent process child process 1 is born. process 1 is getting the mutex child process 0 is born. process 0 is getting the mutex process 1 successfully got the mutex Child 0 completedprocess 0 unable to lock mutex. Child 0 completed最后,如果文中有错误的地方,希望大神指出,帮助一下菜鸟进步,谢谢各位。
2023年08月09日
18 阅读
0 评论
0 点赞
2023-08-09
PHP 收藏集
收藏集PHP 收藏集(一)csdnPHP 收藏集(二)Awesome PHP其他文章ThinkPHPhttps://blog.p2hp.com/archives/11222 ThinkPHPV8.0发布——AI助力开发体验一些laravel 框架学习资源http://www.cnblogs.com/yjf512/p/4061892.html 使用laravel一分钟搭建CURD后台页面https://www.laravist.com/blog/post/programming-with-laravel-5-model-controller-view-basic-workflow Laravel教程 五:MVC的基本流程https://www.laravist.com/blog/post/programming-with-laravel-5-laravel-forms-input Laravel教程 六:表单 Formshttps://www.laravist.com/blog/post/programming-with-laravel-5-database-and-eloquent-model Laravel教程 四:数据库和Eloquenthttps://my.oschina.net/u/1186749/blog/643850 php artisan常用方法http://www.verronknowles.com/laravel-migrations-with-moloquent-and-mongodb-with-mysql-still-present/http://www.opentechguides.com/tutorials/laravel-mongodb/10/mongodb-migration.htmlhttp://blog.sina.com.cn/s/blog_a77576280102x60a.htmlhttp://www.jb51.net/article/54736.htmhttp://blog.csdn.net/iroycn/article/details/47036719http://www.jb51.net/article/60989.htmhttps://blog.p2hp.com/archives/7442https://blog.p2hp.com/archives/7392 加速你的laravel框架运行, 教你如何减少服务提供者的启动.https://blog.p2hp.com/archives/7523https://blog.p2hp.com/archives/7551 使用Laravel Packer创建laravel包脚手架https://blog.p2hp.com/archives/7853 Laravel Model 利用 Macroable 为数据模型添加宏能力https://blog.p2hp.com/archives/7829 Laravel Telescope 完美的应用调试工具https://blog.p2hp.com/archives/8110 Laravel框架的Pipeline解读。它是一个非常好用的组件,能够使代码的结构非常清晰。 Laravel的中间件机制便是基于它来实现的。通过Pipeline,可以轻松实现APO编程。https://blog.p2hp.com/archives/7883 终极Laravel应用性能检查表https://blog.p2hp.com/archives/8122 Laravel框架中使用 Repository 模式Lhttps://blog.p2hp.com/archives/8120 aravel核心解读–服务提供器(ServiceProvider)https://blog.p2hp.com/archives/8114 优化laravel数据库查询的 18 个提示https://blog.p2hp.com/archives/8821 Laravel 的 ORM 缓存包https://blog.p2hp.com/archives/8677 18 个 Laravel 8 数据库查询优化建议https://blog.p2hp.com/archives/10241 Laravel 10 现已发布!新特性一览了解 Laravel 的 Macroable 特性https://blog.p2hp.com/archives/11067https://blog.p2hp.com/archives/11065框架关于如何正确使用PHP框架及如何选择框架之我见微信开发关于微信网页授权获取用户基本信息的切入问题 微信公众平台—-带参数二维码生成和扫描事件 微信开发上传图文消息内的图片(只返回图片URL),报错41005 【微信开发】网页授权多域名解决方案服务器php在Nginx环境下进行刷新缓存立即输出,实现常驻进程轮询 php nginx 实时输出 https://blog.p2hp.com/archives/5808 解决PHP的一个长期存在的通过Opcache泄漏敏感数据的问题。 https://blog.p2hp.com/archives/5789 为PHP-FPM和nginx设置多个进程池而安全地运行多个网站https://blog.p2hp.com/archives/5778 nginx不同站点的php-fpm的PHP_ADMIN_VALUE值会覆盖其它站点值的问题!https://blog.p2hp.com/archives/5814 共享APC或OPcache:为什么多个PHP-FPM主机更好https://blog.p2hp.com/archives/7768 nginx + php做服务,在高并发的时候会出现一些错误 connect() to unix:/var/run/php-fpm.sock failed (11: Resource temporarily unavailable) 。mongodb用PHP把 图片,文件上传到 mongodb gridfs 中中间件为什么要关心PHP中间件 关于中间件的一切 漫谈php框架之中间件 在PHP中实现前置/后置中间件其他周末有空,我们来聊聊几块钱的PHP 原 PHP 在不调用构造函数的情况下创建对象 https://learnku.com/php/t/24576https://blog.p2hp.com/archives/6655 PHP加密文件解密过程详解https://blog.p2hp.com/archives/6648 PHP获取类私有属性的几种方式https://blog.p2hp.com/archives/7061【PHP】获取浏览器HTTP请求header信息、获取服务器HTTP响应header信息https://blog.p2hp.com/archives/7364 php设置跨子域名可读的cookiePHP 生成器入门 https://blog.p2hp.com/archives/7243模仿laravel,使用反射来实现自动依赖注入 https://www.jianshu.com/p/9176b12eb843https://stitcher.io/blog/php-in-2020PHP8.0 JIT介绍,及如何在PHP 8中设置JIT https://blog.p2hp.com/archives/7577如何处理 PHP 中file_get_contents 函数的警告?https://blog.p2hp.com/archives/7846Zend Engine中的函数内联-使用完全限定函数名称提高PHP程序性能 https://blog.p2hp.com/archives/7967 Zend PHP8.1发布,新特性一览 https://blog.p2hp.com/archives/8224Laravel 8更改密码功能实现 https://blog.p2hp.com/archives/8210如何优化symfony(PHP)的性能 https://blog.p2hp.com/archives/8196How Livewire works (a deep dive) https://blog.p2hp.com/archives/8190移除无用的Composer加载文件,以提升性能 https://blog.p2hp.com/archives/8178现代 PHP 数据加密/解密与Sodium扩展 https://blog.p2hp.com/archives/8174PHP–激动人心的时代即将到来,让我们来看看现代的 PHP https://blog.p2hp.com/archives/8310Modern PHP Without a Framework–现代PHP不使用框架 https://blog.p2hp.com/archives/9205PHP 8.2 新特性 https://blog.p2hp.com/archives/9144PHP mysqli 查询数据库的几个方法 https://blog.p2hp.com/archives/90632023 年的 PHP https://blog.p2hp.com/archives/10124如何延长遗留 PHP 应用程序的生命周期 https://blog.p2hp.com/archives/10122Nginx 黑魔法:使用 NGX-PHP 模块低成本实现高性能应用 https://blog.p2hp.com/archives/10540https://blog.p2hp.com/archives/10282https://blog.p2hp.com/archives/10279https://blog.p2hp.com/archives/10268spatie / invade 使用私有属性和方法的 PHP 函数 https://blog.p2hp.com/archives/11069知识点web全栈大福袋 https://www.52fun.com/13860.htmlhttps://www.itresource.org/2023/08/03/web3.0热门领域nft项目实战完结/
2023年08月09日
12 阅读
0 评论
0 点赞
2023-08-09
PHP The Right Way 中文版本
PHP The Right Way(PHP 之道) 中文版本
2023年08月09日
15 阅读
0 评论
0 点赞
2023-08-08
被swoole坑哭的PHP程序员
被swoole坑哭的PHP程序员首先说一下对swoole的理解:披着PHP外衣的C程序。很多PHPer朋友看到swoole提供的强大功能、外界对其的崇拜便跃跃欲试的安装、调 试其demo、编写新功能,然后兴奋的奔走相告。本文主要记录一下学习swoole的过程、填过的坑以及swoole究竟有多么强大!首先说一下对swoole的理解:披着PHP外衣的C程序。很多PHPer朋友看到swoole提供的强大功能、外界对其的崇拜便跃跃欲试的安装、调 试其demo、编写新功能,然后兴奋的奔走相告。没过几天当你按照自己的理解继续用swoole时,发现代码并没有按照自己的预期运行,然后开始破口大 骂,什么破东西呀,代码跟demo基本一样,为啥运行不通呢?什么狗屁work、task、共享内存、ipcs、异步,各种问题涌现,然后迅速去查官方文 档,发现文档中竟然对这些并没有提及,只是简单的介绍怎么使用,此时几乎对swoole丧失希望。被swoole坑哭的PHP程序员遇到的几点问题:1:关于phper常用的全局变量(global)为什么在onRequest函数中不能使用。因为swoole是多线程编程,global是不能在多个进程间共享的。例global $i = 0;function onRequest() {echo $i++;}如果在swoole中写一个上面的程序,并不会每次访问输出一个递增的数字。如果要实现预期的效果,需要使用swoole_table的相关函数。2:什么是异步、什么是回高对于phper来说,对异步、回调的理解估计就是ajax。当看到swoole里面对异步、回调的解释,貌似很简单的样子,就这样在没有任何多线程编辑经验的时候贸然用了swoole,结果被坑的偷偷撸代码好几个通宵来填自己的坑。3:为什么onReceive收到的数据这么大客户端发送的多次请求,服务端是可以一次性接收的。并不是客户端发送一次,服务端接收一次4:自制httpserve写一个http服务端,然后通过浏览器访问这个自制的服务器,刷新一次浏览器,服务端为什么为接收到两次请求?这个问题估计困饶了好多初次用swoole写httpserver的朋友。因为浏览器会多发一个favicon.ico请求。原因出现这种情况的原因其实很简 单,大部分phper都只会php这一种语言,主要用途就是做web,写业务逻辑。很少去了解服务器程序的开发。有一次一个朋友用swoole写了一个简 单的服务端,一个客户端,跑过来问我为什么都启动了却都收不到数据,我简单看了下代码,所有连接确实都成功了,两端都设置了onReceive回调,代码 没问题,看到最后才发现他的服务端、客户端都设置了接到消息的回调函数,但是两端都没有向对方发消息,两端处于僵持状态。然后swoole官方对于这种常 识问题没有给出说明,只是说如何设置回调、如何发消息,如何这样,如何那样。对于有服务端开发经验的同学来说,肯定不会遇到这种问题,swoole文档也 不需要指明需要这样做,因为这是常识。但对于phper来说,指明这一点是非常重要的,因为如上面所说phper是没有这方面认知的,只有服务端开发经验 的程序员有才会有。swoole的特色:网络通信 框架、异步、多线程。这些特性正是php所不完善的功能(虽然官方提供很多基础函数可以实现这些功能,然后缺少中文文档,很少有人用php来实现这部分功 能),普通的phper也不具备这些特性的基础认知,所以贸然使用swoole难免会遇到一些根本在swoole官方查不到的常识问题。使用swoole必须要掌握的技能多线程编程进程间通信网络协议TCP/UDP的认知PHP的各项基本技能个人学习swoole的经历在很久之前我也是一个只会 php的程序员,后来一次偶然机会需要用httpsqs,用了一段时间后发现有一些个性的需求,于是就开始看源码。这真是不看不知道,一看吓一 跳,httpsqs只是一层简单的包装,内部是一个Tokyo Cabinet数据库,印象中封装的代码也就一百多行。主要思路就是用C语言的libevent做了一个http服务器,接收请求读写tokyo cabinet数据库,当时按照这种思路做出来的程序确实不少。后来我就突发奇想,既然C语言可以用libevent函数,那PHP肯定也可以用 libevent监听网络,接收请求后读写数据库做队列服务。后来经过查php官方文档,PHP确实提供一系统完整的函数来完成这些功能,甚至多线程的全 套函数都有提供,但中文文档太少,网上也很少搜索到成熟的代码。在逼不得已的情况下,补习了linux-C多线程开发的基本原理,进程间通信的常用方法, 也用来做了一些简单的demo。唯一的感觉就是写一个简单的功能,设计起来还真复杂。就在快要放弃的时候,swoole出现了。swoole所提供的功能 正是php所缺失的功能,简直是太棒了。swoole做为一种网络通信框架,只需要简单的几行设置,一个服务器就搭建起来了,以后就是不断的去完善业务代 码。之前在libevent交流群中得知swoole的设计在c\c++中并不是最好的框架设计,但其亮点就是把基本功能用C封装好,业务功能留给世界上 最好的语言PHP来编写。自此便开始了swoole的填坑之旅。总结swoole并不是一个简单的PHP框架,正如swoole官方首页的第一句话“重新定义PHP”,千万不要用旧有php的思想来写swoole代码!swoole重新激活了PHP,php成就了swoole!
2023年08月08日
9 阅读
0 评论
0 点赞
2023-08-08
关于PHP程序员解决问题的能力
关于PHP程序员解决问题的能力这个话题老生长谈了,在面试中必然考核的能力中,我个人认为解决问题能力是排第一位的,比学习能力优先级更高。解决问题的能力既能看出程序员的思维能力,应变能力,探索能力等,又可以看出他的经验。如果解决问题能力不佳是无法通过面试的。这里举个例子,假如我执行了一个PHP的脚本,如php test.php,预期是可以返回一个字符串。但执行后没有任何信息输出,这时候通过什么方法能知道程序错在哪里?这里可以将解决问题能力分为8个等级,越到后面的表示能力越强。Lv0 查看PHP错误信息程序没有达到预期效果,证明代码出错了,看PHP的错误信息是第一步。如果直接忽略错误信息,表明这个人不适合担任专业的程序员岗位。有些情况下php.ini配置中关闭了错误显示,需要修改php.ini打开错误信息,或者错误信息被导出到了日志文件,这种情况可以直接tailf php_error.log来看错误信息。拿到错误信息后直接定位到程序代码问题,或者到Google/百度搜索,即可解决问题。注:打开错误显示的方法是php.ini中display_errors / display_startup_errors 设置为Onphp.ini中error_reporting 设置为E_ALLPHP代码中设置error_reporting(E_ALL)Lv1 存在多个版本的php或php-cli与php-fpm加载不同的配置存在多个版本的php,懂得通过which php来看是哪个PHP,或者加绝对路径制定php版本。表示此PHPer通过了此层级的50%考验。另外一个情况就是php-cli与php-fpm得到的执行情况不一样,如在web浏览器中执行是对的,cli下执行是错的。这时候可能是2个环境加载的php.ini不同所致。cli下通过php -i |grep php.ini得到加载了哪个php.ini。而fpm下通过phpinfo()函数可以得到php.ini的绝对路径。Lv2 var_dump/die打印变量值信息单步调试这是惯用的程序调试手段,也是最简单粗暴有效的解决问题方法。高级一点的手段是使用PHP的Trace类/日志类,花哨一点的可以借助phpstorm+xdebug在IDE工具里进行Debug。Trace工具还可以分析脚本的耗时,进行PHP程序的性能优化。这3个考验全部通过,表明此程序员已经具备了专业PHP程序员应该有的解决问题能力了。PHP程序员只要过了这个等级,就足以应多大部分情况,在中小型网站中毫无压力。Lv3 使用strace工具跟踪程序执行strace可以用来查看系统调用的执行,使用strace php test.php,或者strace -p 进程ID。strace就可以帮助你透过现象看本质,掌握程序执行的过程。这个手段是在大型网站,大公司里最常用的。如果没掌握strace,这里只能说抱歉了,我们不接受不会strace的PHPer。strace其实也是对程序员基础的考验,如果不懂操作操作系统,完全不懂底层,肯定也达不到会用strace的程度。当然strace对于PHP代码里的死循环是解决不了的。比如你发现一个php-fpm进程CPU100%了,strace恐怕是解决不了的。因为strace是看系统调用,一般都是IO类操作,既然是IO密集,那CPU一定不可能是100%。Lv4 使用tcpdump工具分析网络通信过程tcpdump可以抓到网卡的数据通信过程,甚至数据内容也可以抓到。使用tcpdump可以看到网络通信过程是什么样的,如何时发起了TCP SYN3次握手,何时发送FIN包,何时发送RST包。这是一个基本功,如果不懂tcpdump,证明不具备网络问题解决能力。Lv5 统计函数调用的耗时和成功率使用xhporf/xdebug导出PHP请求的调用过程,然后分析每个函数调用的过程和耗时。能够分析PHP程序的性能瓶颈,找出可以优化的点。另外一个对于网络服务的调用,如mysql查询,curl,其他API调用等,通过记录起始和结束时microtime,返回的是不是false,可以得到调用是否成功,耗时多少。如果可以汇总数据,整理出调用的成功率,失败率,平均延时,证明此程序员对接口质量敏感,有大型网站项目经验。Lv6 gdb使用gdb是C/C++调试程序的利器,需要具备一定C/C++功底的程序员才会能熟练使用gdb。上面说的strace无法跟踪php程序CPU100%,而gdb是可以跟踪的。另外gdb也可以解决php程序core dump的问题。通过gdb -p 进程ID,再配合php-src的.gdbinit zbacktrace等工具,可以很方便地跟踪PHP程序的执行。像上面的CPU100%往往是PHP程序中发生死循环了,gdb进行多次查看,就大致可以得到死循环的位置。具备gdb解决问题能力的PHP程序员少之又少。如果能使用gdb解决PHP问题,这个PHPer百分之百可以通过面试,并且可以拿到较高的技术评级。Lv7 查看PHP内核和扩展源码如果能熟悉PHP内核和扩展的源码,遇到PHP程序中最复杂的内存错误,也可以有解决的能力。这类PHP程序员就是凤毛麟角了。配合gdb工具和对PHP源码的熟悉,可以查看opcode的信息,execute_data的内存,全局变量的状态等。
2023年08月08日
12 阅读
0 评论
0 点赞
1
...
109
110
111
...
157