1 2 3 4 5 6 |
POST /indexname/typename/_delete_by_query { "query": { "match_all": {} } } |
专注WEB编程开发技术
1 2 3 4 5 6 |
POST /indexname/typename/_delete_by_query { "query": { "match_all": {} } } |
我们在项目调优过程中,通常会对代码的运行时间进行统计,以便了解程序运行的性能和效率,这些统计结果将作为代码优化时的重要指标,帮助开发者有针对性的进行调优工作。
MiniFramework 在 1.3.0 版本中,新增了 Debug 类,其中包含有时间统计功能的若干方法,可以非常便捷地帮助开发者实现上述统计需求,下面我们来通过示例代码介绍具体实现方法。
首先,假设我们有一个名为 Index 的 Controller,并且其中包含有一个名为 index 的 Action(MiniFramework下载包中已经包含),我们将代码写在这个 Action 中,如下:
在开发 Socket 通信时,由于 TCP 协议的特性,在网络状况不佳的情况下,数据传输过程中经常会出现半包或粘包。为解决这一问题,通常我们需要自定义一个通信协议,增加一个 HEADER 部分,并在其中对数据包的长度进行声明,下面分享一段封包和解包的示例代码,可用于 Golang 开发 Socket 时处理数据传输,具体代码如下:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package protocol import ( "bytes" "encoding/binary" ) const ( TCP_HEADER = "TCPHEADER" TCP_HEADER_LEN = 9 TCP_DATA_LEN = 4 ) // 封包 func Enpack(msg []byte) []byte { return append(append([]byte(TCP_HEADER), IntToBytes(len(msg))...), msg...) } // 解包 func Depack(buffer []byte, readerChannel chan []byte) []byte { length := len(buffer) var i int for i = 0; i < length; i++ { if length < i + TCP_HEADER_LEN + TCP_DATA_LEN { break } if string(buffer[i:i + TCP_HEADER_LEN]) == TCP_HEADER { msgLen := BytesToInt(buffer[i + TCP_HEADER_LEN : i + TCP_HEADER_LEN + TCP_DATA_LEN]) if length < i + TCP_HEADER_LEN + TCP_DATA_LEN + msgLen { break } data := buffer[i + TCP_HEADER_LEN + TCP_DATA_LEN : i + TCP_HEADER_LEN + TCP_DATA_LEN + msgLen] readerChannel <- data i += TCP_HEADER_LEN + TCP_DATA_LEN + msgLen - 1 } } if i == length { return make([]byte, 0) } return buffer[i:] } // 整形转换成字节 func IntToBytes(n int) []byte { x := int32(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, x) return bytesBuffer.Bytes() } // 字节转换成整形 func BytesToInt(b []byte) int { bytesBuffer := bytes.NewBuffer(b) var x int32 binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x) } |
详见代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package main import ( "fmt" "net" ) for _, address := range addrs { // 检查 ip 地址判断是否回环地址 if ipnet, flag := address.(*net.IPNet); flag && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { fmt.Println(ipnet.IP.String()) } } } |
阳光部落原创,更多内容请访问http://www.sunbloger.com/
最近在一个基于 Web 的 IM 项目中,我采用异步向服务器发起请求拉取最新的聊天内容,服务器端通过 PHP 处理拉取请求,拉取过程是用 10 次循环查询数据库是否有最新的聊天内容。如发现新内容,则立即向浏览器输出,并结束掉本次请求的进程。在这 10 次的循环中,每次查询数据库后,均通过 Sleep 函数让进程暂停 1 秒,那么这个 PHP 进程可能会在服务器端保持 10 秒。
在测试过程中,我发现当这个拉取请求运行期间,其他向服务器端 PHP 发起的请求,均受到影响,响应变的非常慢。
经过一系列的排查,问题始终得不到解决,但当把代码中涉及到 SESSION 的部分全部跳过时,情况发生了变化,所有 PHP 进程都恢复正常的响应速度了。由此,联想到问题可能出在了 SESSION 阻塞机制上了。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// main package main import ( "fmt" ) func main() { val := []int{7, 3, 8, 1, 0, 2, 5, 9, 6, 4} fmt.Println(val) // 冒泡排序 for i := 0; i < len(val)-1; i++ { for j := i + 1; j < len(val); j++ { if val[i] > val[j] { val[i], val[j] = val[j], val[i] } } } fmt.Println(val) } |
阳光部落原创,更多内容请访问http://www.sunbloger.com/
MiniFramework 是一款遵循 Apache2 开源协议发布的,支持 MVC 和 RESTful 的超轻量级 PHP 开发框架。
在 MiniFramework 最新的版本中,提供了上传文件的特性,下面我们来演示一下实现过程。
首先,新建一个名为 Upload 的 Controller,并在其中新建一个名为 index 的 Action,代码如下:
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 26 |
<?php namespace App\Controller; use Mini\Upload; class Upload extends Action { function indexAction() { if (! empty($_FILES)) { // 实例化 Upload 类 $upload = new Upload(); $res = $upload->save($_FILES['f']); if (! $res) { $errmsg = $upload->getErrorMsg(); echo $errmsg; } else { dump($res); } } $this->view->display(); } } |
上边的代码中,通过 use Mini\Upload; 引入了 MiniFramework 框架所提供的一个用于文件上传的类库。
在实例化 Upload 类后,通过调用 save 方法,并将 PHP 的 $_FILES 传入,来实现上传文件的保存。
在调用 save 方法后,若文件保存失败,可以通过 getErrorMsg 方法来获取错误信息。
如果文件保存成功,那么 save 方法会返回一个数组,其中包含有文件保存的路径和文件名,上边的示例代码中使用了 MiniFramework 内置的全局函数 dump() 来输出 save 所返回的数组。
另外,在实例化 Upload 类时,可传入一个数组类型的参数,对文件保存路径、大小和类型进行设定,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// 配置数组 $config = array( // 文件保存的根目录 'rootPath' => PUBLIC_PATH . '/uploads', // 文件的大小限制(单位:Byte) 'maxPath' => 512000, // 允许的类型 'allowType' => 'bmp,gif,jpg,jpeg,png' ); // 实例化 Upload 类时,将配置数组作为参数传入 $upload = new Upload($config); |
上边的代码中,常量 PUBLIC_PATH 是 MiniFramework 内置用于定义站点根目录所对应的路径,默认对应的是 Public 目录所在的路径
接下来创建视图,在 View 目录中创建一个名为 upload 的目录,将视图文件保存到 View/upload/index.php,代码如下:
1 2 3 4 5 |
<h1>Upload</h1> <form method="post" enctype="multipart/form-data"> <input type="file" name="f" > <input type="submit" value="upload" /></p> </form> |
完成上述步骤后,便可以访问类似下面的地址来测试了
http://你的域名/index.php?c=upload&a=index
如果你的站点开启了伪静态,那么访问地址可以是下面这样:
http://你的域名/upload/index
上边的 URL 中,最后的 index 可以省略,例如:
http://你的域名/upload
阳光部落原创,更多内容请访问http://www.sunbloger.com/
为 PHP 设置了 open_basedir 后,发现使用 require 和 include 始终会报出下面这样的 Warning 信息:
Warning: require(): open_basedir restriction in effect. File() is not within the allowed path(s)
这个 Warning 信息中,require 和 File 的括号中都是空白没有内容的,经过反复检查代码,确认所引用的路径在 open_basedir 允许的范围内。
通过去国外网站搜索资料,发现是因为 open_basedir 与 eAccelerator 冲突造成的。
需要重新编译一次 eAccelerator,编译时需要带上 –without-eaccelerator-use-inode 参数。
编译完重新启动 php-fpm 并删除之前的 eAccelerator 缓存文件即可。
阳光部落原创,更多内容请访问http://www.sunbloger.com/
今天为 MiniFramework 新增了一个名为 Captcha 的类,用于图片验证码的输出和校验。
具体用法如下:
用 MiniFramework 新建一个名为 Example 的控制器,例如:
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 26 27 28 29 30 31 32 33 |
<?php namespace App\Controller; use Mini\Action; use Mini\Captcha; /** * Example */ class Example extends Action { function captchaAction() { if (!empty($_POST['code'])) { $captcha = new Captcha(); $res = $captcha->check($_POST['code']); if ($res) { $this->view->assign('info', 'success'); } else { $this->view->assign('info', 'fail'); } $this->view->assign('code', $_POST['code']); } $this->view->display(); } function getcaptchaAction() { $captcha = new Captcha(); $captcha->create(); } } |
同时创建视图,代码如下:
1 2 3 4 5 6 7 |
<?php if (isset($this->code)) echo '<p>input code: ' . $this->code . '</p>';?> <?php if (isset($this->info)) echo '<p>check result: ' . $this->info . '</p>';?> <img src="getcaptcha" onclick="this.src='getcaptcha?t='+Math.random()" /> <form method="post" action="captcha"> <p>code:<input type="text" name="code" value="" /> <input type="submit" value="check" /></p> </form> |
创建完成后,访问 http://你的域名/example/captcha 即可看到效果。
上边的代码已经包含在 MiniFramework 位于 GitHub 的 master 主线上。
GitHub源代码地址:https://github.com/jasonweicn/MiniFramework
接手一个在线客服的项目,本质上就是一个 IM 项目。
第一个想到的是用 WebSocket,然而一些客观因素导致这个项目很难采用 WebSocket 来做。那么,就只好用 http 实现,并为此设计了如下流程:
如图,首先 Browser 端发起一个拉取消息的请求。Server 端收到请求后,立即查询是否有新消息,如查询到了新消息,则立即返回结果给 Browser 端。
Browser 端收到返回结果后,再次发起一个新的拉取消息的请求,如此往复进行。
若 Server 端接到拉取请求后,没有查询到新消息,则 Hold 住这个请求进程,同时设置一个时间阈值,比如5秒。
在这5秒内,Server 端反复查询是否有新消息,当发现了新消息后,则立即向 Browser 端返回结果同时结束掉进程。若始终都没有新消息,则在达到预设的时间阈值后,向 Browser 端返回一个通知,告知 Browser 端这次没有新消息。
在这个流程中,Browser 端发出请求后,可能会立即收到结果,也可能在5秒后得知没有新消息,不论是否有新消息,在得到 Server 端反馈后,都要立即再次发出请求。
阳光部落原创,更多内容请访问http://www.sunbloger.com/