简单PHP性能记录工具

简单PHP性能记录工具

最近写了一个异步mysql客户端的封装,想与传统的串行方式做下性能对比。包括运行时间、内存使用情况等信息。在github和packagist上搜索并没有找到自己想要的,xhprof又太大了,结果也太复杂,不符合现在的需要。所以决定自己写一个package,来实现对php脚本运行时间和内存使用情况的监控,并生成报告。 项目地址:https://github.com/huyanping/php-timer   示例代码:   require dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; //初始化,设置内存单位 $timer = new \Jenner\Timer(\Jenner\Timer::UNIT_KB); //记录a状态 $timer->mark('a'); sleep(2); //记录b状态 $timer->mark('b'); sleep(3); //记录c状态 $timer->mark('c'); sleep(4); //记录d状态 $timer->mark('d'); //打印总体报告(不包含差值) $timer->printReport(); //获取总体报告,返回数组 $report = $timer->getReport(); //获取一个mark的报告 $a_report = $timer->getReport('a'); print_r($a_report); //打印a状态和b状态的差异信息,包含运行时间、使用内存等 $timer->printDiffReportByStartAndEnd('a', 'b'); //获取a状态和b状态的差异报告 $ab_diff_report = $timer->getDiffReportByStartAndEnd('a', 'b'); //打印第一个mark和最后一个mark之间的差异信息 $timer->printDiffReport(); //获取第一个mark和最后一个mark之间的差异信息 $diff_report = $timer->getDiffReport();
Continue reading 简单PHP性能记录工具

PHP异步并发访问mysql简单实现

PHP异步并发访问mysql简单实现

在实际的开发过程中,我们常常会遇到需要操作多张表,多个库的情况。有时因为一些限制我们不能进行连表(例如,异地数据库),所以只能用php串行访问后再在php里进行合并,有时还需要模拟mysql对合并后的结果进行排序、归并等。 这里产生的一个问题就是串行带来的访问时间问题。由于传统的串行访问方式,我们只能等到一条sql执行完毕后才可以执行下一条,所以执行时间是累加的。PHP官方手册提供了一种可以异步并发访问mysql的方式,详见:http://php.net/manual/zh/mysqli.poll.php,参考资料:https://svn.osgeo.org/mapguide/sandbox/rfc94/Oem/php/ext/mysqli/tests/mysqli_poll.phpt,使用此种方式,我们可以对Mysql进行异步并发访问,访问时间不再是串行累加,而是取决于执行时间最长的sql。 项目地址:https://github.com/huyanping/async-mysql-php show you the code: try{ $async_mysql = new \Jenner\Mysql\Async(); $async_mysql->attach( [‘host’ => ‘127.0.0.1’, ‘user’ => ‘root’, ‘password’ => ”, ‘database’ => ‘test’], 'select * from stu' ); $async_mysql->attach( [‘host’ => ‘127.0.0.1’, ‘user’ => ‘root’, ‘password’ => ”, ‘database’ => ‘test’], 'select * from stu limit 0, 3' ); $result = $async_mysql->execute(); print_r($result);
Continue reading PHP异步并发访问mysql简单实现

php包管理机制-支持php5.3的方法

php包管理机制-支持php5.3的方法

