服务化一般流程

编  写:袁亮
时  间:2015-12-16
说  明:服务化的一般流程

一、理清功能点

    1、找到业务对接人

    2、找同类功能,其他家比较好的是怎么做的

    3、确定功能,可能做什么,哪些不做,后期可能扩展


二、如果在已有的基础上升级

    1、理清原来代码

    2、什么地方,做了什么事

    3、有哪些代码是冗余的

    4、记录文档


三、数据字典设计

    1、根据功能设计数据字典初稿

    2、对照功能点,一个个的过,看是否能实现预期的功能

    3、如果后期要升级,是否好扩展

    4、业务方面能支持的情况下,看是否会有性能瓶颈

    5、是否需要增加冗余字典,查询优化


四、接口列表划分

    1、根据需求,罗列接口列表

    2、重新审查接口列表,是否有重复的

    3、不同接口之间是否有部分做的同样的事,是否需要抽离

    4、重新根据功能进行接口聚合,分类,整理完整列表

    5、拿着接口列表,分别看看需求和现有功能是否能满足

    6、给出完整确认的接口列表


五、定义接口

    1、根据接口列表写注释

    2、需要输入哪些参数,分别代表什么意思

    3、这些参数需要做哪些格式验证

    4、业务方面需要做哪些验证

    5、非查询条件,需要做哪些数据更新操作

    6、接口返回什么


六、根据接口定义写代码

    1、根据接口定义,编写代码

    2、写相应的demo,测试各种情况

    3、监控查看接口返回是否正常

    4、后期做成能自动监控


七、接口文档

    1、编写apidoc需要的注释

    2、生成apidoc文档

    3、更新到文档库

    4、查看文档是否有错误


八、旧项目升级

    1、如果是从旧项目升级,需要将旧数据,写脚本导入写服务中

    2、旧的代码中,所有涉及到这块的,根据之前列的文档,一个个的改成接口调用

    3、改动一处,即进行完整测试,并做相应标记

    4、全部改完之后,整体测试


九、上线

    1、代码上线前,将旧数据转换脚本启动,并跑完

    2、代码通过版本控制器上线,同时转换脚本开启,避免上线过程中产生的新数据未同步

    3、上线测试是否正常,并重点关注error_log

    4、查看旧数据库是否还有数据新增,以及新数据库数据增长是否正常

    5、查看接口监控日志,是否有异常调用

    6、关注用户反馈,自己多测几次正常流程,特别是涉及到改动的地方

php文件包含路径问题


编	写:袁	亮
时	间:2015-12-01
说	明:php文件包含路径问题

一、解决什么问题
	1、在某些项目代码中,会出现包含出错问题
	2、多次include的时候,会发现不知道包含的到底是哪个文件
	3、某些项目代码中,找不到对应include进来的文件

二、前置知识:3种路径
	1、绝对路径
		linux下,以/开头的路径
		window下以盘符开头的,比如c:/
	2、相对路径
		以.或者..开头的路径
	3、不确定路径
		非上述两种情况的都是

三、包含路径include_path
	1、这是一个目录列表
	2、在php查找文件的时候起作用,主要是以下这些函数
		include,require,fopen,file,readfile,file_get_contents
	3、查找文件的时候,会根据include_path中的目录列表一个个去找,找到之后中止返回
	4、功能类似系统中的环境变量
	5、可以通过php.ini或者php代码中进行设置(也可以通过php函数读取)
	6、默认值是. 代表当前工作目录(简单来说就是访问的第一个php文件所在的目录)

四、查找要包含哪个文件
	1、包含的是绝对路径的文件
		与include_path无关,直接引用绝对路径所对应的文件
	2、包含的是相对路径的文件
		跳过include_path,根据工作路径拼接上相对路径,查找文件,如果有则包含,没有则报错
		ps:工作路径即访问的第一个php文件所在的目录
	3、包含的是不确定路径的文件
		3.1 逐个使用include_path中的目录跟不确定路径拼接查找文件,找到则退出
		3.2 如果没有找到,则根据包含语句include所在的文件的目录,拼接上不确定路径查找文件
		3.3 如果还是没有,则报错

