BoxCore

Start


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

  • 站点地图

  • 搜索

PHPUNIT测试

发表于 2017-07-19 | 分类于 php , api | | 阅读次数

1. PHPUNIT是什么

PHPUnit是一个用PHP编程语言开发的开源软件,是一个单元测试框架。

1.1 为什么要用PHPUNIT

  1. 用phpunit是一个不错的主意
  2. 更改代码不会破坏他原有的结构 - 我们不需要修改源码。。
  3. 帮助其他开发人员了解您的代码的作用(并帮助入职过程,新人等等。。)
  4. 帮助您在编写代码时保持检查。 它会迫使你思考一些事情,例如“我将如何测试这个?
  5. 帮助你在晚上能睡好觉。。。。

1.2 单元测试的概念

程序单元是应用的最小可测试部件。 在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

2. 开始学习

Getting Started With PHPUnit: http://phpunit.de/

安装

  • 旧方法:PEAR
  • 新方法:PHAR or Composer

http://phpunit.de/manual/current/en/installation.html

案例1

The Code:

1
2
3
4
5
6
7
8
9
10
11
class Unicorns {
private $count = 8;
public function getCount() {
return $this->count;
}
public function steal($number) {
$this->count -= $number;
}
}

The Unit Test

1
2
3
4
5
6
7
8
9
10
11
12
class UnicornsTest extends PHPUnit_Framework_TestCase {
public function test_can_steal() {
// Setup
$unicorns = Unicorns();
// Action
$unicorns->steal(5);
// Assert
$this->assertEquals(3, $unicorns->getCount());
}
}

Running PHPUnit

1
$ phpunit tests/unicorns.php
PHPUnit 3.4.0 by Sebastian Bergmann.
Time: 0 seconds, Memory: 0.5Mb
OK (1 tests, 1 assertions)

案例2

The “Optimizer”

1
2
3
4
5
6
7
8
9
10
11
class Unicorns() {
private $count = 8;
public function getCount() {
return $this->count;
}
public function steal($number) {
$this->count -= $this->count - $number >= 0 ? $number : 0;
}
}

OUR TEST:

1
2
3
4
5
6
7
8
9
10
11
12
13
class UnicornsTest extends PHPUnit_Framework_TestCase() {
public function test_can_steal() {
$unicorns = Unicorns();
$unicorns->steal(5);
$this->assertEquals(3, $unicorns->getCount());
}
public function test_cant_steal() {
$unicorns = Unicorns();
$unicorns->steal(1000);
$this->assertEquals(8, $unicorns->getCount());
}
}

Running PHPUnit

1
2
3
4
5
PHPUnit 3.4.0 by Sebastian Bergmann.
..
Time: 0 seconds, Memory: 0.5Mb
OK (2 tests, 2 assertions)

案例3

The Bad “Optimizer”

1
2
3
4
5
6
7
8
9
10
11
12
class Unicorns() {
private $count = 8;
public function getCount() {
return $this->count;
}
public function steal($num) {
$this->count -= $this->count - $num >= 0 ? $num : $this->count;
}
}

Running PHPUnit (again):

1
phpunit tests/unicorns.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PHPUnit 3.4.0 by Sebastian Bergmann.
Time: 0 seconds, Memory: 0.5Mb
There was 1 failure:
1) UnicornsTest::test\_cant\_steal
Failed asserting that 0 matches expected 8.
/path/to/test/unicorns.php:11
FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

3. 配置项

  • assertEquals()
  • assertTrue()
  • assertFalse()
  • assertLessThan()
  • assertNull()
  • assertRegExp()

http://phpunit.de/manual/current/en/appendixes.assertions.html

4. FizzBuzz

FizzBuzz是借鉴一个英国学校里小孩子经常玩的游戏。改编后的题目大概是这样的 “编写程序把1-100的数字打印出来。不过,要把3的倍数打成"Fizz",把5的倍数打成"Buzz"。而如果一个数既是3的倍数。又是5的倍数时,就打成"Fizz-Buzz",其余的输出数字。然后在论坛看见这道编程题很多计算级系的高材生(博士、硕士之类的)都不能现场写出来,更有多年经验自称高级开发程序员在几分钟内也写不出来

