mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-03 04:08:01 +08:00
commit
920af44fa1
@ -151,7 +151,7 @@ return [
|
||||
|
||||
配置好数据库后,便可以使用 `Hyperf\DbConnection\Db` 进行查询。
|
||||
|
||||
### Select 查询
|
||||
### query查询类(Select、属性为 READS SQL DATA 的存储过程、函数)
|
||||
|
||||
`select` 方法将始终返回一个数组,数组中的每个结果都是一个 `StdClass` 对象
|
||||
|
||||
@ -160,7 +160,7 @@ return [
|
||||
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
$users = Db::select('SELECT * FROM `user` WHERE gender = ?',[1]);
|
||||
$users = Db::select('SELECT * FROM `user` WHERE gender = ?',[1]); // 返回array
|
||||
|
||||
foreach($users as $user){
|
||||
echo $user->name;
|
||||
@ -168,29 +168,21 @@ foreach($users as $user){
|
||||
|
||||
```
|
||||
|
||||
### 运行插入语句
|
||||
### execute执行类(insert、update、delete,属性为 MODIFIES SQL DATA 的存储过程、)
|
||||
|
||||
可以使用 `Db` 的 `insert` 方法来执行 `insert` 语句。与 `select` 一样,该方法将原生 `SQL` 查询作为其第一个参数,并将绑定数据作为第二个参数:
|
||||
`select` 方法将始终返回一个数组,数组中的每个结果都是一个 `StdClass` 对象
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
Db::insert('insert into user (id, name) values (?, ?)', [1, 'Hyperf']);
|
||||
$result = Db::statement(" CALL pro_test(?,'?') ",[1,'your words']); //返回bool CALL pro_test(?,?) 为存储过程,属性为 MODIFIES SQL DATA
|
||||
return $result ; // 执行成功返回1,否则返回 0 ;
|
||||
```
|
||||
|
||||
### 运行更新语句
|
||||
|
||||
`update` 方法用于更新数据库中现有的记录。该方法返回受该语句影响的行数:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Hyperf\DbConnection\Db;
|
||||
|
||||
$affected = Db::update('update user set name = ? where id = ?', ['John', 1]);
|
||||
```
|
||||
|
||||
### 数据库事务
|
||||
### 自动数据库事务
|
||||
|
||||
你可以使用 `Db` 的 `transaction` 方法在数据库事务中运行一组操作。如果事务的闭包 `Closure` 中出现一个异常,事务将会回滚。如果事务闭包 `Closure` 执行成功,事务将自动提交。一旦你使用了 `transaction` , 就不再需要担心手动回滚或提交的问题:
|
||||
|
||||
@ -206,7 +198,7 @@ Db::transaction(function () {
|
||||
|
||||
```
|
||||
|
||||
### 手动使用事务
|
||||
### 手动数据库使用事务
|
||||
|
||||
如果你想要手动开始一个事务,并且对回滚和提交能够完全控制,那么你可以使用 `Db` 的 `beginTransaction`, `commit`, `rollBack`:
|
||||
|
||||
@ -224,3 +216,12 @@ try{
|
||||
}
|
||||
```
|
||||
|
||||
### 原生sql还提供了以下静态函数,供不同的需求调用
|
||||
```sql
|
||||
use Hyperf\Dbconnection\Db;
|
||||
|
||||
Db::insert("sql语句",[参数1,参数2,..]) // 返回:bool
|
||||
Db::update("sql语句",[参数1,参数2,..]) // 返回:int
|
||||
Db::delete("sql语句",[参数1,参数2,..]) // 返回:int
|
||||
```
|
||||
|
||||
|
@ -15,7 +15,8 @@ return [
|
||||
// 这里的 http 对应 config/autoload/server.php 内的 server 所对应的 name 值
|
||||
'http' => [
|
||||
// 这里配置完整的类命名空间地址已完成对该异常处理器的注册
|
||||
\App\ExceptionHandler\FooExceptionHandler::class,
|
||||
\App\Exception\Handler\FooExceptionHandler::class,
|
||||
\App\Exception\Handler\MyExceptionHandler::class,
|
||||
],
|
||||
],
|
||||
];
|
||||
@ -25,23 +26,24 @@ return [
|
||||
|
||||
# 定义异常处理器
|
||||
|
||||
我们可以在任意位置定义一个 `类(Class)` 并基础抽象类 `Hyperf\Framework\ExceptionHandler` 并实现其中的抽象方法,如下:
|
||||
我们可以在任意位置定义一个 `类(Class)` 并继承抽象类 ` Hyperf\ExceptionHandler\ExceptionHandler;` 并实现其中的抽象方法,如下:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace App\ExceptionHandler;
|
||||
namespace App\Exception\Handler;
|
||||
|
||||
use Hyperf\Framework\ExceptionHandler;
|
||||
use Hyperf\ExceptionHandler\ExceptionHandler;
|
||||
use Hyperf\HttpMessage\Stream\SwooleStream;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use App\Exception\CustomException\MyException;
|
||||
use Throwable;
|
||||
|
||||
class FooExceptionHandler extends ExceptionHandler
|
||||
class MyExceptionHandler extends ExceptionHandler
|
||||
{
|
||||
public function handle(Throwable $throwable, ResponseInterface $response)
|
||||
{
|
||||
// 判断传入的异常是否是该处理器希望处理的异常
|
||||
if ($throwable instanceof FooException) {
|
||||
if ($throwable instanceof MyException) {
|
||||
// 传入的异常是我们希望捕获的 FooException,我们格式化为 JSON 格式并输出到用户端
|
||||
$data = json_encode([
|
||||
'code' => $throwable->getCode(),
|
||||
@ -51,7 +53,51 @@ class FooExceptionHandler extends ExceptionHandler
|
||||
}
|
||||
// 传入的异常不是该处理器希望处理的异常,不处理并交由下一个异常处理器处理
|
||||
}
|
||||
|
||||
public function isValid(Throwable $throwable): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# 自定义我的异常类
|
||||
```php
|
||||
<?php
|
||||
namespace App\Exception\CustomException;
|
||||
|
||||
use Throwable;
|
||||
|
||||
class MyException extends \Exception
|
||||
{
|
||||
function __construct(string $message = "", int $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
function fun_custom(){
|
||||
// Tudo something
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# 我们可以在控制器手动抛出异常,就会触发以上异常处理相关代码
|
||||
```php
|
||||
//以下是控制器代码片段
|
||||
use App\Exception\CustomException\MyException;
|
||||
... ...
|
||||
|
||||
public function index()
|
||||
{
|
||||
//假设用户没有提交参数username,我们就触发刚才定义的异常类
|
||||
if($this->request->input('username')){
|
||||
return $this->response->redirect('http://www.baidu.com');
|
||||
}else{
|
||||
throw new MyException('MyExceptions',-1);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果程序没有收到username参数,浏览器收到的结果就是状态码:500,并且收到了json数据(MyExceptionHandler响应的数据)
|
||||
|
||||
```
|
||||
在上面这个例子,我们先假设 `FooException` 是存在的一个异常,以及假设已经完成了该处理器的配置,那么当业务抛出一个没有被捕获处理的异常时,就会根据配置的顺序依次传递,整一个处理流程可以理解为一个管道,若前一个异常处理器存在返回值则不再往后传递,若最后一个配置的异常处理器仍不对该异常进行捕获处理,那么就会交由 Hyperf 的默认异常处理器处理了。
|
@ -152,7 +152,72 @@ class IndexController
|
||||
}
|
||||
}
|
||||
```
|
||||
#### 中间件相关的代码
|
||||
>快捷生成命令:php ./bin/hyperf.php gen:middleware Auth/FooMiddleware
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware\Auth;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Hyperf\HttpServer\Contract\ResponseInterface as resp; // 这里需要手动引入response类,便于向浏览器响应信息
|
||||
|
||||
|
||||
class FooMiddleware implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
protected $request;
|
||||
protected $response;
|
||||
|
||||
public function __construct(ContainerInterface $container,resp $response)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->response = $response;
|
||||
|
||||
/* $this->request = $container->get(RequestInterface::class); // 从容器解析出request对象
|
||||
$this->response = $container->get(ResponseInterface::class); // 从容器解析出response对象*/
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
/*
|
||||
var_dump($request->getQueryParams()); // 获取requests对象中相关的请求参数,便也业务逻辑判断
|
||||
var_dump($request->getServerParams()); // 获取requests对象中相关的请求参数,便也业务逻辑判断
|
||||
*/
|
||||
// 根据具体业务判断逻辑走向,这里假设用户携带的token有效
|
||||
$is_valid_token=true;
|
||||
if($is_valid_token){
|
||||
return $handler->handle($request);
|
||||
}else{
|
||||
/*
|
||||
* 如果不满足条件,那么程序直接从这里向浏览器响应,停止继续向下执行后续代码
|
||||
*/
|
||||
return $this->response->json(
|
||||
array(
|
||||
'code'=>-1,
|
||||
'msg'=>"failed",
|
||||
'data'=>[
|
||||
"error"=>"中间里验证token无效,阻止继续向下执行"
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
中间件的执行顺序为 `BarMiddleware -> FooMiddleware`。
|
||||
|
||||
## 中间件的执行顺序
|
||||
|
58
zh/router.md
58
zh/router.md
@ -63,7 +63,41 @@ Router::addRoute($httpMethod, $uri, $callback);
|
||||
```php
|
||||
use Hyperf\HttpServer\Router\Router;
|
||||
|
||||
Router::addRoute(['get', 'post'], $uri, $callback);
|
||||
Router::addRoute(['GET', 'POST','PUT','DELETE'], $uri, $callback);
|
||||
```
|
||||
|
||||
#### 路由组的定义方式
|
||||
>以Users 表模型为例,定义一个增、删、改、查路由组
|
||||
>Tips:本框架定义的路由参数必须和控制器参数键名保持一致,否则控制器无法接受到相关参数
|
||||
```php
|
||||
Router::addGroup('/user/',function (){
|
||||
//1. 查询,实际访问地址:http://host:por/user/index
|
||||
Router::addRoute(
|
||||
['GET'],
|
||||
'index/',
|
||||
'App\Controller\Api\V1\UserController@index'
|
||||
);
|
||||
//2. 新增
|
||||
Router::addRoute(
|
||||
['POST'],
|
||||
'store',
|
||||
'App\Controller\Api\V1\UserController@store'
|
||||
);
|
||||
|
||||
//3.修改
|
||||
Router::addRoute(
|
||||
['GET'],
|
||||
'update',
|
||||
'App\Controller\Api\V1\UserController@update'
|
||||
);
|
||||
//4.删除
|
||||
Router::addRoute(
|
||||
['POST'],
|
||||
'delete',
|
||||
'App\Controller\Api\V1\UserController@delete'
|
||||
);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### 通过注解定义路由
|
||||
@ -151,6 +185,28 @@ class UserController
|
||||
`server` 表示该路由是定义在哪个 `Server` 之上的,由于 `Hyperf` 支持同时启动多个 `Server`,也就意味着有可能会同时存在多个 `HTTP Server`,则在定义路由是可以通过 `server` 参数来进行区分这个路由是为了哪个 `Server` 定义的,默认为 `http`。
|
||||
|
||||
### 路由参数
|
||||
>Tips: 路由参数的键名必须和控制器函数参数键名一致
|
||||
>定义一个通过关键词参数查询用户数据的路由
|
||||
```php
|
||||
Router::addGroup('/user/',function (){
|
||||
//1. 查询,实际访问地址:http://your domain/user/index
|
||||
Router::addRoute(
|
||||
['GET'],
|
||||
'index/{keywords}',
|
||||
'App\Controller\Api\V1\UserController@index'
|
||||
);
|
||||
});
|
||||
```
|
||||
>以上路由对应的控制器函数参数名必须是keywords
|
||||
```php
|
||||
|
||||
public function index(string $keywords)
|
||||
{
|
||||
var_dump("关键词参数:{$keywords}");
|
||||
return "控制器根据需要返回相关数据";
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### 必填参数
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user