php consult用法,YanPHP: YanPHP——一个为API开发而设计的高性能轻量级框架
YanPHP V0.2
Guide
Documentation
这是一个为API开发而设计的高性能轻量级框架。
框架为你集成了一些常用的类库,让你开发更加便捷。
另外引入了Composer,可以让你更加轻松地管理依赖以及处理命名空间问题。
让语法更加贴近原生PHP,并且在此基础上让你实现自己的定制化功能。
因为封装程度不高,所以框架的性能十分之优秀。
目录结构
├── Application --你的代码目录
│ ├── Cgi --分层应用根目录(这里是Cgi代码)
│ │ ├── Cache --缓存
│ │ ├── Compo --自定义组件
│ │ ├── Config --配置
│ │ ├── Controller --控制器,用于编写业务逻辑
│ │ ├── Logs --日志存放
│ │ ├── Model --模型层
│ │ ├── Param --入参定义,以及参数校验
│ │ └── Util --工具类库
│ └── Server --分层应用根目录(这里是Server代码)
│ │ ├── Cache --缓存
│ │ ├── Compo --自定义组件
│ │ ├── Config --配置
│ │ ├── Controller --控制器,用于编写业务逻辑
│ │ ├── Logs --日志存放
│ │ ├── Model --模型层
│ │ ├── Param --入参定义,以及参数校验
│ │ └── Util --工具类库
├── System --框架目录
│ └── Yan
│ ├── Common
│ └── Core
│ ├── Compo
│ └── Exception
安装
环境要求
Require:
PHP >= 7.0
Composer
安装步骤
先把YanPHP从github拷贝到本地
git clone https://github.com/kong36088/YanPHP.git
然后进行框架依赖组件的安装,这里需要用到composer。请确保您的机器中已经安装了composer
composer install
完成!
hello world
首先安装YanPHP的依赖项:
composer install
来编写我们的第一个hello world
首先我们需要先新增一个控制器
新建一个控制器文件 Application/Cgi/Controller/HelloController.php
namespace App\Cgi\Controller;
use Yan\Core\Compo\ResultInterface;
use Yan\Core\Controller;
class HelloController extends Controller
{
public function index(): ResultInterface
{
return $this->succ('hello world');
}
}
紧接着到Param目录下创建我们的控制器入参规则,
Application/Cgi/Param/HelloController.ini内容如下:
[index]
用命令行重新加载composer中注册的命名空间:
composer dump-autoload
最后,用浏览器访问我们刚才编写的hello world:http://localhost/interface.php/hello/index
返回结果为以下内容
{
"code":0,
"message":"hello world",
"data":[]
}
若有新增类库文件,记得一定要运行一次 composer dump-autoload 以刷新我们的autoloader
路由
默认路由规则
默认路由寻路路径是:/interface.php/controller/method
controller代表您的控制器,method是指向的方法
自定义路由规则
当然,您也可以自定义自己的路由规则。
路由规则存放在 Application/YourLevel/Config/router.php
$config['default_method'] = 'index'; //默认方法
$config['route'] = [
'/' => [ //被映射的路径
'request_method' => ['GET','POST'], //支持的http动作,支持GET和POST
'controller' => 'App\\Cgi\\Controller\\UserController', //所映射到的控制器,需要包含命名空间,映射到Application/Cgi/Controller/UserController
'method' => 'index' //所映射到的方法,映射到UserController的index方法
],
'/user' => [
'request_method' => ['GET'], //支持的http动作,支持GET
'controller' => 'App\\Cgi\\Controller\\UserController', //所映射到的控制器,需要包含命名空间,映射到Application/Cgi/Controller/UserController
'method' => 'getUser' //映射到UserController的index方法getUser方法
],
];
配置
配置文件统一存放在 Application/YourLevel/Config 目录下
Application下的各个文件夹对应着您应用的各个分层,每一层都采用自己独立的Config配置
系统配置相关
$config['namespace'] = 'App\\Cgi';
这里用于配置你的应用层采用的命名空间,在新添加应用层后请勿忘记修改这里的配置哦。
$config['session_path'] = BASE_PATH.'/Cache/session';
$config['session_name'] = 'YAN_SESSION';
session_path 用于配置session存放的僦
session_name 用于配置session名称,即用于标识用户session id的key值
日志配置相关
几种日志等级。比如日志等级配置为INFO,则INFO及INFO以上的(NOTICE、WARING、ERROR)等等级的日志将会被记录。
/**
'DEBUG'
'INFO'
'NOTICE'
'WARNING'
'ERROR'
'CRITICAL'
'ALERT'
'EMERGENCY'
*/
$config['log_level'] = 'DEBUG';
日志存放路径
/**
* The log path
*/
$config['log_path'] = BASE_PATH . '/logs/cgi.log';
/**
* 最大存放的日志文件数量
*/
$config['log_max_file'] = 0;
/**
* 配置日志记录的格式
* "[%datetime%] %channel%.%level_name%: %message% %context%\n";
*/
$config['log_format'] = "[%datetime%]-%extra.process_id% %channel%.%level_name%: %message% %context%\n";
database
database.php
config
options
description
db_host
DB host
db_user
用户名
db_password
密码
db_port
3306/(others)
端口号
db_database
库
db_charset
utf8/(others)
db_driver
mysql/postgres/sqlite/sqlsrv
目前支持四种数据库类型
可以配置多个数据库连接,默认使用default进行连接
例如下面的例子:
$config['db'] = [
'default' => [
/** host */
'db_host' => 'mysql',
/** 数据库用户名 */
'db_user' => 'root',
/** 数据库密码 */
'db_password' => 'root',
/** 端口 */
'db_port' => 3306,
/** 数据库 */
'db_database' => 'yan',
/** 表名前缀 */
'db_prefix' => '',
/**
* mysql/postgres/sqlite/sqlsrv
*/
'db_driver' => 'mysql',
'db_charset' => 'utf8',
'db_collation' => 'utf8_unicode_ci'
],
'mysql1'=>[
'db_host' => '',
'db_user' => '',
'db_password' => '',
'db_port' => 3306,
'db_database' => '',
'db_prefix' => '',
'db_driver' => 'mysql',
'db_charset' => '',
'db_collation' => ''
]
];
这里我们可以对连接进行管理,其中上面的default以及mysql1是我们的连接名称,我们可以根据名称进行数据库连接的切换。
具体可以看Database/DB多连接管理
YAssert
YanPHP内嵌的断言支持。感谢beberlei/assert提供类库支持
入参和Input
用法介绍
所有入参都需要定义在应用目录路径下的Param目录,并且可以对其进行相关的参数校验操作。
下面我们会举例对该功能进行讲解。
例如我们需要请求UserController的index方法,那么我们需要创建一个入参配置文件 Param/UserController.ini
文件内容如下:
[index]
user_id="starts_with[1]|required|numeric|between[1,123]"
page="numeric"
domain="string|numeric"
arr="array"
[getUser]
“=”号左边的是需要的入参,右边的是需要验证的规则。规则都是Validator内置好的,基于Respect/Validation开发
并且只有被定义在入参配置文件中的参数才会被Input类所识别,其余参数一律丢弃。
若参数不符合规则要求,则会直接返回错误信息。
如若你需要为参数配置多个验证规则,可以用 | 进行规则分割,例子:domain="string|length[1,20]"。
在这个例子中,我们要求domain必须是字符串类型,并且长度在1-20个字符之间。
相关入参规则
规则
参数
使用说明
例子
required
否
参数必填
optional
否
参数可空
integer
否
整型
numeric
否
所有字符都是数字(不区分变量类型)
float
否
浮点型
string
否
字符型
array
否
数组型
ip
否
验证是否为一个有效的ip
json
否
验证是否为合法json格式
否
验证是否为合法邮箱
domain
否
验证是否为合法域名
regex
是
正则匹配
regex(/[0-9]+/)
starts_with
是
是否以规定的字符开头
starts_with(ab)
ends_with
是
是否以规定的字符结束
ends_with(ab)
between
是
数值在定义的范围之间
between(1,100)
min
是
定义最小不小于
min(1)
max
是
定义最大不大于
max(100)
length
是
定义字符串长度在定义范围内
length(1,100)
equal
是
入参的值必须等于定义的值
equal(123)
contain
是
入参是否包含给出的值
contain([ab])
获取输入参数
Input::get('user_id'); //获取参数user_id
Input::set('user_id',1); //设置参数
Database
DB方面YanPHP采用了illuminate/Database。
编码设计风格与其保持总体一致。
使用介绍
composer require "illuminate/events" required when you need to use observers with Eloquent.
Once the Capsule instance has been registered. You may use it like so:
Using The Query Builder
$users = Capsule::table('users')->where('votes', '>', 100)->get();
Other core methods may be accessed directly from the Capsule in the same manner as from the DB facade:
$results = Capsule::select('select * from users where id = ?', array(1));
Using The Schema Builder
Capsule::schema()->create('users', function ($table) {
$table->increments('id');
$table->string('email')->unique();
$table->timestamps();
});
Using The Eloquent ORM
class User extends Illuminate\Database\Eloquent\Model {}
$users = User::where('votes', '>', 1)->get();
或者使用YanPHP提供的风格
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class User extends Model
{
protected $table = 'user';
protected $primaryKey = 'uid';
protected $keyType = 'int';
public function getById($id): Collection
{
return $this->where([$this->primaryKey => $id])->get();
}
public function getByCond($cond): Collection
{
return $this->where($cond)->get();
}
public function updateByCond($cond, $update): bool
{
return $this->where($cond)->update($update);
}
public function deleteById($id)
{
return $this->where($id)->delete();
}
}
$UserModel = new User();
$UserModel->getById(1); // 获取user表中uid为1的用户数据信息
For further documentation on using the various database facilities this library provides, consult the Laravel database documentation.
DB多连接管理
在配置文件database.php配置我们的连接后,可以实现多个db连接实例。
下面我们将介绍如何进行连接的切换。
Model/User.php
namespace App\Cgi\Model;
use Illuminate\Support\Collection;
use Yan\Core\Model;
class User extends Model
{
protected $table = 'user';
protected $connection = 'mysql1'; //这里可以配置User Model默认使用"mysql1"连接
public function getById($id): Collection
{
//这里可以使当前实例的连接切换为"default"
$this->setConnection('default');
return $this->where([$this->primaryKey => $id])->get();
}
}
我们可以使用Model当中的$connection配置默认的连接。
另外一种方法是使用自带的$this->setConnection($name)方法进行连接的设置
Session
用法示例
use Yan\Core\Session;
Session::set('a','b'); //设置session值
$sessionVaue = Session::get('a'); //获取session中的值
Session::destroy(); //销毁所有session
Session类中有以下方法
/**
* @method static mixed get($key, $alt = null)
* @method static mixed set($key, $val)
* @method static null clear()
* @method static mixed getFlash($key, $alt = null)
* @method static null setFlash($key, $val)
* @method static null clearFlash()
* @method static mixed getFlashNext($key, $alt = null)
* @method static null setFlashNow($key, $val)
* @method static null clearFlashNow()
* @method static null keepFlash()
* @method boo null destroy()
*/
定制化
定制Result格式
可以到你的应用目录下的Compo/Result.php定制化你的Result格式
下面是Result类的示例:
namespace App\Cgi\Compo;
use Yan\Core\Compo\ResultInterface;
class Result implements ResultInterface
{
protected $code;
protected $message;
protected $data;
public function __construct(int $code, string $message, array $data = [])
{
$this->code = $code;
$this->message = $message;
$this->data = $data;
}
function getCode(): int
{
return $this->code;
}
function getMessage(): string
{
return $this->message;
}
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by json_encode,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
function jsonSerialize()
{
return ['code' => $this->code, 'message' => $this->message, 'data' => $this->data];
}
}
jsonSerialize()返回一个数组,作为结果输出
定制ReturnCode
YanPHP为你定义了一个全局的返回码,返回码的修改可以到System/Yan/Core/ReturnCode.php修改
YanPHP命名规范准则
YanPHP的所有的类文件文件名都 必须 与类名保持一致
框架的命名方式应该遵循驼峰命名法的命名规范。相关介绍可以看这里
控制器
控制器类名需要以驼峰命名法进行命名,并且以Controller作为后缀结束。
例如:UserController、TotalStatisticsController、InfoListController
Model
采用驼峰法,名字可以根据你自己的喜好进行命名。我们会推荐你根据数据库表名或相关的业务用途对model进行命名。
例如:User、Product、Price
入参配置文件(Param/*.ini)
文件名 必须 与你的控制器名称保持一致。每个控制器单独对应一个入参配置文件。
例如:UserController.ini、TotalStatisticsController.ini、InfoListController.ini
安全
重新生成SessionID
Any time a user has a change in privilege (that is, gaining or losing access
rights within a system) be sure to regenerate the session ID:
\Yan\Core\Session::regenerateId();
?>
N.b.: The regenerateId() method also regenerates the CSRF token value.
Cross-Site Request Forgery
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
CSRF防御措施
为了防范Csrf攻击,server端的处理逻辑应该是这样的:
为每一个已经登陆了的用户的每个表单请求放置一个验证token;
确保所有通过 POST/PUT/DELETE (i.e., "unsafe") 的请求都包含上一步骤提到的token值。
N.b.: 如果我们的应用是通过GET请求方法去修改应用资源 (这
是一个错误的做法), 我们同样应该对GET方法的请求
进行CSRF token的验证,以确保用户资源的安全。
例如,我们想要生成一个CSRF token,可以参考以下做法
\Yan\Core\Session::getCsrfToken()->getValue();
当server端接收到一个请求时,我们应该对CSRF token进行以下的处理:
use Yan\Core\Session;
use \Yan\Core\Input;
/**
* @var Vendor\Package\User $user A user-authentication object.
*/
$unsafe = $_SERVER['REQUEST_METHOD'] == 'POST'
|| $_SERVER['REQUEST_METHOD'] == 'PUT'
|| $_SERVER['REQUEST_METHOD'] == 'DELETE';
if ($unsafe && $user->auth->isValid()) {
$csrf_value = Input::get('__csrf_value');
$csrf_token = Session::getCsrfToken();
if (! $csrf_token->isValid($csrf_value)) {
echo "This looks like a cross-site request forgery.";
} else {
echo "This looks like a valid request.";
}
} else {
echo "CSRF attacks only affect unsafe requests by authenticated users.";
}
?>
Nginx
我们需要把每一层应用层作为你的根目录
# 这里是你的Cgi层
server
{
listen 80;
server_name cgi.example.com;
index index.shtml index.html index.htm interface.php;
root root /path/to/root/YanPHP/Application/Cgi/;
location / {
try_files $uri $uri/ =404;
if (!-e $request_filename)
{
rewrite (.*) /interface.php;
}
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
access_log /var/log/YanPHP/access.log;
error_log /var/log/YanPHP/error.log;
}
# 这里是你的Server层
server
{
listen 80;
server_name server.example.com;
index index.shtml index.html index.htm interface.php;
root root /path/to/root/YanPHP/Application/Server/;
location / {
try_files $uri $uri/ =404;
if (!-e $request_filename)
{
rewrite (.*) /interface.php;
}
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
access_log /var/log/YanPHP/access.log;
error_log /var/log/YanPHP/error.log;
}
Apache
如果你需要进行url重写,那么你需要开启 rewrite module。
YanPHP已经为你编写好了 .htaccess 文件,并且存放在每一个应用层的目录下。
DocumentRoot "/path/to/root/YanPHP/Application/Cgi/;"
ServerName cgi.example.com
AddType application/x-httpd-php .php
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
DirectoryIndex interface.php
DocumentRoot "/path/to/root/YanPHP/Application/Server/;"
ServerName server.example.com
AddType application/x-httpd-php .php
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
DirectoryIndex interface.php
Tests
YanPHP编写了相关的测试用例,可以通过运行一下命令进行单元测试,同时也欢迎提交pull request进行测试用例的补充。
phpunit --configuration phpunit.xml
License
MIT
php consult用法,YanPHP: YanPHP——一个为API开发而设计的高性能轻量级框架相关推荐
- API开发接口设计 采用微信accessToken授权方式
⼀.开放接⼝设计说明: 在开发微信授权登入,访问用户信息,就会发现,在微信开发平台调用接口的流程如下: 1. 在开发平台申请到 appid 和 app_secret 2. 通过appid 和 app_ ...
- python实现简单的api接口-用python写一个restful API
# -*- coding: utf-8 -*- # 作者: 煮酒品茶 """ package.module ~~~~~~~~~~~~~~ python实现的图书的一个re ...
- python restful api_用Python语言写一个restful API
本文主要向大家介绍了用Python语言写一个restful API,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. """ package.modul ...
- 使用python的Flask实现一个RESTful API服务器端
使用python的Flask实现一个RESTful API服务器端[翻译] 最近这些年,REST已经成为web services和APIs的标准架构,很多APP的架构基本上是使用RESTful的形式了 ...
- 启动服务错误5拒绝访问_【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器...
启动一个最简单的 RESTful API 服务器 本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本 ...
- 一个简单可参考的API网关架构设计
http://www.infoq.com/cn/articles/api-gateway-architecture-design 网关一词较早出现在网络设备里面,比如两个相互独立的局域网段之间通过路由 ...
- 一个Win32 API实例类(代码收集)
最近看到别人代码中一个很好的功能类,该类是一个Win32 API实例类,该类功能包括:同一程序禁止启动多次:获取任意窗体:恢复窗体状态:设置窗体焦点等. 该类很实用,与大家分享一下: 1 / ...
- 使用PHP创建一个REST API(译)
最近API在网络领域有些风靡,明确的说是REST的影响力.这实在没什么好惊讶的,因为在任何编程语言中,消费REST API都是非常的容易.构建它也非常的简单,因为本质上你不会用到任何那些已存在很久的H ...
- 【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器
本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本小节源码下载路径:demo01 可先下载源码到本地 ...
最新文章
- Angular1.x入门级自定义组件(导航条)
- eclipse插件 --js
- linux学习-----开机启动项设置,ntp服务,防火墙服务,rpm服务,cron服务
- wcf 远程终结点已终止该序列 可靠会话出错
- Create new SAP DDL view and click finish in wizard
- 【每日算法Day 83】邻居小孩一年级就会的乘法表,你会吗?
- 代码管理学:功能实现,一定要与界面分开
- windows批处理脚本导入注册表不弹出确认框
- HTML零基础入门教程完整版
- 计算机桌面工作提醒,有什么好用的电脑桌面日程安排提醒软件?
- java数据流编辑 kylo,Kylo的安装
- STM32 USB Mass Storage 例程调试笔记
- 数据结构之leetcode 347题
- 【SAP消息号M8147】
- Android系统sdcard目录
- 从iOS切换到Android(flyme)
- 一加和小米哪个好 一加用技术领先树立起品牌典范
- Week of 2.7
- 血泪!pyinstaller打包文件过大的解决方法
- tf.layers.flatten()使用