不过既然说到这了,那就先打开来考验下自己,最后我是通过两种方式来实现的:
第一种:利用循环和条件判断,过滤满足特定条件的数字,然后输出结果,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for ($i = 1; $i <= 100; $i++)
{
if($i % 3 == 0 && $i % 5 ==0){
echo "FizzBuzz<br />\n";
}
else if($i % 3 == 0){
echo "Fizz<br />\n";
}
else if($i % 5 == 0){
echo "Buzz<br />\n";
}
else {
echo $i."<br />\n";
}
}
1
2
3
4
5
6
7
8
// 或者更加简单
for ($i = 1; $i <= 100; $i++) {
$mod3 = $i % 3;
$mod5 = $i % 5;
echo (!$mod3 && !$mod5 ? "FizzBuzz" : (!$mod3 ? "Fizz" : (!$mod5 ? "Buzz" : $i))) ."<br>\n";
}

Alt text

  • URL: https://devtest.net/take_test/test_attempts/new

5. 扩展

DOCUMENT

  • https://phpunit.de/manual/current/zh_cn/writing-tests-for-phpunit.html

PHP接口设计之道

发表于 2017-07-19 | 分类于 php , api | | 阅读次数

设计前后端完全分离的应用,可以使用到RESTful API。比如, Backbone 的默认规则最适合的是一个完全 restful 风格的后端接口,如果你的后端系统没有准备好,那就直接覆盖掉吧。restful 不光是前端的事~ 是构架层面上的事情,如果想用Backbone的话,肯定是需要后端重新定义所有的接口了,但是这也是好事,毕竟 restful 逻辑更清晰,以后的更新,维护会更方便。

一、基础

现在的网站没有API都给人落后的印象了,而当下设计API流行的规范便是RESTful。REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:”我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。” 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。

它涉及到以下这些内容。

1.1 域名

应尽量部署在专用域名之下,可以在前边加个二级头或者域名后添加api路径。

https://api.example.com
https://example.com/api/

1.2 版本

API经常会变,因此要注意区分版本。一般放入URL中。

https://api.example.com/v1/

1.3 路径

路径又称”终点”(endpoint),表示API的具体网址。
在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的”集合”(collection),所以API中的名词也应该使用复数。
举例来说,有一个API提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees

1.4 HTTP动词

对于资源的具体操作类型,由HTTP动词表示。
常用的HTTP动词有下面五个(括号里是对应的SQL命令)。

  • GET(SELECT):从服务器取出资源(一项或多项)
  • POST(CREATE):在服务器新建一个资源
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
  • DELETE(DELETE):从服务器删除资源

下面是一些例子。

  • GET /zoos:列出所有动物园
  • POST /zoos:新建一个动物园
  • GET /zoos/ID:获取某个指定动物园的信息
  • PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
  • PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
  • DELETE /zoos/ID:删除某个动物园
  • GET /zoos/ID/animals:列出某个指定动物园的所有动物
  • DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物

1.5 过滤信息

如果记录数量很多,服务器不可能都将它们返回给用户。API应该提供参数,过滤返回结果。
下面是一些常见的参数。

  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置
  • ?page=2&per_page=100:指定第几页,以及每页的记录数
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
  • ?animal_type_id=1:指定筛选条件