五、解决方案
	1、项目的一个公共文件,通过__FILE__,或者__DIR__(php 5.3后),结合dirname来计算获取项目根目录
	2、所有文件包含,均通过项目根目录进行拼接,得到绝对路径,再包含
	3、使用不确定路径包含文件
		3.1 使用不确定路径,包含当前目录或当前目录的子目录下的文件
		3.2 这种方法性能较差,因为必然是经过多次查找才能得到
		3.3 而且在项目工作目录出现同名文件,则会出现包含到错误文件的情况
		3.4 常见于sdk包,一般情况下少用

参考文档:
1、PHP中require和include路径问题详解
	http://www.cnblogs.com/rainman/p/4177302.html
2、PHP手册
	http://php.net/manual/zh/ini.core.php#ini.include-path
	http://php.net/manual/zh/function.set-include-path.php

使用token来解决用户信息同步问题


编	写:袁	亮
时	间:2015-11-27
说	明:多应用系统用户信息统一安全升级策略

一、问题
	1、post请求之后,后退按钮导致加载失败,提示需要重新提交数据问题的解决
	2、用户信息被抓包,会导致账号泄漏问题
	
二、原因
	1、根据http协议,post请求非幂等,不能缓存,因此有响应头Pragma:no-cache
	2、后退的时候,浏览器会强制提醒用户,确认是否重新输入数据
	3、因此后退会出现白页

三、可能解决思路
	1、post请求换成get请求,绕过限制
		1.1 私密数据不安全,如果链接发给其他人,会导致账号被盗
		1.2 统计代码中,会把这些链接都给存储下来,太危险
	2、对get的数据进行可逆加密并加过期时间
		还是解决不了上面的两个问题
	3、先post发送私密数据过去,然后get跳转
	
四、完整思路
	1、私密数据,必须要走post,不能get
	2、先通过服务器间请求,将私密数据post过去
		2.1 在客户端对数据进行签名及有效期
		2.2 通过post将数据通过服务器与服务器传输
		2.3 服务端返回该数据存储的token(类似session存储)
			为防止服务器返回较慢,导致token丢失,token以客户端传过去的签名为准
		2.4 该数据,只存储一个小时,超过则失效
	3、get形式带上token去请求数据
		3.1 根据token,取到对应的数据
		3.2 用户之后的token要删除,不允许重复使用
		3.3 取出的数据需要验证是否有效期内,并验证签名是否正确
	4、解决了哪些问题
		4.1 没有通过get传输私密数据
		4.2 浏览器没有发起post请求,因此不存在后退刷新的问题
		4.3 私密数据通过服务器间的post请求,因此对用户抓包,并不能获取到这份私密数据
			抓更原始的包那就没办法,虽然不知道原始数据,但还是能登陆到用户账户上
	5、导致的问题及解决办法
		5.1 比之前多了一次http请求,会变的更慢
			在相应的服务器端加host,降低解析时间(同一机房,走内网)
			服务端只做数据存储到内存,不做额外操作降低运行时间
			客户端设置超时,防止卡住
		5.2 memcache存储的数据,存在一定几率丢失
			可以暂时不考虑,概率太低,而且最坏的影响也就是用户某一次可能登陆不上(只有新用户)
		5.3 token丢失或被抓包
			32位的加盐散列,基本可以不考虑被暴力强刷
			token即使丢失,问题也不大,因为token生成之后,用户基本上马上就使用,之后token就失效了
	

使用范例见附件:build_query

Apidoc的安装及使用

整    理:曹燕

时    间:2015-11-27

