安装
安装swoole扩展:wget https://github.com/swoole/swoole-src/archive/v4.5.0.tar.gz
phpize
./configure --with-php-config=/www/server/php/72/bin/php-config --enable-http2 --enable-openssl
make
make install
php --ri swoole
通过 Composer 创建项目:composer create-project hyperf/hyperf-skeleton
启动:php bin/hyperf.php start
访问:curl http://127.0.0.1:9501/
ab压测:ab -k -c 100 -n 10000 http://127.0.0.1:9501/
路由
config/routes.php
<?php
declare(strict_types=1);
use Hyperf\HttpServer\Router\Router;
Router::addRoute(['GET', 'POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
//[root@VM_0_13_centos hyperf-skeleton]# curl 127.0.0.1:9501/
<?php
declare(strict_types=1);
use Hyperf\HttpServer\Router\Router;
Router::addRoute(['POST', 'HEAD'], '/', 'App\Controller\IndexController@index');
//curl 127.0.0.1:9501/ -w %{http_code}
//Allow: POST, HEAD405
//curl 127.0.0.1:9501/ -w %{http_code} -X POST
//{"method":"POST","message":"Hello Hyperf."}200
<?php
declare(strict_types=1);
use Hyperf\HttpServer\Router\Router;
Router::post('/', 'App\Controller\IndexController@index');
注解
路由定义,可通过注解形式配置路由,@Controller,需要搭配@RequestMapping,@GetMapping,@PostMapping,@PutMapping等注解一起使用
//curl 127.0.0.1:9501/index/index -w %{http_code} -X POST
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
*/
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
//curl 127.0.0.1:9501/user/index -w %{http_code} -X POST
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController(prefix="user")
*/
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
//curl 127.0.0.1:9501/user/index/index -w %{http_code} -X POST
<?php
declare(strict_types=1);
namespace App\Controller\User;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
*/
class IndexController extends AbstractController
{
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
<?php
//curl 127.0.0.1:9501/index/index -w %{http_code} -X POST
declare(strict_types=1);
namespace App\Controller\User;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
/**
* @Controller(prefix="index")
*/
class IndexController extends AbstractController
{
/**
* @RequestMapping(path="index",methods={"get","post"})
*/
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
<?php
//curl 127.0.0.1:9501/overwrite -w %{http_code} -X POST
declare(strict_types=1);
namespace App\Controller\User;
use App\Controller\AbstractController;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\RequestMapping;
/**
* @Controller(prefix="index")
*/
class IndexController extends AbstractController
{
/**
* @RequestMapping(path="/overwrite",methods={"get","post"})
*/
public function index()
{
$user = $this->request->input('user', 'Hyperf');
$method = $this->request->getMethod();
return [
'method' => $method,
'message' => "Hello {$user}.",
];
}
}
Ioc与DI
Ioc,即控制反转,把对象的调用权交给容器,通过容器来实现对象的装配和管理。
DI,即依赖注入,对象之间依赖关系由容器在运行期决定,由容器动态将依赖关系注入到队形之中。
DI是对Ioc更完善的描述。
对注解和DI的总结
1、PHP语法上没有支持注解,只能基于约束号的规定去从注释上解析
2、注解只是元数据定义,实现功能时不利用这些数据的话没有任何作用
3、使用了注解的对象基于Hyperf的DI容器来创建对象才能生效
4、注解可以用在类,类方法,类成员属性上
5、DI容器是负责管理对象的创建和对象的依赖管理的
6、DI容器创建出来的对象是个单例,是长生命周期对象
7、通过$container->make()方法或make()函数创建短生命周期对象
8、通过new来实例化的对象注解不会生效,依赖需要自行管理
自定义注解
app/Annotation/Foo.php
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"CLASS","METHOD"})
*/
class Foo extends AbstractAnnotation
{
/**
* @var string
*/
public $bar;
}
app/Controller/User/IndexController.php
<?php
declare(strict_types=1);
namespace App\Controller\User;
use App\Annotation\Foo;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
* @Foo("123ka==")
*/
class IndexController
{
public function index()
{
$res =AnnotationCollector::getClassByAnnotation(Foo::class);
return json_encode($res);
}
}
AOP
AOP是什么?
面向切面编程,通过预编译方式或运行期动态代理实现程序功能的统一维护的一种技术。
AOP在字面上与OOP很相似,但设计思想在目标上有着本质的差异
OOP是针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。
而AOP则是针对业务处理过程中的切面进行提取,它所面对是处理过程中的某个步骤或阶段,以获得逻辑过程
中各部分之间低耦合性的隔离效果。
每个方法的前后
Hyperf里的AOP
只需理解一个概念即可,即Aspect(切面)
Aspect可以切入任意类或任意注解类
被切入的类必须由DI管理
相对于其他框架实现的AOP功能的使用方式,我们进一步简化了AOP的使用
不做过细的划分(如Before,After,AfterReturning,AfterThrowing),仅存在
环绕(Around)一种通用的形式。
Hyperf的AOP是基于DI实现的
必须使用的是Hyperf的DI组件,即hyperf/di
必须通过DI创建的对象才能使AOP生效,直接new不行
必须当代理类缓存文件不存在时才会重新生成代理类。
AOP的应用场景
参数校验、日志、无侵入埋点,安全控制,性能统计,事务处理,异常处理,缓存,
无侵入监控,资源池,连接池管理等
基于AOP的功能
@Cacheable
@CachePut
@CacheEvict
@Task
@RateLimit
@CircuitBreaker
调用链追踪的无侵入埋点
app/Aspect/IndexAspect.php
<?php
namespace App\Aspect;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use App\Controller\User\IndexController;
/**
* @Aspect()
*/
class IndexAspect extends AbstractAspect
{
public $classes = [
IndexController::class .'::'.'index',
];
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
//var_dump(__CLASS__);
$result = $proceedingJoinPoint->process();
return 'before=='.$result.'==after';
}
}
app/Controller/User/IndexController.php
<?php
declare(strict_types=1);
namespace App\Controller\User;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
*/
class IndexController
{
public function index()
{
return 2;
}
}