1.6 状态码

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。

  • 200 OK – [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)
  • 201 CREATED – [POST/PUT/PATCH]:用户新建或修改数据成功
  • 202 Accepted – [*]:表示一个请求已经进入后台排队(异步任务)
  • 204 NO CONTENT – [DELETE]:用户删除数据成功
  • 400 INVALID REQUEST – [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的
  • 401 Unauthorized – [*]:表示用户没有权限(令牌、用户名、密码错误)
  • 403 Forbidden – [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的
  • 404 NOT FOUND – [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的
  • 405 method not allowed – [*]:该http方法不被允许
  • 406 Not Acceptable – [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的
  • 422 Unprocesable entity – [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误
  • 500 INTERNAL SERVER ERROR – [*]:服务器发生错误,用户将无法判断发出的请求是否成功

1.7 错误处理

如果状态码是4xx,就应该向用户返回出错信息。一般来说,返回的信息中将error作为键名,出错信息作为键值即可。

1
{error: "invalid API key"}

1.8 返回结果

针对不同操作,服务器向用户返回的结果应该符合以下规范。

  • GET /collection:返回资源对象的列表(数组)
  • GET /collection/resource:返回单个资源对象
  • POST /collection:返回新生成的资源对象
  • PUT /collection/resource:返回完整的资源对象
  • PATCH /collection/resource:返回完整的资源对象
  • DELETE /collection/resource:返回一个空文档

二、最佳实践

2.1 Slim框架的使用

推荐一个轻量版PHP RESTful框架:Slim ,有兴趣的同学可以参考其文档:http://docs.slimframework.com/

下面以一个网上的教程给大家说明,主要是应用前端框架AngularJS 和 后端PHP框架Slim搭设的一个简易图书管理系统为例。

代码实现

主要的工作是在项目根目录下的index.php文件里进行的,第一步需要引入Slim框架

1
2
3
4
5
//第一步:引用Slim框架
//首先,需要在你的index.php中引入Slim框架的依赖,根据实际情况,你可能得调整下文件的路径
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();

2.x 测试 - 插件使用

  1. Chrome 插件 Postman:
    Alt text

  2. Chrome插件Json-viewer 和 json-handle

###

三、扩展

3.1 不要默认使用大括号封装,但要在需要的时候支持

json 还是回调,那是个问题:

1
2
3
4
5
6
{
"data" : {
"id" : 123,
"name" : "John"
}
}

or

1
2
3
4
5
6
7
callback_function({
status_code: 200,
next_page: "https://..",
response: {
... actual JSON response body ...
}
})

好的做法是:

  • http://example.com/api/xxx?type=jsonp&callback=yourCallBackName
  • http://example.com/api/xxx?type=json
  • http://example.com/api/xxx?type=xml

就返回对应结构的数据。

3.2 如何使用 Last-Modified 和 Etags 如何帮助提高性能?

开发者会把 Last-Modified 和 ETags 请求的 HTTP 报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生 Last-Modified/Etag 标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其缓存是否过期。

HTTP 协议规格说明定义 ETag 为“被请求变量的实体值”。 服务器单独负责判断记号是什么及其含义,并在 HTTP 响应头中将其传送到客户端,以下是服务器端返回的格式:

ETag: “d41d8cd98f00b204e9800998ecf8427e”

客户端的查询更新格式是这样的:

If-None-Match: W/“d41d8cd98f00b204e9800998ecf8427e”

如果ETag没改变,则返回状态304,内容为空,这也和Last-Modified一样。下面再扔些php的例子看看:

1
2
3
4
5
6
7
8
9
10
11
12
$file = 'myfile.php';
$last_modified_time = filemtime($file);
$etag = md5_file($file);
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
header("Etag: $etag");
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||
trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
header("HTTP/1.1 304 Not Modified");
exit;
}

补充:对于前端部分网上的一些做法是:Gulp对所有的静态资源进行预处理,生成一份manifest,标明了预处理前后文件之间的对应关系。DEMO, 另外腾讯前端团队的一篇关于web缓存系列文章大家也可以查阅下:直通车

总结

技术的变革一般都是为了提高生产力的,restful的初衷也是。它提倡简单(理论上讲只要业务实体抽象的好就够了),纯粹(每个资源就四种操作)的 API 设计思想,需要使用者坚持信仰(坚持基本原则),适度灵活。

— 来自SF.gg

Q&A

1. 务器返回的数据格式,应该使用JSON还是使用XML?

推送使用JSON,如果提供的服务对象较多,可以设置兼容XML

2. REST能应用在什么场景?

REST规范中明确规定,处理的是资源(或者实体),而不是动作。换句话说,REST处理的是books或者animals这种东西,而login之类的业务逻辑是动作,不适用REST。

restful 可以看做 orm 的 web api 形式,也就是说,资源指的是数据库里面的表(或者表的连接),或者是你nosql数据库里面的对象。当调用者需要并且有权直接操作它们,或者是以表的粒度操作数据库,才需要使用 restful。

3. 统计能使用REST吗?
4. 兴趣探讨Vue.js、ReactJS、AngularJS
5. 扩展:API Cookie加密
6. php crud 和resetful的相似之处

参考

简单版:

  • 《RESTful API 设计指南》 - 阮一峰的网络日志
  • restful-api-design-references
  • REST API 使用详解
  • 国内值得关注的官方 API 集合

高阶版:

  • phalcon框架的REST实践
  • PHP-CRUD-API:

UPS:

  • https://segmentfault.com/a/1190000004038353
  • https://segmentfault.com/a/1190000002690813
  • https://zhujun24.github.io/2014/12/10/AngularJS%E5%85%A5%E9%97%A8%E7%9A%84%E5%B0%8FDemo/
  • https://zhujun24.github.io/2015/03/19/%E7%94%A8Slim%E8%BD%BB%E5%9E%8BPHP%E6%A1%86%E6%9E%B6%E5%86%99RESTful%20APIs/
  • https://segmentfault.com/a/1190000004690182

  • http://www.php.cn/php-notebook-285669.html
  • http://www.yiifans.com/yii2/guide/tool-gii.html

感冒最全用药攻略

发表于 2017-07-18 | | 阅读次数

一. what

“出门多穿点别着凉”、“捂好脑袋别见风”,每到冬天,我们耳边总少不了这些叮嘱。似乎只要别着凉、别见风、别出门的地方,就能够防着感冒这个大魔王了。

但感冒真是由风和寒冷引起的?防感冒最好是待屋里别出去?我们的预防三板斧,真的管用吗?

二. 用药大全

2.1 常见感冒药

Alt text

在服用阿司匹林时需要关注出血风险。这个出血风险并非脑出血,而是消化道黏膜的弥漫性出血。为减少阿司匹林用药的不良反应,用药前,医生会识别消化道损伤的高危人群,包括年龄≥65岁、既往有消化道溃疡或出血病史、合并服用其他抗栓药物/糖皮质激素等。

2.2 找药

1) 流鼻涕、鼻塞——找“麻”

  1. 药盒上写了“麻”的代表里面含有“伪麻黄碱”,这种成分能减轻鼻咽粘膜充血,缓解你的鼻塞、流鼻涕。

2) 浑身酸痛、低烧——找“酚”

“酚”指的是对乙酰氨基酚,能够有效地缓解疼痛和退烧。我们平常能买到的感冒药,比如新康泰克、感康、白加黑等,都含有这种成分。

此外,布洛芬、吲哚美辛、阿司匹林和对乙酰氨基酚的作用类似,如果感冒药中有这几种成分的话,也能帮你降温、减轻身体酸痛感。

不适宜人群:有消化道溃疡的人。

3) 干咳——找“美”

这个“美”指的是右美沙芬,它是临床上常用的的一种中枢性镇咳药,含此成分的感冒药通用名多含有“美”字。咳嗽比较厉害,晚上甚至因为咳嗽很难睡好觉的话,选它就对了。

不适宜人群:痰多的患者要慎用,这种药的中枢镇咳作用可能会影响痰液排出;怀孕3个月以内的女性禁用。

4) 打喷嚏、流鼻涕——敏(氯苯那敏)

