学习 Javascript 之变量
变量的声明
|
|
变量的声明作用域
- var
- 在全局作用域内有效
- let
- 只在声明所在的块级作用域内有效
- const
- 只在声明所在的块级作用域内有效
变量的声明陷阱
- 变量提升
- 变量无法在 let 命令声明之前使用,否则报错
- 变量可以在 var 命令声明之前使用,值为 undefined
- 暂时性死区
- 在代码块内,使用 let 命令声明变量之前,该变量都是不可用的
- 重复声明
- var 命令允许在相同作用域内,重复声明一个变量
- let 命令不允许在相同作用域内,重复声明一个变量
解构赋值
|
|
变量的解构赋值用途如下:
- 交换变量的值
- 从函数返回多个值
- 函数参数的定义
- 提取 JSON 数据
- 函数参数的默认值
- 遍历 Map 结构
- 输入模块的指定方法
Head First Design Patterns
如何定义模式
模式是某种情景下,针对某问题的某种解决方案。
- 情景
- 应用某个模式的情况,应该是会不断出现的情况
- 问题
- 想在某个情景下达到的目标,但也可以是某情景下的约束
- 解决方案
- 一个通用的设计,用来解决约束、达到目标
帮助记忆上述概念的方法
如果你发现自己处于某个情境下,面对着所欲达到的目标被一群约束影响着的问题,然而,你能够应用某个设计,克服这些约束并达到该目标,将你领向某个解决方案。
比如
- 问题:我要如何准时上班
- 情景:我的钥匙锁在车里了 | 搭地铁肯定要迟早了
- 解决方案:打破窗户、进入车内、启动引擎,开车上班 | 打开手机、呼叫滴滴、上出租车,打车上班。
更多定义的细节:
- 意图
- 动机
- 对比
- 适用性
- 举一反三
如何更加详细去定义和学习一个设计模式
- 名称:用于学习与分享时共享词汇,概括性描述一个设计模式的作用
- 分类:用于归纳设计模式的用途
- 动机:给出了问题以及如何解决这个问题的具体场景
- 结构:提供了图示,显示出参与此模式的类之间的关系
- 参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色
- 结果:描述采用此模式之后产生的效果:好与不好
- 协作:告诉我们参与者如何在此模式中合作
- 实现:提供了你在实现该模式时需要使用的技巧,以及应该小心面对的问题
- 代码:提供实现的代码,对如何实现有所帮助
- 已知应用:用来描述已经在真实系统中发现的模式例子
- 相关模式:描述了此模式和其他模式之间的关系
「Tips」Yii2 前端请求的参数字段映射数据模型的属性
使用 Yii 2 构建 RESTFul API 项目时,需要实现一个功能。这个功能可以将 HTTP 请求的参数和后端数据模型相映射,让前端的请求参数命名和后端数据的模型属性不需要保持一致,并在指定场景中实现数据验证。实现代码如下:
「Tips」.htaccess 配置 HTTP Header
使用 Yii 2 做 RESTFul API 项目时,发现在前端发起一个请求时,会出现以下错误:
排查问题进行了很久,最后才发现在 Yii 2 的 web
目录下,有个文件 .htaccess
,是可以配置 Apache
服务器接受 HTTP 请求的头部信息的,在特定选项加入 access-token
即刻不再报错,因为本次项目使用 HTTP Header
传递 access-token
的,没有加入 access-token
就意味 Apache
服务器不接受头部带有 access-token
的 HTTP 请求 。文件配置代码如下:
「Tips」PHP 7.1 命名空间的新特性和使用方法
新特性和使用方法如下:
Swagger-PHP 基础使用
Swagger-PHP 的基本语法
参考文档
常用属性
红色为必写的字段,蓝色为封装的字段。
- @SWG\Swagger
- swagger
- info: @SWG\Info
- host - 接口域名
- basePath - 接口前缀路径
- schemes: [“http”, “https”, “ws”, “wss”]
- consumes - 请求 Mime Types
- produces - 响应 Mime Types
- paths: @SWG\Path - @SWG\Info
- title - 文档标题
- description - 文档描述
- termsOfService - 所属团队
- contact: @SWG\Contact - 联系方式
- @SWG\Contact
- url - 联系链接
- name - 联系名称
- email - 联系邮箱
- @SWG\License
- name - 开源许可证
- url - 许可证地址
- @SWG\Path
- get: @SWG\Get - HTTP Get 请求
- put: @SWG\Put - HTTP Put 请求
- post: @SWG\Post - HTTP Post 请求
- delete: @SWG\Delete - HTTP Delete 请求
- options: @SWG\Options - HTTP Options 请求
- @SWG\GET
- tags - 请求分类
- summary - 请求简介
- description - 请求描述
- operationId - 请求编号,要求唯一
- consumes - 请求 Mime Types
- produces - 响应 Mime Types
- parameters: @SWG\Parameter - 请求参数
- responses: @SWG\Response - 请求响应
- schemes: [“http”,”https”,”ws”,”wss”] - 请求协议
- deprecated - 是否弃用
- @SWG\Parameter
- name - 请求参数名称
- in: [“query”,”header”,”path”,”formData”,”body”] - 请求参数存放方式
- description - 请求参数描述
- required - 是否要求
- schema - 当
in
为body
时可以使用,用于描述参数 - type: [“string”, “number”, “integer”, “boolean”, “array”, “file”] - 请求参数类型
- format: [“int32”, “int64”, “float”, “double”, “byte”, “date”, “date-time”] - 请求参数格式
- allowEmptyValue - 是否允许空值
- items - 当
type
为array
,items
为required
,描述参数数组 - collectionFormat
- default - 请求参数默认值
- @SWG\Response
- default
- response object
- description - 响应描述
- schema: @SWG\Schema
- headers: @SWG\Header - 响应头部
- example: @SWG\Example - 响应数据例子
- reference object
- $ref
- HTTP Status Code
- response object
- description
- schema: @SWG\Schema
- headers: @SWG\Header
- example: @SWG\Example
- reference object
- $ref - @SWG\Definition
- definition
- required
- @SWG\Property - @SWG\Property
- property - 模型成员属性
- type: [“string”, “number”, “integer”, “boolean”, “array”, “file”] - 模型参数类型
- format: [“int32”, “int64”, “float”, “double”, “byte”, “date”, “date-time”] - 模型参数格式
- @SWG\Header
- header - 头部名称
- type - 头部数值类型
- description - 头部简介
模块文件上使用
打开文件 api/modules/v1/module.php
,添加代码如下:
上述代码生成文档时的效果如下图:
控制器文件上使用
打开文件 api/modules/v1/controllers/MenuController.php
上述代码生成文档时的效果如下图:
模型文件上使用
|
|
使用 Yii2 构建 RESTFul API
安装 Yii2 高级模板
|
|
初始化项目
打开文件 common/config/main-local.php
,配置数据库信息
执行迁移文件,生成数据表
新建模板 api
,执行操作如下:
- 复制目录
frontend
为api
- 复制目录
environments/dev/frontend
为environments/dev/api
- 复制目录
environments/prod/frontend
为environments/prod/api
- 修改目录
api
里面文件的命名空间namespace
- 打开文件
common/config/bootstrap.php
并加入代码Yii::setAlias('api', dirname(dirname(__DIR__)) . '/api');
清理模板 api
,删除文件如下:
- api/assets
- api/views
- api/controllers
- api/web/assets
- api/web/css
配置 Apache 虚拟主机
搭建基本的 RESTFul 架构
创建控制器
在目录 api/controllers
下创建控制器 UserController
,代码如下:
配置路由规则
打开文件 api/config/main-local.php
,在数组 $config['components']
中新增代码如下:
创建数据模型
在目录 api\models
新增数据模型,代码如下:
测试接口地址
使用 HTTP GET
的方式去访问 http://api.app/user
,得到 JSON 数据如下:
版本控制
实现方式
有两种方案可以实现 API 版本控制:
- 在 URL 中带上请求的版本号,比如:
http://example.com/v1/users
- 把版本号放在HTTP请求头中,通常通过 Accept 头,像这样:
Accept: application/json; version=v1
Yii2 两种方案都支持,官方推荐,使用模块来实现版本化,简化代码维护和管理,在 URL 上带上一个大版本号(比如: v1, v2),在每个大版本中,使用 Accept HTTP
请求头来判定小版本号并编写针对各小版本的条件语句。
创建模块
新建目录 api/modules/v1
,目录下新建文件 Module.php
,代码如下:
创建控制器
新建目录 api/modules/v1/controllers
,在该目录下新增控制器 OrderController.php
,代码如下:
创建模型
新建目录 api/modules/v1/models
,在该目录下新增数据模型 Order.php
,代码如下:
配置路由与模块
打开文件 api/config/main-local.php
,在数组 $config[]
新增模块版本,在数组 $config['components']['urlManager']['rules']
新增路由规则,代码如下:
测试接口地址
使用 HTTP GET
的方式去访问 http://api.app/v1/order
,得到 JSON 数据如下:
API 认证
Yii 2 有三种认证用户的验证方式
HttpBasicAuth::className()
:是通过弹窗填用户名密码,默认只需要在用户名栏填入Access-Token
返回接口数据。HttpBearerAuth::className()
:是通过请求Headers
带上Authorization: Bearer Access-Token
参数返回接口数据。QueryParamAuth::className()
:是通过URL
带上?access-token=Access-Token
参数返回接口数据。
采用 QueryParamAuth
方式进行验证,因为 RESTFul API
是无状态的,不能通过 session
或 cookie
来保持状态,在模块文件 Module.php
中修改代码如下:
使用 HTTP GET
的方式去访问 http://api.app/v1/order?access-token=HelloWorld
,得到 JSON 数据如下:
使用 Swagger 生成 API 可调试文档
配置 Swagger-UI
执行以下命令,将 Swagger-UI
克隆到 api/web/v1/
文件夹下:
执行以下命令,在目录 api/web/v1
下生成 Swagger
文档配置文件:
打开文件 api/web/v1/swagger-ui/dist/index.html
,修改生成文档的配置文件地址:
Swagger-PHP 的基本语法
参考文档
红色为必写的字段,蓝色为封装的字段。
- @SWG\Swagger
- swagger
- info: @SWG\Info
- host - 接口域名
- basePath - 接口前缀路径
- schemes: [“http”, “https”, “ws”, “wss”]
- consumes - 请求 Mime Types
- produces - 响应 Mime Types
- paths: @SWG\Path - @SWG\Info
- title - 文档标题
- description - 文档描述
- termsOfService - 所属团队
- contact: @SWG\Contact - 联系方式
- @SWG\Contact
- url - 联系链接
- name - 联系名称
- email - 联系邮箱
- @SWG\License
- name - 开源许可证
- url - 许可证地址
- @SWG\Path
- get: @SWG\Get - HTTP Get 请求
- put: @SWG\Put - HTTP Put 请求
- post: @SWG\Post - HTTP Post 请求
- delete: @SWG\Delete - HTTP Delete 请求
- options: @SWG\Options - HTTP Options 请求
- @SWG\GET
- tags - 请求分类
- summary - 请求简介
- description - 请求描述
- operationId - 请求编号,要求唯一
- consumes - 请求 Mime Types
- produces - 响应 Mime Types
- parameters: @SWG\Parameter - 请求参数
- responses: @SWG\Response - 请求响应
- schemes: [“http”,”https”,”ws”,”wss”] - 请求协议
- deprecated - 是否弃用
- @SWG\Parameter
- name - 请求参数名称
- in: [“query”,”header”,”path”,”formData”,”body”] - 请求参数存放方式
- description - 请求参数描述
- required - 是否要求
- schema - 当
in
为body
时可以使用,用于描述参数 - type: [“string”, “number”, “integer”, “boolean”, “array”, “file”] - 请求参数类型
- format: [“int32”, “int64”, “float”, “double”, “byte”, “date”, “date-time”] - 请求参数格式
- allowEmptyValue - 是否允许空值
- items - 当
type
为array
,items
为required
,描述参数数组 - collectionFormat
- default - 请求参数默认值
- @SWG\Response
- default
- response object
- description - 响应描述
- schema: @SWG\Schema
- headers: @SWG\Header - 响应头部
- example: @SWG\Example - 响应数据例子
- reference object
- $ref
- HTTP Status Code
- response object
- description
- schema: @SWG\Schema
- headers: @SWG\Header
- example: @SWG\Example
- reference object
- $ref - @SWG\Definition
- definition
- required
- @SWG\Property - @SWG\Property
- property - 模型成员属性
- type: [“string”, “number”, “integer”, “boolean”, “array”, “file”] - 模型参数类型
- format: [“int32”, “int64”, “float”, “double”, “byte”, “date”, “date-time”] - 模型参数格式
- @SWG\Header
- header - 头部名称
- type - 头部数值类型
- description - 头部简介
配置 Swagger-PHP
使用 Composer
安装 Swagger-PHP
,在项目根目录中执行命令如下:
在 api\controllers
新增文档控制器 DocumentController.php
,因为要生成不同版本的文档,控制器必须放在公用的目录,代码如下:
新增路由如下:
模块文件 app/modules/Module.php
新增注释如下:
Yii 2 的 RESTFul APT 会自动为控制器提供六个动作如:index
、view
、create
、update
、delete
、options
,给控制器 app/v1/controlelr/OrderController.php
新增以下注释,为其生成接口文档。
打开控制器 app/modules/v1/controller/UserController.php
,继承 actions() 方法,修改 user/create
的场景,并添加 user/create
文档生成注释代码,如下:
打开文件 app/modules/v1/models/User.php
,新增代码如下:
在 ap1/modules/v1
下新增控制器 MenuController.php
,新增模型 Menu.php
,配置好路由,控制器和模型代码如下:
模型
在浏览器中打开 URL: http://api.app/document/build/v1
生成文档。
API 授权
现在已经解决了 RESTFUL API 的脚手架、版本化、API 验证和 API 文档生成的问题,接下来我们来完成 API 授权功能。
首先我们需要建立授权数据,而所有授权数据相关的任务如下:
- 定义角色和权限;
- 建立角色和权限的关系;
- 定义规则;
- 将规则与角色和权限作关联;
- 指派角色给用户。
我们先配置所需的组件,我们使用 Yii2 自带 RBAC 组件进行权限控制,打开配置文件 api/config/main.php
,在数组 components
新增代码如下:
然后在根目录执行命令,在数据库创建好相关的数据表,执行命令如下:
在项目根目录 console/controllers
文件夹新建控制器 RbacController.php
,代码如下:
然后在根目录中执行命令 php yii rbac/init
,填充 RBAC 的测试数据,并在文件 v1/Module.php
中更改代码如下:
编写测试
如果是 RESTFul API 的架构,我会选择编写 API 测试和单元测试。首先先从 API 测试开始。首先在 api
中创建 API 测试配置文件,执行命令如下:
进入文件夹api/tests
,打开文件 api.suite.yml
,编写配置如下:
在文件夹 api
生成 API 测试文件,执行命令如下:
打开文件 api/tests/api/v1/SearchMenuCept.php
,编写代码如下:
打开文件 api/tests/api/v1/CreateMenuCept.php
,编写代码如下:
接着构建测试环境,并运行所编写的 API 测试,执行命令如下:
错误处理
Yii 2 的 REST 框架的 HTTP 状态代码如下:
- 200: OK。一切正常。
- 201: 响应 POST 请求时成功创建一个资源。Location header 包含的URL指向新创建的资源。
- 204: 该请求被成功处理,响应不包含正文内容 (类似 DELETE 请求)。
- 304: 资源没有被修改。可以使用缓存的版本。
- 400: 错误的请求。可能通过用户方面的多种原因引起的,例如在请求体内有无效的JSON 数据,无效的操作参数,等等。
- 401: 验证失败。
- 403: 已经经过身份验证的用户不允许访问指定的 API 末端。
- 404: 所请求的资源不存在。
- 405: 不被允许的方法。 请检查 Allow header 允许的HTTP方法。
- 415: 不支持的媒体类型。 所请求的内容类型或版本号是无效的。
- 422: 数据验证失败 (例如,响应一个 POST 请求)。 请检查响应体内详细的错误消息。
- 429: 请求过多。 由于限速请求被拒绝。
- 500: 内部服务器错误。 这可能是由于内部程序错误引起的。
对应的 class 使用如下:
- BadRequestHttpException - 400
- UnauthorizedHttpException - 401
- ForbiddenHttpException - 403
- NotFoundHttpException - 404
- MethodNotAllowedHttpException - 405
- UnsupportedMediaTypeHttpException - 415
- UnprocessableEntityHttpException - 422
- TooManyRequestsHttpException - 429
- ServerErrorHttpException - 500
「复习」使用阿里云从零开始部署 Laravel
准备
更新 Yum
更新 Yum 源
安装 Git
安装 Htop
安装 Vim
Nginx
安装 Nginx 代码仓库
安装 Nginx
启动 Nginx
开机启动 Nginx
Nginx 配置文件
- /usr/share/nginx/html 默认的代码目录
- /etc/nginx/conf.d/default.conf 默认的配置文件
MariaDB
安装 MariaDB
启动 MariaDB
初始化 MariaDB
开机启动 MariaDB
PHP
安装 PHP
启动 PHP-FPM
开机启动
配置 PHP 关联 Nginx,编辑 Nginx 配置文件如下:
在 /usr/share/nginx/html
新增文件 index.php
,编辑代码如下:
输入域名,检查 PHP 是否与 Nginx 关联起来
Redis
安装 Redis
启动 Redis
开机启动 Redis
Beanstalkd
安装 Beanstalkd
启动 Beanstalkd
开机启动
Composer
安装 Composer
全局设置国内镜像
Node.js
安装 Node.js
安装 webpack、gulp、bower
Gogs
设置子域名
禁用 SELinux 相关选项
创建 gogs 数据库
安装 Go
安装 Gogs
访问 URL 进行安装,安装 URL 是主机 IP 地址加上 3000 端口。
以守护进程的形式运行 Gogs:https://github.com/gogits/gogs/blob/master/scripts/init/centos/gogs
Walle
进入 MySQL,新增数据库如下:
安装依赖
代码检出
连接数据库
安装 vendor
初始化项目
配置 Nginx
然后访问你配置好的域名或服务器地址,管理员默认账号密码是 admin/admin
,开发者默认账号密码是 demo/demo
。
有些错误 walle 捕捉不到,默认操作日志在 /tmp/walle/ 下,具体可在 config/local.php 里 log.dir 配置路径,tail 着日志,部署看日志。
如果发现 /tmp/walle 下没有日志,很有可能是因为 CentOs 7 yum 安装的 php-fpm 默认 /tmp 目录不可写:/usr/lib/systemd/system/php-fpm.service 中的 PrivateTmp=true 禁止了向tmp目录写日志,解决方法如下:
Supervisor
安装 Supervisor
配置 Supervisor,打开刚才生成的配置文件 vim /etc/supervisord.conf
,把 include 块的注释打开,并修改如下:
使用新的配置文件启动 Supervisor
查看 Supervisor 是否正常启动
Vsftpd
安装 Vsftpd
开机启动
修改配置文件如下:
新增用户
Alias 常用进程命令
- Nginx
- alias nginx.start=’systemctl start nginx’
- alias nginx.restart=’systemctl restart nginx’
- alias nginx.stop=’systemctl stop nginx’
- alias nginx.status=’systemctl status nginx’
- Mysql
- alias mysql.start=’systemctl start mysql’
- alias mysql.restart=’systemctl restart mysql’
- alias mysql.stop=’systemctl stop mysql’
- alias mysql.status=’systemctl status mysql’
- PHP-FPM
- alias php-fpm.start=’systemctl start php-fpm’
- alias php-fpm.restart=’systemctl restart php-fpm’
- alias php-fpm.stop=’systemctl stop php-fpm’
- alias php-fpm.status=’systemctl status php-fpm’
- Redis
- alias redis.start=’systemctl start redis’
- alias redis.restart=’systemctl restart redis’
- alias redis.stop=’systemctl stop redis’
- alias redis.status=’systemctl status redis’
- Beanstalkd
- alias beanstalkd.start=’systemctl start beanstalkd’
- alias beanstalkd.restart=’systemctl restart beanstalkd’
- alias beanstalkd.stop=’systemctl stop beanstalkd’
- alias beanstalkd.status=’systemctl status beanstalkd’
- Gogs
- alias gogs.start=’/etc/rc.d/init.d/gogs start’
- alias gogs.stop=’/etc/rc.d/init.d/gogs stop’
- alias gogs.restart=’/etc/rc.d/init.d/gogs restart’
- alias gogs.status=’/etc/rc.d/init.d/gogs status’
学习 UML(二)
类图
类图(class diagram)只是 UML 的一部分,但它们可能是最常用的,因为类图在描述面向对象关系时非常有用。
类、抽象类、接口
类是类图的主要部分。类用带有类名的方框来描述,如下图所示:
抽象类通常使用斜体的类名,或者增加 {abstract}
到类名下来表示,如下图所示:
接口的定义方式和类相同,但接口必须增加 <<interface>>
到类名上来表示,如下图所示:
属性
属性用于描述一个类的属性,属性直接列在类名下面的格子中。属性使用符号来表示类属性的可见性,其中 +
对应 public
、-
对应 private
、#
对应 protected
,如下图所示:
操作
操作用于描述类方法,操作表示类方法可见性的办法与属性一致。类方法有参数,则包含在括号之中;类方法有返回类型,则用冒号来描述,如下图所示:
继承
UML 一般用「泛化」来描述继承关系。这个关系用从子类到父类的一条线来标识,线的顶端有一个空心闭合箭头,如下图所示:
实现
UML 用「实现」来描述接口和实现接口的类之间的关系。这个关系用从实现接口的类到接口的一条虚线来标识,线的顶端有一个空心闭合箭头,如下图所示:
关联
当一个类的属性保存了对另一个类的一个实例或多个实例的引用时,就产生了关联。类之间的关联有单向关联、双向关联和多个引用关联,如下图所示:
聚合和组合
聚合和组合都描述了一个类长期持有其他类的一个或多个实例的情况。通过聚合或组合,被引用的对象实例成为引用对象的一部分。
聚合的情况下,被包含对象是容器的一个核心部分,但是它们也可以同时被其他对象所包含。聚合关系用一条空心菱形开头的线来说明。
组合则是一个更强的关系。在组合中,被包含对象只能被它的容器所引用。当容器被删除时,它也应该被删除。组合关系可以用类聚合关系的方式描述,但是菱形必须是实心的。
描述使用
一个对象使用另一个对象的关系在 UML 中被描述为一个依赖关系。一个被使用的类可以作为类方法的参数传递或者作为方法调用的结果得到。
使用注解
类图可以捕捉到系统的结构,但类图并不能解释类处理任务的过程,可以通过使用注解来补充说明。注解由一个折角的方框组成。它通常包含伪代码片段。注解使类图变得易于理解。