说    明:Apidoc的安装及使用(官方文档:http://apidocjs.com/

 

1.安装

2.运行

3.apidoc.json配置文件

4.注释中必需的部分

5.继承

6.apidoc的注释规则

(1)@api——定义接口的请求方式、请求路径、标题

(2)@apiDefine——定义一个可重用的块

(3)@apiDescription——api方法的详细介绍

(4)@apiError——出错情况的描述

(5)@apiErrorExample——一个返回出错信息的示例

(6)@apiExample——使用一个接口的示例

(7)@apiGroup——对块进行分类,便于导航条分类

(8)@apiHeader

(9)@apiHeaderExample

(10)@apiIgnore——不被转换的块

(11)@apiName——接口的名称

(12)@apiParam——描述接口的参数

(13)@apiParamExample——接口参数的一个示例

(14)@apiPermission

(16)@apiSuccess——成功时的返回值

(17)@apiSuccessExample——一个成功的返回信息的示例

(18)@apiUse——调用一个已经定义好的块

(19)@apiVersion——一个块的版本信息

 

1.安装

npm install apidoc -g

2.运行

apidoc -i myapp/ -o apidoc/ -t mytemplate/

-i 输入文件的目录,即项目文件夹

-o 输出目录,即放置生成文档的位置

-t 使用的模板,会有默认的模板,当然也可以用自己定义的模板

示例: apidoc -i abc/ -o doc/   apidoc的使用1956

3.apidoc.json配置文件

放在你的工程项目的根目录下,是对项目的概要介绍,包括标题、简要介绍、版本等。

{

"name": "育儿网",

"version": "1.0.0",

"description": "育儿API文档",

"title": "API文档",

"template": {

"withCompare": true,

"withGenerator": true

}

}

其中name、version、description都会被显示出来。

4.注释中必需的部分

/**

* @api {get} /user/:id Request User information

* @apiName GetUser

* @apiGroup User

*/

  • 注释块必须用/** */包围
  • @api {get} /user/:id Request User information

注释块必须以@api开头,否则会忽视这个注释块

  • @apiName必须是一个独一无二的名字
  • @apiGroup的作用是给这个方法分组

5.继承apidoc的使用2448

@apiDefine定义了一个可重用的块,然后其他块调用这个块的时候就写:

@apiUse UserNotFoundError

在生成的文档中会自动填充成UserNotFoundError块的具体内容。

Apidoc中的继承只能继承一层,层数多了会影响可读性。

6.apidoc的注释规则

(1)@api——定义接口的请求方式、请求路径、标题

【开头必需,除非是@apiDefine开头】apidoc的使用2644

Method:必须,方法的请求方式,如get、post、put、delete...

Path:必须,请求路径

Title:可选,可选,用于导航和文章的子标题apidoc的使用2725

(2)@apiDefine——定义一个可重用的块apidoc的使用2753

Name:必须,独一无二的名字,之后引用这个块就是用这个名字

Title:可选,标题

Description:可选,详细介绍,另起一行写apidoc的使用2824

(3)@apiDescription——api方法的详细介绍apidoc的使用2858

Text:必须,api方法的文字介绍

(4)@apiError——出错情况的描述apidoc的使用2902

(Group):可选,有了group值之后该错误会被分组;默认归类为Error 4xx。

{Type}:可选,返回类型,如{Boolean},{Number},{String}等。

Field:必须,返回标识符,例如错误码。

Description:可选,对错误码的描述。apidoc的使用3041

(5)@apiErrorExample——一个返回出错信息的示例

会以预格式化代码输出到页面apidoc的使用3091

{type}:可选,返回信息的格式

Title:可选,这个出错信息的标题

Example:必须,具体的返回信息apidoc的使用3149

(6)@apiExample——使用一个接口的示例

会以预格式化代码输出到页面apidoc的使用3192

{type}:可选,代码的语言

Title:必须,这个例子的标题

Example:必须,使用接口的代码apidoc的使用3246

(7)@apiGroup——对块进行分类,便于导航条分类apidoc的使用3278

Name:必须,分类的名称apidoc的使用3294

(8)@apiHeader

暂略

(9)@apiHeaderExample

暂略

(10)@apiIgnore——不被转换的块apidoc的使用3361

将这句放在块的起始位置,这样进行转换的时候这个块就会被跳过,常常用于一个块还没有开发完毕的时候。

Hint:可选,描述为什么不转换这个块apidoc的使用3432

(11)@apiName——接口的名称apidoc的使用3455

Name:必须,接口的名称,必须是独一无二的名称(允许版本不同的同一名称)apidoc的使用3495

(12)@apiParam——描述接口的参数apidoc的使用3521

(group):可选,所有的参数会被分到这个类里,如果不设置,就分到Parameter。

{type}:可选,参数的类型,如{String}等。

{type{size}}:可选,参数取值的详细信息,如

{number{100-999}}——参数必须是个100-999的数字

{string{2..5}}——参数必须是2-5个字符的字符串

{type=allowedValues}:可选,关于变量允许取值的信息,如

{string="small","huge"}——参数必须是包含”small”或”huge”的字符串

Field:必须,变量名,表示该参数对于接口是必须的

[field]:必须,变量名,表示该参数对于接口不是必须的

=defaultValue:可选,参数的默认取值

Description:可选,参数的描述apidoc的使用3884

(13)@apiParamExample——接口参数的一个示例apidoc的使用3919

{type}:可选,请求信息的格式

Title:可选,示例的标题

Example:必须,请求的具体信息apidoc的使用3973

(14)@apiPermission

暂略

(15)@apiSampleRequest——模拟请求时的urlapidoc的使用4031

(16)@apiSuccess——成功时的返回值apidoc的使用4602

(group):可选,所有的参数会被分到这个类里,如果不设置,就分到Success 200。

{type}:可选,参数的类型,如{String}等。

Field:必须,返回标识符。

Description:可选,成功码的描述。apidoc的使用4723

(17)@apiSuccessExample——一个成功的返回信息的示例apidoc的使用4763

{type}:可选,返回信息的格式

Title:可选,示例的标题

Example:必须,返回的具体信息apidoc的使用4817

(18)@apiUse——调用一个已经定义好的块

已经定义的块是指用@apiDefine定义的块apidoc的使用4869

Name:必须,@apiDefine定义的块的名称apidoc的使用4897

(19)@apiVersion——一个块的版本信息

Group和name值都相同的块,可以进行不同版本的对比。可用于在生成的文档中和之前的版本进行比较,增加和修改的会用绿色标出、删除的会用红色标出。apidoc的使用5000

Version:必须,版本号apidoc的使用5017

https的使用注意事项


编	写:袁	亮
时	间:2015-11-20
说	明:https的使用注意事项

一、全部https的优缺点以及选择
	1、优点
		1.1 安全性高
	2、缺点
		2.2 用户访问会变慢,特别是第一次访问(需要下载证书)
		2.2 开发成本较高,https页面的所有资源都必须是https资源
		2.3 统计代码不能使用,大部分统计代码都不提供https版本
		2.4 服务器端的负载也会变高
	3、其他网站参考
		3.1 百度、淘宝等很多二级域名也不是https
		3.2 京东大部分都不是https
	4、结论
		只针对安全级别高的几个页面采用https即可,不需要整个域名都使用https
		
二、开发过程注意事项
	1、静态资源都必须是https
		1.1 js等请求,浏览器直接会阻止http的请求
		1.2 图片请求,http的不阻止,但是会报warning错误
		1.3 为兼容http和https同时访问,可以写//***.ci123.com/****,会自动根据当前的访问协议加上http或者https
	2、ajax请求
		2.1 ajax请求也必须是同协议的,否则将跨域,不能访问
		2.2 jsonp可以解决这个问题,但最好不要这么做
	3、核心cookie可以设置为仅https访问
		3.1 淘宝中的skt,对应的应该是一个sessionId,就是仅https的
		3.2 这个设置要小心,因为该cookie在http中是访问不到的
		3.3 可以防止cookie被劫持,一般用与session
		3.4 用的不多
	4、关键地方,只配置https,不允许http访问
		4.1 防止用户被引导到http请求中,然后输入了敏感信息
		
三、安全问题
	1、证书伪造:浏览器有提示
	2、引导到http请求,然后盗取

四、其他
	1、https请求可以被缓存
	
附录:
1、HTTPS连接的前几毫秒发生了什么
	http://blog.jobbole.com/48369/ 
2、与HTTP有什么区别?HTTPS的七个误解
	http://www.chinaz.com/web/2015/0320/391752.shtml
3、HTTPS那些事(一)HTTPS原理
	http://www.guokr.com/post/114121/
	日志转载:HTTPS那些事(二)SSL证书
	http://www.guokr.com/post/116169/
	HTTPS那些事(三)攻击实例与防御
	http://www.guokr.com/blog/148613/
		


[PHP]PSR-1/2 育网修订版介绍以及推广

整    理:吴万利

时    间:2015-11-23

说    明:代码规范

关于PSR-1/2

国内靠谱翻译psr-1
国内靠谱翻译psr-2

补充规定

如下的这些都是基于上面规定来的,只是将一些规定明确化

psr-1部分

1 概览

  • 不准使用<\?=短标签

4.2 属性

  • 属性明确规定必须按照"下划线分隔式"
  • 常用变量名
  1. $sql: sql语句
  2. $page: 分页页码
  3. $limit: 每页显示多少条
  4. $ip: 用户ip地址
  5. $dated: 当前时间
  6. $ms: mysqls操作类实例
  7. $pager: 存放分页的html代码
  8. $data: 当前页面主要的数据
  9. $user_id: 用户id
  10. $username: 用户名
  11. $nickname: 用户昵称

psr-2部分

8. [补充]字符串单引号、双引号

  • 纯字符串的时候,使用单引号
  • 字符串中有变量时,使用双引号,变量用{}包含起来。
  1. $show = "你好,{$nickname}!";

9. [补充]用die不用exit

关于CodeSniffer

Github-PHP_CodeSniffer

关于如何操作?

检查我改动的代码

  1. phpcs --standard=PSR2 [files you\'ve changed]

结果展示

  1. FILE: /opt/ci123/www/html/vshop2_dev/svn/lab/src/entity/Product.php
  2. ----------------------------------------------------------------------
  3. FOUND 2 ERRORS AFFECTING 2 LINES
  4. ----------------------------------------------------------------------
  5. 74 | ERROR | Method name "Product::get_discount" is not in camel
  6. | | caps format
  7. 84 | ERROR | Method name "Product::get_photo_url" is not in camel
  8. | | caps format
  9. ----------------------------------------------------------------------

如果没有错误就没有提示

自动修复

  1. phpcbf --standard=PSR1 --standard=PSR2 Slider.php

结果展示

  1. Changing into directory /opt/ci123/www/html/vshop2_dev/svn/lab/src/entity
  2. Processing Slider.php [PHP => 379 tokens in 45 lines]... DONE in 23ms (1 fixable violations)
  3. => Fixing file: 0/1 violations remaining [made 2 passes]... DONE in 49ms
  4. Patched 1 file
  5. Time: 124ms; Memory: 6.75Mb

实际操作步骤说明

jquery – 事件绑定的不同写法


编	写:袁	亮
时	间:2015-11-16
说	明:jquery事件绑定

一、作用
	1、将html显示与js动态交互分离,不在html中写一堆的onclick等js
	2、简化代码,统一处理,防止遗漏以及重复写,比如ajax请求等
	3、结构清晰,分层,html,css,js等独立
	
二、如何绑定事件
	1、bind:向匹配元素添加一个或多个事件处理器
		1.1 所有jquery版本均支持,但1.7版本后,推荐使用on
		1.2 只能对已经存在的元素进行事件绑定
		1.3 了解即可,不使用
	2、live:向当前或未来的匹配元素添加一个或多个事件处理器
		2.1 jquery 1.9版本以上,已经删除
		2.2 使用on来代替
	3、delegate:为指定的元素(被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)
		3.1 jquery 1.4以上版本支持
		3.2 1.7以下版本的时候可以考虑使用,旧项目,新项目使用不要使用
	4、on【重点】:为指定的元素,添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。使用 on() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)
		4.1 jquery 1.7以上版本支持
		4.2 尽量使用这个,不要使用其他三种绑定
		
三、简单例子
	$("选择器").on({
		click:function(){
			console.log("我是"+$(this));
			console.log("点击触发");
		},
		mouseout:function(){
			console.log("我是"+$(this));
			console.log("鼠标触发");
		}
	},"子选择器(可选)");

四、常见问题(1.72版本jquery下测试)
	1、元素后加载,事件绑定不成功
		1.1 示范代码
			<code>
			<div class="test">你好</div>
			<script type="text/javascript">
			$(function(){
				//a标签事件绑定
				$(".test a").on({
					click:function(){
						console.log("click");
					}
				});

				//后加载生成dom节点
				$(".test").prepend("<a>测试连接</a><hr>");
			});
			</script>
			</code>
		1.2 因为a标签是后加载的元素,在绑定事件的时候,dom数上还没有该元素,因此绑定失败
		
	2、解决办法1
		2.1 事件绑定在已经存在的父元素上,匹配选择器是否符合
		2.2 示例代码
			<code>
			<div class="test">你好</div>
			<script type="text/javascript">
			$(function(){
				//后加载生成dom节点
				$(".test").prepend("<a>测试连接</a><hr>");

				//a标签事件绑定
				$(".test").on({
					click:function(){
						console.log("click");
					}
				},"a");
			});
			</script>
			</code>
		2.3 优点:绑定事件与处理逻辑脱离,代码更简单易懂
		2.4 缺点:需要注意选择器必须是已经存在的节点,子选择器可以是后加载的元素,不清楚的话,可以直接绑定在document上
				iphone下,会出问题,元素需要添加cursor: pointer;样式,手机使用,不采用这个

	3、解决办法2
		3.1 在元素加载后,执行绑定函数
		3.2 实例代码
			<code>
			<div class="test">你好</div>
			<script type="text/javascript">
			$(function(){
				$(".test").prepend("<a>测试连接</a><hr>");

				$(".test a").on({
					click:function(){
						console.log("click");
					}
				});
			});
			</script>
			</code>
		3.3 优点:各种情况都兼容,不会出现绑定失败
		3.4 缺点:代码可能不是那么好看,绑定事件混在了处理逻辑中

五、使用建议
	1、使用1.7以上版本jquery,2.0以下(不兼容ie8及以下版本)
	2、绑定事件均使用on来绑定,不要使用其他的
	3、对于后加载元素,在加载完成之后进行事件绑定,避免兼容性问题

六、原理,额外拓展,dom树结构(了解即可)
	1、可以使用off来取消事件绑定
	2、可以使用.one,只绑定一次,触发之后就取消绑定
	3、页面dom数结构
	4、事件如何冒泡

附参考文档:
	1、浅谈Jquery中的bind(),live(),delegate(),on()绑定事件方式
	2、jQuery三种事件绑定方式.bind(),.live(),.delegate()
	
	

【svn入门】- 1、初次使用

编  写:袁  亮
时  间:2015-11-02
说  明:从未接触过svn的人,5分钟内学会简单使用svn

一、获取svn地址
1、发送邮件到cjy@corp-ci.com,告知项目名,申请获取svn地址
例如:http://****/demo/
2、如果没有svn账号的,也一并邮件中申请
二、windows中开始使用
1、下载TortoiseSVN安装
2、在需要使用svn的文件目录上右击,选择SVN CheckOut

1

2

3、从svn控制中心,更新最新的程序到本地

3

4、新增的文件,添加到版本库中

4

5、将改动提交到svn控制中心(新增或者修改都需要做这步操作)

5

6

三、linux种开始使用
1、进入到项目开发目录 cd demo/
2、从版本库中checkout下来

1

3、从svn控制中心更新最新版本

2

3、将新文件加入到svn中
3
4、将改动过的内容提交到svn版本控制中心

4

四、常用命令使用
1、【svn入门】- 2、常用命令及练习

2、pdf版本下载:【svn入门】- 初次使用

【web安全规范】 – 2、基本安全防御


编	写:袁	亮
时	间:2015-10-09
说	明:web安全规范 - 2、基本安全防御

一、外部输入过滤
	1、所有外部参数,必须经过处理过滤
		get参数、post参数($_REQUEST)、cookie数据,$_SERVER中的referer,ua,ip等数据
	2、所有过滤,以服务端验证为准,js客户端验证仅仅是为了增强用户体验
		不允许仅仅是在js加了判断验证,服务端没有
	3、只允许使用过滤后的数据,不允许在后面再使用过滤前的原始参数
		$p = isset($_GET['p'])?intval($_GET['p']):1; //过滤参数
		后面只允许只用$p,不允许出现任何直接调用$_GET['p']的地方
	4、过滤方法
		4.1 整型参数,一律采用intval转换
		4.2 短字符串,采用正则验证,常用正则百度,或者参考统一类库
			比如手机号、用户名、邮箱、邮编等等
		4.3 长字符串,非富文本
			比如个人介绍等,过滤html标签(strip_tags),再加过滤sql注入函数(stripSql)
			如果没有验证完全,或者不确定,可以使用mysql_escape_string()进行转义
		4.4 富文本编辑器的长字符串内容
			htmlspecialchars
			采用统一函数或者类库验证过滤
		4.5 这块详见附件 web安全规范 - 参数过滤
	5、严禁使用register_global、extract函数,php配置中也不允许开启register_global
		也不允许自己写代码,将外部变量全部变成内部变量,很多旧项目中就有
		也不要开启magic_quotes,在需要的时候使用addslashes转义

二、报错信息
	1、错误信息只能显示我们定义的对用户友好的内容,不允许显示与实际错误相关的内容
	2、线上不允许开启报错,包括php.ini和程序中的display_errors
	3、特别要注意,类似mysql_error等,只允许记log,不允许输出到页面
	4、必须要记录日志,这是之后排查的唯一依据
	5、日志不允许web直接访问到
	6、更多报错相关信息,请参考内部博客
		http://blog.geekman.vip/archives/27

三、数据存储
	1、log文件不允许存储在web能访问的地方
	2、cookie记录
		2.1 必须设置httponly属性,防止js读取
		2.2 cookie中不允许存储敏感数据,比如用户密码或者邮箱,手机号等
		2.3 cookie内容必须添加签名,并存储,验证cookie的时候必须比对签名是否正确
	3、数据库存储用户密码
		3.1 不允许存储明文密码
		3.2 必须添加盐值做散列
	4、cookie、session等用户登录凭证,需要设置过期时间,防止被劫持之后,一直有效
	5、注意加密算法和编码、散列的区别
		不要误拿编码做加密(base64、urlencode等等)
		不要使用自己编写的加密算法,采用成熟的高安全性算法
	6、日志文件中,不允许记录密码、银行账号等敏感数据

四、数据签名
	1、签名做法可以参考内部博客
		http://blog.geekman.vip/archives/46
	2、cookie存储需要签名
	3、写接口必须加签名
	4、敏感的读数据接口也必须添加签名验证,比如用户邮寄地址等

五、防暴力破解
	1、用户登录等危险操作必须考虑暴力破解的情况
	2、连续错误次数达到一定次数,则需要一个封禁时间
	3、同一个ip同时对多个账号多次尝试也需要处理
	4、发现有人暴力破解的时候,需要有报警机制,比如邮件、短信等

六、业务逻辑bug
	1、发布的时候,进行了相应的过滤,但是编辑的时候未处理,也会导致bug
	2、修改密码的时候,不进行验证,直接修改
	3、购买商品的时候,价格直接通过参数传递结算
	4、找回密码的时候,通过安全问题来验证,但是安全问题可以在登陆的时候直接修改
	5、这些业务逻辑的bug,需要在需求、开发阶段就要多想想,特别是一些比较危险的操作

七、越权访问
	1、所有后台、管理员操作的地方必须要经过权限验证
	2、所有验证必须是通过服务端验证,不允许采用js隐藏,不显示按钮等来完成
	3、每次都必须验证,不要指望在入口那边验证过了,操作的时候就可以不验证
	4、权限验证,不要寄希望与链接、入口别人不知道,浏览器插件、搜索引擎,都有可能泄露
	5、特别要注意调用接口的地方,不要遗漏
	6、所有操作,都必须想想,这是不是一个所有人都可以任意访问的资源,如果不是,都需要权限验证

八、服务器安全
	1、mysql资源
		1.1 除非特殊申请,否则主库增删改查权限,从库查权限
		1.2 给定权限的时候,必须限制ip,一般是内网固定某台
	2、web服务
		不允许使用root账号启动,比如apache等(我们的云主机上有见过root启动的)
		不要安装不用的扩展,很多扩展是有高危漏洞的
	3、redis、memcache资源
		需要绑定ip,一般是内网
		也可设置加账号密码访问
	4、严禁rm -rf命令,同学的同事有过rm -rf之后,损失一个亿的教训
	5、程序源码被直接显示出来
		解析不当+程序员操作不当,导致.bak文件等直接源码显示出来
	6、.svn文件夹等,直接可以遍历扫描
	7、web访问目录层级,web不允许直接访问到项目代码根目录
		/项目代码根目录/webroot/

九、文件上传
	1、上传文件的存储目录,不允许给执行权限【最重要】
	2、上传图片采用其他域名访问,与web服务域名分开
	3、文件扩展名白名单过滤
	4、存储文件名必须系统生成,不允许用户自定义
	5、想了解更多,可以参考内部博客
		http://blog.geekman.vip/archives/301

十、不要调用系统命令
	1、不要在web服务中调用shell命令,比如exec,system,eval之类的
	2、实在要用,shell命令的参数不要是通过web参数带过来的,否则很容易导致系统被攻破

十一、测试环境
	1、重要项目,必须有搭建测试环境(可以在本地搭建)
	2、测试环境的数据库、memcache等资源也必须是用的测试的
	3、不要把调试后门给上传到了线上,因为不知道哪天调试后门就会被人非法访问了
		不要觉得你这个链接从来没公布出去别人不知道,有个东西叫浏览器插件,还有个东西叫抓包

十二、跳转链接
	1、登陆等callback页面,必须要对callback后的链接进行验证
		否则给用户发了一个育儿网的链接,结果用户登陆之后跳到一个恶意网站,在恶意网站提示用户账户密码错误,请重新输入,然后就会导致用户账户密码被盗
	2、进行有根据用户的referer来进行跳转的,referer中的链接也需要验证,可以随意伪造

php发送邮件的相关知识

编	写:袁	亮
时	间:2015-07-28
说	明:php发送邮件的相关知识

一、什么时候需要用到?
	1、系统监控,应用监控报警
	2、相应的项目统计
	3、用户注册、重置密码
	4、发送推广内容(现在很少)
	5、给用户的正式通知
	
二、php中发送邮件的方式
	1、使用封装好的PHPMailer类发送【常用】
		网上下载相应的类文件即可phpmailer
	2、使用smtp类发送
		与PHPMailer类似
	3、PEAR::Net_SMTP组件
		需要引用pear类库中的Net/SMTP.php和Mail/mime.php,服务器上没有的话,直接下载也可以
		据说挺好用的,很强大,没用过,可以尝试下
	4、内置函数mail
		php需要安装正在运行的邮件系统,了解即可,平时不用
	5、popen管道形式发送
		需要配置邮件服务器,了解即可,我也没用过

三、PHPMailer简单demo
	IsSMTP();//使用smtp协议
	$mail->SMTPDebug = false;
	$mail->Host = "smtp.163.com"; //使用哪个smtp服务器,在对应的邮件设置里找SMTP服务器
	$mail->SMTPAuth = true; //需要认证,必选,基本没有不认证的了
	$mail->Username = "ci123_demo"; //邮箱账号,不需要@什么的,需要在邮箱里开启smtp服务,否则失败
	$mail->Password = "nymqjctyjlykkfpt"; //开启smtp服务的时候系统自动设置的密码(163是这样)

	$mail->CharSet = "UTF-8";//编码设置
	$mail->From = "ci123_demo@163.com";//发件人完整邮箱地址
	$mail->FromName = "育儿网";//发件人备注名,可以随意填写,方便自己看即可

	//发送给谁,可以发给多个人,多次执行AddAddress,前面是邮箱地址,后面是备注
	$mail->AddAddress('yuanliang@corp-ci.com', "袁亮");
	$mail->AddCC('629036398@qq.com','暗夜御林');//抄送,暗送是BCC

	$mail->Subject = '邮件标题';
	$content = '邮件测试内容'.date('Y-m-d H:i:s');
	//$mail->Body = $content;//纯文本内容,不能发送html
	$mail->MsgHTML($content);//以html的形式发送,一般用这个,方便排版

	if(!$mail->Send()){
		echo $mail->ErrorInfo;
		die();
	}
	echo 'succ';
	die();
		
四、PHPMailer注意事项
	1、php需要支持sockets,大部分情况下都开启了,phpinfo查看Sockets Support
	2、最常见的错误是需要开启smtp服务,到对应的邮箱里开启
		smtp服务器地址
		邮箱账号
		授权密码,非邮箱登陆密码
	3、需要发送html内容的,需要使用MsgHTML
	4、发送失败的情况下,第一反应是看报错信息,而不是瞎猜
		
五、邮件发送的注意事项
	1、限制
		每个邮件服务器,都有限制邮件数量,163的限制比较少
		出现莫名其妙收不到的情况,可以尝试换一个账号发,换一个账号收等来测试是哪方面有问题
	2、内容过滤
		垃圾内容过滤是邮件服务器最核心的功能,如果对用户发的时候,需要注意内容是否会被过滤,可以先拿自己的账号测试
	3、发送附件
		AddAttachment('文件绝对路径','附件名称');
		
六、邮件协议
	1、POP3
		1.1 POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件
		1.2 POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上
			比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的
	2、IMAP
		2.1 交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一
		2.2 IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,
			对邮件进行的操作,服务器上的邮件也会做相应的动作
		2.3 IMAP像POP3那样提供了方便的邮件下载服务,让用户能进行离线阅读
	3、SMTP
		3.1 简单邮件传输协议;它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式
		3.2 SMTP认证,就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,现在已经没有不需要认证的了,除非自己搭
		3.3 发送邮件,必须是开的这个服务
		
附录:
	http://www.w3school.com.cn/php/php_ref_mail.asp
	http://blog.csdn.net/heiyeshuwu/article/details/458170
	http://blog.csdn.net/rainday0310/article/details/6281936
	http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html