氯苯那敏就是我们熟知的扑尔敏,它的作用是抗过敏,能让你少打喷嚏、流鼻涕,而且还有一定的镇静作用(让你犯困,想睡觉)。

不适宜人群:因为药物有镇静作用,所以吃药的时候最好不要开车、从事高空作业或者是做任何精细操作,好好休息。

其他
  1. 上面的时候可以选择含有咖啡因的感冒药, 有提神

2.3 禁忌

1) 感冒药别混着吃,容易吃过量!

虽然感冒药的名字不一样,但是里面可能含有很多相同的成分,甚至是一些中成药里也含有“对乙酰氨基酚”、“氯苯那敏”等。药物过量可能会伤害胃黏膜,造成胃痛、胃溃疡、过度困乏,所以不论吃啥药前,都看看成分表吧,避免服用过量。

2) 不要一大把药一起吃!

如果本身就有固定要吃的药(比如降血压的药之类的),加上感冒药就更多了,但最好不要手里拿一把药一起吃下去,因为很多药物之间有相互反应,甚至会产生一些毒性,建议每间隔半小时再吃另一种药。

3) 吃感冒药别喝酒

吃啥药最好都别喝酒,饮酒会导致肝功能下降,影响药物的代谢。

4) 吃了感冒药,别开车!