composer作为目前主流的php包管理器,使得我们组合不同功能的php代码非常容易,开发也可以更专注某一个模块了。而composer要求我们的php版本不低于php5.3,虽然php5.3也能跑,但不保证不会有问题。而相信目前国内很多公司的php版本仍然停留在php5.3以下的时代,或者由于自身实现了autoload,很难与composer组合到一起,虽然对composer的功能很喜欢,但也只能望而却步。 我们接触最多的php开发,就是MVC了,我们一般只需要编写M、V、C的代码即可,这些框架一般都有提供。但如果框架如果不是很强大的话,例如我们希望在写错误日志的同时,发送报警,相信会有一些框架难以做到这一点。为此你不得不再编写一些helper工具类来帮你实现你想要的。类似的场景会有很多,系统复杂度越高,我们需要的就越多,而框架就有可能在这个时候显得力不从心。 解决上面的问题,我们需要能够灵活的向框架中注入不同的模块,而不影响现有的代码。如何实现呢?spl_autoload_register()函数能够帮我们做到这一点。   下面我假设一个场景,然后利用spl_autoload_register()函数完成我们的模块注入。 假设,我们有一个php5.2的项目,非常复杂,autoload自动加载会扫描很多目录,同时会做autoload缓存,以便提升autoload性能。 如果我们添加一个功能包,除了修改__autoload函数外,我们还可以使用spl_autoload_register,这个函数像是一个注册器,每次调用,都会在一个注册树上注册一个autload函数,当你需要使用一个尚未载入的class时,php会自动从注册树顶部开始调用你所注册的autoload函数,直到找到你要载入的类为止。 利用spl_autoload_register的这个功能,我可以首先要做的事情就是修改我们的__autoload函数,因为如果你使用了__autoload函数,则会清空注册树上的函数。我们必须把我们之前编写的autoload函数同样的注册到注册树上才可以与其他autoload共存。具体看如下示例。 首先假设我们系统的__autoload函数类似如下: function __autoload($class_name){ $filename = FRAMEWORK_DIR . '/' . $class_name . '.class.php'; if(file_exists($filename)){ require $filename; } } 我们只需要做如下修改即可: function myAutoload($class_name){ $filename = FRAMEWORK_DIR . '/' . $class_name . '.class.php'; if(file_exists($filename)){ require $filename; } } spl_autoload_register('myAutoload'); 做完这一步,你可以测试你的系统能否正常运行,至此我们完成了第一步。 下面我们需要注入我们想使用的包,假设我们在github上找到了一个不错的包,但是它需要命名空间支持,所以我们做了些修改,去掉了命名空间。我们希望把这个包注入到我们的系统中。 我们需要做的就是为这个包编写一个autoload函数,然后调用spl_autoload_register()函数,把它注册到注册树上。类似如下: function githubPackageAutoload($class_name){ $filename = GITHUB_PACKAGE_PATH . '/' . $class_name
Continue reading php包管理机制-支持php5.3的方法

PHP微信SDK——Zebra-Wechat

PHP微信SDK——Zebra-Wechat

Zebra-Wechat Zebra-Wechat是微信公众平台开放接口的PHP封装,简单易用,支持以下功能: 接收微信服务器推送信息,对推送信息类型进行识别 微信API客户端封装(用户管理、用户组管理、客服管理、自定义菜单管理、系统管理等) 微信跳转验证封装 微小店相关接口 博客地址:www.huyanping.cn 接收微信推送示例 use \Jenner\Zebra\Wechat\WechatServer; use \Jenner\Zebra\Wechat\Response\TextResponse; $token = ‘you wechat token’; $server = new WechatServer($token); $server->on(‘before’, function(WechatServer $server, $request){ //do something }); $server->on(‘after’, function(WechatServer $server, $result){ //do something }); $server->on(‘unknown_message’, function(WechatServer $server, $request){ //do something }); $server->on(‘unknown_event’, function(WechatServer $server, $request){ //do something }); $server->on(‘text’, function(WechatServer $server, $request){ $to_user =
Continue reading PHP微信SDK——Zebra-Wechat

composer之创建自己的包

composer之创建自己的包

composer的出现,使得PHPer可以像java一样更加方便的管理代码。在composer没有出现之前,人们大多使用pear、pecl管理依赖,但是局限性很多,也很少有人用(接触的大多phper基本不适用pear管理依赖)。composer不仅仅能够解决依赖的问题,也可以在一定程度上解决造轮子的问题。 废话不多说,这篇主要记录如何创建自己的package。 大概步骤如下: 在github上创建一个项目(项目名称可以随意) 编写composer.json copy代码文件并修改命名空间 在https://packagist.org/上递交自己的包 设置github的hook 编写composer.json 先看一个示例: { "name": "jenner/message_queue", "description": "php message queue wrapper", "license": "MIT", "keywords": [“message queue”], "version": "1.0.0", "authors": [ { "name": "Jenner", "email": "hypxm@qq.com" } ], "require": { "php": ">=5.3.0" }, "autoload": { "psr-0": { "Jenner\\Zebra\\MessageQueue": "src/" } } } 需要注意的几个字段说明如下: name:包名称,递交时packagist会检测报名字是否合法。必须是一个/分隔的字符串。当别人引入你的包时,vendor下会自动创建这个目录。例如org/package包,则会在vender下创建org/package目录。 autoload:包的加载方式,具体加载方式可以参考composer中文网说明。这里使用的是psr-0标准加载方式。composer会在src目录下根据命名空间执行自动加载。   copy代码修改命名空间 composer.json文件修改后,我们需要把要打包的源文件复制过来。这里我把所有的文件放在了src目录下,后面可能会有和src同级的tests等目录,而这些目录是不会被加载的。src目录下需遵循psr-0标准。命名空间和目录定义要一直。例如Namespcae/SubNamespace命名空间,则src下必须有Namespace/SubNamespace目录。 代码编写标准可以参考psr-0、psr-1标准
Continue reading composer之创建自己的包

翻译:Laravel Generators laravel代码生成器

翻译:Laravel Generators laravel代码生成器

使用自定义代码生成工具快速进行Laravel开发 这个Laravle包提供了一种代码生成器,使得你可以加速你的开发进程,这些生成器包括: generate:model – 模型生成器 generate:view – 视图生成器 generate:controller – 控制器生成器 generate:seed – 数据库填充器 generate:migration – 迁移 generate:pivot – 关联表 generate:resource -资源 generate:scaffold – 脚手架 安装 需要一个五分钟教程视频吗? Laravel 4.2 或者更低的版本 使用Composer安装这个包,编辑你项目的composer.json文件,在require中添加way/generators “require-dev”: { “way/generators”: “~2.0” } 然后,在命令行下执行composer update: composer update –dev 一旦这个操作完成,就只需要最后一步,在配置文件中加入服务提供者。打开app/config/app.php文件,添加一个新的记录到providers数组中. ‘Way\Generators\GeneratorsServiceProvider’ 这样就可以了,你已经安装完成并可以运行这个包了。运行artisan命令行则可以在终端上看到generate相关命令。 php artisan Laravel 5.0 或者更高版本 使用Composer安装这个包,编辑你项目的composer.json文件,在require中添加way/generators “require-dev”: { “way/generators”: “~3.0” } 由于在Laravel高版本中默认文件夹结构,需要3.0或者更高的版本,才能适应5.0版本以上的Laravel 然后,在命令行下执行composer update: composer update –dev 一旦这个操作完成,就只需要最后一步,在配置文件中加入服务提供者。打开app/config/app.php文件,添加一个新的记录到providers数组中. ‘Way\Generators\GeneratorsServiceProvider’
Continue reading 翻译:Laravel Generators laravel代码生成器

基于Redis的MessageQueue队列封装

基于Redis的MessageQueue队列封装

Redis的链表List可以用来做链表,高并发的特性非常适合做分布式的并行消息传递。 github地址:https://github.com/huyanping/Zebra-Message-Queue packagist地址:https://packagist.org/packages/jenner/message_queue 左进右出 $redis->lPush($key, $value); $redis->rPop($key); 以下程序已在生产环境中正式使用。 基于Redis的PHP消息队列封装 <?php /** * Created by PhpStorm. * User: huyanping * Date: 14-8-19 * Time: 下午12:10 * * 基于Redis的消息队列封装 */ namespace Zebra\MessageQueue; class RedisMessageQueue implements IMessageQueue { protected $redis_server; protected $server; protected $port; /** * @var 消息队列标志 */ protected $key; /** * 构造队列,创建redis链接 * @param $server_config *
Continue reading 基于Redis的MessageQueue队列封装

基于System V Message queue的PHP消息队列封装

基于System V Message queue的PHP消息队列封装

System V Message queue 是一种进程通信(IPC)的方式,方便实现生产者-消费者模型,单个或多个生产者向队列中写入消息,多个生产者再从队列中获取消息进行处理。 项目地址:https://github.com/huyanping/Zebra-Message-Queue packagist地址:https://packagist.org/packages/jenner/message_queue 该Wrapper支持: 进程通信 设置最大队列容量(字节单位) 获取当前队列数量 修改队列部分属性 注意:如果要修改队列最大容量,请确保你的脚本是运行在root下 <?php /** * Created by PhpStorm. * User: huyanping * Date: 14-8-9 * Time: 上午3:44 * * System V message queue IPC通信消息队列封装 * 如果你想修改一个队列最大能够存储的字节数,请确认你的脚本具有root权限 */ class SystemVMessageQueue implements IMessageQueue { //消息分组类型,用于将一个消息队列中的信息进行分组 private $msg_type; //队列标志 private $queue; //是否序列化 private $serialize_needed; //无法写入队列时,是否阻塞 private $block_send;
Continue reading 基于System V Message queue的PHP消息队列封装

关于以UTF8编码的文件,php发送header时报错的原因

关于以UTF8编码的文件,php发送header时报错的原因

最近在给实习的同事讲解关于wordpress的二次开发。这几天他们的工作中经常遇到一个问题,问题描述如下:访问wordpress网站时经常会报错,说是再header函数之前就已经有输出了字符,且是在functions.php文件的第一行。 当我一次次修改该文件无效果的情况下,我删除了文件中的所有内容,结果依旧。所以我开始怀疑编码问题,并将编码改为ANSI编码,问题解决了。但我们的项目是UTF8编码,且该文件中存在中文,所以这样的解决方法并不是我们想要的。于是我思索其原因,有可能是UTF8编码默认有输出字符串,于是我GOOGLE以上问题,并得解答,UTF8编码默认输出BOM字符,所以在header函数调用处就会提示之前有字符输出。 该文章提供了具体解决方法,UTF8编码提供了一种特殊的无BOM的编码方式,我们可以通过notepad或者eclipse等工具修改其编码为无BOM编码格式,即可解决以上问题。相信有很多同行遇到了此类问题,希望本文能为您提供帮助。 本文允许转载,转载请保留源地址:http://huyanping.sinaapp.com/?p=58 原创文章,转载请注明: 转载自始终不够 本文链接地址: 关于以UTF8编码的文件,php发送header时报错的原因

使用Include函数的返回值

記得以前在thinkphp中看到一種寫法,一個文件中只有一條return語句,而return的內容是一個數組例如下面代碼: [php] view plaincopy included.php return array(1,2,3,4,5); 當時我猜想其應該是把這個數組當做include函數的返回值。經過測試果然如此,看如下調用代碼: [php] view plaincopy include.php 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) 用途: 1、我們可以將配置文件寫成這樣,當我們需要其中配置數據時,只需調用include函數即可獲得其配置參數。 2、我們可以同過Php對其本身進行修改,達到修改配置文件的作用。 本文允许转载,转载请保源地址:http://huyanping.sinaapp.com/?p=64 原创文章,转载请注明: 转载自始终不够 本文链接地址: 使用Include函数的返回值