感冒药中的氯苯那敏、扑尔敏等成分有一定的镇静作用,吃了之后会让你昏昏欲睡,开车的时候精神不集中,很容易导致交通事故。

而感冒药里最容易使人犯困的一类成分,就是能减轻流鼻涕的「抗组胺成分」。
抗组胺成分目前有两类,一类比较「古老」,它们在起作用的同时还可以通过我们大脑的血脑屏障进入大脑,对大脑产生明显抑制作用而让我们犯困,被称作「第一代抗组胺药」。属于这一代的药,有马来酸氯苯那敏(俗称「扑尔敏」)、苯海拉明、赛庚啶、异丙嗪、酮替芬。

Alt text

关于育苗:

流感疫苗是安全有效的,老人和孩子最好要按时接种。流感疫苗是使用每年最流行的三个病毒株做成疫苗,也就是说,注射之后人会获得对于最流行的几种感冒的抗性。注射疫苗尽管不能避免得感冒,但是却能避过最厉害的那几种去。

说到最后还是建议大家多运动,多保持健康向上的心态工作和生活,.

最后再奉上常见感冒药成分表2张,祝大家健康~~

Alt text
Alt text

(先说明不是在做广告, 截止今天未收到任何商家的广告费..)

有趣的问题:

  1. 你们知道处方药 和 非处方药(OTC) 的区别吗?
  2. 中成药和复方的区别?

  • http://chuansong.me/n/1509328352420
  • https://www.zhihu.com/question/28697324
  • https://zhuanlan.zhihu.com/p/21956501?refer=c_32319456
  • https://zhuanlan.zhihu.com/p/21956501?refer=c_32319456
  • http://songshuhui.net/archives/23219
  • http://nakseuksa.github.io/2016/04/03/%E5%8C%BB%E7%94%9F%E7%9F%A5%E9%81%93%E7%9A%84%E4%BA%8B/

MySQL硬盘实例测试之裤子搭建

发表于 2017-07-18 | | 阅读次数

裤子搭建过程(未完成):

一, 安装新实例

/usr/local/mysql/bin/mysqld –defaults-file=/data/mysql/3306/my.cnf –basedir=/usr/local/mysql –datadir=/data/mysql/3306/data –plugin-dir=/usr/local/mysql/lib/plugin –user=mysql –log-error=/data/mysql/3306/mysql_run.err –open-files-limit=65536 –pid-file=/data/mysql/3306/pid_mysql.pid –socket=/data/mysql/3306/mysqltmp/mysql.sock –port=3306

mysqld –initialize –user=mysql –console

1
mysqld --defaults-file=/opt/data/mysql/var/my.cnf --basedir=/usr/local/Cellar/mysql/5.7.11 --datadir=/opt/data/mysql/data --plugin-dir=/usr/local/Cellar/mysql/5.7.11/lib/plugin --user=mysql --log-error=/opt/data/mysql/var/mysql_run.err --open-files-limit=2048 --pid-file=/opt/data/mysql/var/pid_mysql.pid --socket=/opt/data/mysql/var//mysql.sock --port=3307 --initialize --user=mysql --console

注意尾部有: mysqld --initialize --user=mysql --console
错误: 2017-02-13T06:47:11.067815Z 0 [Warning] Could not increase number of max_open_files to more than 7168 (request: 65536)

生成后, 通过日志文件找到新实例的密码为:
2017-02-13T06:50:20.157831Z 1 [Note] A temporary password is generated for root@localhost: Gbovl1rilt;Q

执行启动应用:
mysqld –defaults-file=/opt/data/mysql/var/my.cnf –basedir=/usr/local/Cellar/mysql/5.7.11 –datadir=/opt/data/mysql/data –plugin-dir=/usr/local/Cellar/mysql/5.7.11/lib/plugin –user=mysql –log-error=/opt/data/mysql/var/mysql_run.err –open-files-limit=2048 –pid-file=/opt/data/mysql/var/pid_mysql.pid –socket=/opt/data/mysql/var//mysql.sock –port=3307

进入mysql-cli后修改密码 : set password = password(‘root’);

二, 社工库操作

2.1 数据导入的方法合集

mysql-cli中导入:

source xxx.sql;
LOAD DATA INFILE ‘~/Downloads/2345.csv’ INTO TABLE tmp FIELDS TERMINATED BY ‘,’ ENCLOSED BY ‘“‘ LINES TERMINATED BY ‘\n’ IGNORE 1 ROWS;

/Volumes/BoxHD/db/SGK/163

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
LOAD DATA INFILE '/Volumes/BoxHD/db/SGK/163/1.txt' \
INTO TABLE account \
FIELDS TERMINATED BY ',' \
ENCLOSED BY '"' \
LINES TERMINATED BY '\n' \
-- IGNORE 1 LINES \
(name, password);
LOAD DATA INFILE '/Volumes/BoxHD/db/SGK/163/2.txt' \
INTO TABLE account \
FIELDS TERMINATED BY ' ' \
ENCLOSED BY '"' \
LINES TERMINATED BY '\n' \
(name, password);
LOAD DATA INFILE '/Volumes/BoxHD/db/SGK/163/3.txt' \
INTO TABLE account \
FIELDS TERMINATED BY '\t' \
ENCLOSED BY '"' \
LINES TERMINATED BY '\n' \
(name, password);

实战项目

发表于 2017-07-18 | | 阅读次数

这里罗列一些实战的项目。

举个栗子,我弄了个裤子,you know it!

hadoop note

发表于 2017-06-22 | | 阅读次数
1
2
$ 查看文件列表清单
hadoop fs -du -h /user/hive/warehouse/{database_name}.db/{table_name};

Learn about phpunit

发表于 2017-06-22 | | 阅读次数

phpunit测试

Laravel Dusk

1
2
$ install laravel framework for test phpunit
composer create-project laravel/laravel --prefer-dist laravel-testing

phpunit 指定类测试

phpunit –filter=类名 or 方法名

断点判断相等:(断言)

$this->assertEquals(‘值’, $xxx->function());

$this->assertCount($value, $xxx->method());

其他: 安装phpstrom插件 CamelCase, 可以切换驼峰或者匈牙利密码法的名称,快捷键 shift + alt + U

可测试的设计原则

  • 单元测试中, 代码在一个隔离的环境中运行(周围没有它熟悉的框架 和配置), 所以尽量低的耦合和明确的依赖关系是可测试代码的最主要的要求。
  • 实现低耦合的代码, 重点是按照单一职责原则,对系统进行功能划分, 达到高内聚(一个单元能完成一个具体的功能),低耦合(模块之间 的接口最简单)。
  • 明确的依赖关系需要通过依赖注入的方式来实现,不能对代码的运行 环境有任何隐含的假设, 这样仅通过接口的声明, 而不需要了解实现, 就可以知道让这个模块跑起来所需要的资源。

不可测试的代码

  • 超全局变量(Superglobals) $_
  • 写在构造函数中的业务逻辑
  • 静态方法(static class method) Class::
  • 单例(Singleton) &get_instance()
  • PHP的动态魔术
  • 超长的函数和类

总结

  • 可测试的代码, 一定是遵照依赖倒置原则DIP写出的代码
  • 代码模块之前的依赖关系, 是按照单一职责SRP的划分产生的
  • 单一职责决定了接口设计需要小而专一,即接口隔离ISP
  • 单一职责原则要求把系统中变化的和不变的部分分离,以达到对扩展 开放, 对修改封闭OCP
  • 继承和多态是实现可扩展架构的主要工具,里氏替换原则LSP明确了对继承的要求:子类需要能胜任父类工作的所有岗位, 才算个合格的子类。

可测试的代码 == SOLID

  • Single Responsibility Principle : 单一职责原则(SRP)
  • Open-Close Principle: 开闭原则(OCP)
  • Liskov Substitution Principle : 里氏替换原则(LSP)
  • Interface Segregation Principle : 接口隔离原则(ISP)
  • Dependency Inversion Principle: 依赖倒置原则(DIP)

持续集成

  • 持续集成并不属于自动化测试, 但它是保证自动化测试能顺利实施的 必要条件。
  • 持续集成会在代码每次提交时执行代码构建, 自动化测试,代码检查, 自动部署等工作,给开发人员及时的反馈, 来保证小问题不会积累。
  • 单元测试时需要同代码一起变化的, 只有一直在运行的测试代码才不 会被遗忘, 才能被不断维护。
  • 解决开发与测试之间“在我机器上没问题”的问题

CI工具箱

  • Jenkins
  • PHPUnit
  • CodeCeption
  • Behat
  • PHPSpec
  • PHP Mess Detector
  • PHP Code Sniffer

测试驱动开发会带来的改变

  • 一开始的进度变慢了

    • 写代码前需要更多的思考, 分解问题, 设计接口
    • 学习测试工具, 准备测试代码
  • 可测试的代码

    • 测试驱动会促使你写出可测试的代码, 不然写测试用例没法下手
    • 有了自动测试的保护, 可以随时重构看着不顺眼的代码
  • 信心
    • 对于已经完成的代码正确性有十足的信心
    • 面对新功能和需求变更,可以对开发时间有准确的估计
    • 遇到bug可以快速的定位和修复问题

php的各种超时设置

发表于 2017-06-22 | | 阅读次数

ini_set(‘mysql.connect_timeout’, 1800);
ini_set(‘default_socket_timeout’, 1800);
ini_set(‘max_execution_time’, 1800);

set_time_limit(1800);

request_terminate_timeout

100 way to setting proxy

发表于 2017-06-19 | | 阅读次数

$ terminal setting proxy:

export http_proxy=socks5://127.0.0.1:5566
export https_proxy=$http_proxy
unset http_proxy https_proxy

$ see other proxy setting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ add some alias
alias goproxy='export http_proxy=socks5://127.0.0.1:5566 https_proxy=socks5://127.0.0.1:5566'
alias disproxy='unset http_proxy https_proxy'
$ setting homebrew :
export ALL_PROXY=socks5://127.0.0.1:5566
ALL_PROXY=socks5://127.0.0.1:9001 brew upgrade
$ see what ip you in!
curl ip.cn
add sss
/usr/local/opt/shadowsocks-libev/bin/ss-local -c /usr/local/etc/shadowsocks-libev.json > /dev/null 2>&1 &
/usr/local/opt/shadowsocks-libev/bin/ss-local -c /usr/local/etc/shadowsocks-libev-cn.json > /dev/null 2>&1 &
/usr/local/opt/shadowsocks-libev/bin/ss-local -c /usr/local/etc/shadowsocks-libev-jp.json > /dev/null 2>&1 &

也可以使用Mac的launchctl来启动|停止

1
2
3
4
5
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.xxxxx.plist
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.xxxx.plist # 新增定时任务
ln -sfv /usr/local/opt/xxx/*.plist ~/Library/LaunchAgents # 设置开机启动
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.xxxx.plist

我的Mac开发工具集

发表于 2017-06-19 | | 阅读次数

1. zsh插件

命令行自动提醒:zsh-autosuggestions

2. tig

一个不错的git 下cli管理工具
安装: brew install tig

3. ccat

高亮显示源码
安装: brew install ccat

4. item配色工具

https://github.com/mbadolato/iTerm2-Color-Schemes

5. git自动部署

http://overtrue.me/articles/2015/01/how-to-deploy-project-with-git-hook.html

https://m.aoh.cc/149.html

6. php类库

php shell wrapper

7. phpstom使用的一些技能

laravel help: 解决类库无法找到的问题

phpstorm live template 功能。模板参考如:

1
2
3
4
5
<!--- $VALUE$ Field --->
<div class="form-group">
{!! Form::label('$NAME$', '$VALUE$:') !!}
{!! Form::text('$NAME$', null, ['class' => 'form-control']) !!}
</div>

更详细的文档可以参考:Laravel Live Templates for PhpStorm

验证码

geetest 滑动验证

http://blog.csdn.net/paololiu/article/details/52514504

ping++ 聚合付费sdk

Sentry服务集中处理

Sentry.io 是一个超级棒的错误处理工具,它可以捕捉应用在生产环境中出现的 exception 和 errors,直接将其定位到具体的某一行,对于应用的运维和修复 bug 都是一件非常好的事

1…171819…26
Zack Hwang

Zack Hwang

Go

257 日志
42 分类
76 标签
RSS
Links
  • 小白博客
  • 我的书单
© 2018 Zack Hwang
由 Hexo 强力驱动
主题 - NexT.Muse
又拍云