对 Hyperf 做的那些事 1(定义规范)

  1. 作为一个PHPer一直思考PHP怎么做高性能(个人基础比较弱),怎么微服务,之前真不知道,不是概念而是怎么落地,谈概念有用但是不落地有点扯
  2. Swoole没有实际项目用过,swoole相关框架也没了解过也不知道,获取知道了可能对于之前的问题就可能有一些答案了
  3. Hyperf的出现简直就是太及时了,文档清晰,框架灵活等等等,简直不要太好
  4. 虽然Hyperf已经这么好了,但是还是希望把它稍微按着自己喜欢的规范改造一下,这里就把多有对它的改造都定义为自己的开发规范,如果大家觉得有道理可以沿用
  5. 感谢swoole团队(韩老师等……),感谢Hyperf团队(黄老师等……)
  6. 看完文章是否可以点个赞!!!!

工欲善其事,必先利其器,它有个名字HyperfCMS

开整(1)

  1. 定义目录结构

    ├─app                    应用目录
    │  ……                    框架其它目录
    │  ├─Core                核心目录(都在这里面)框架的修改,业务的核心都放在这个目录下处理
    │  │  ├─Facade           服务容器中可用的类提供了一个「静态」接口的类放在这个地方
    │  │  ├─HF               hyperf框架相关修改放于此
    │  │  ├─LogHandler       日志处理
    │  │  ├─Repositories     仓库目录,业务逻辑处理,区分业务模块
    │  │  │  ├─Admin         后台业务
    │  │  │  ├─Home          前台业务
    │  │  │  ├─Api           接口业务
    │  │  ├─Services         服务目录,业务逻辑处理,所有业务模块公用
    │  │  ├─common.php       公共函数文件
    │  │  ├─Response.php     统一响应处理出口
  2. 调用逻辑设计

  1. 控制器—–>仓库—–>服务—–>模型(Model),解释:http请求过来,通过路由找到控制器,控制器找到对应的仓库,仓库找到对应的服务,服务找到对应的模型,注意:为了规范,仓库不可直接操作模型。
  2. 虽然hyperf提供了多种方法注入,但是个人觉的还是比较麻烦,如果引用类过多需要写很多看着没有实际用途的代码。所以进行了修改,隐式注入
  3. 隐式注入需要遵循约定的规范,如下:
  4. Controller需要继承BaseController,且如果用到哪个仓库需要在注释里@property \APP\Core\Repositories\TestRepository $testRepo目的是可以让phpstorm可以函数间跳转。
  5. 控制器调用仓库的变量需要RepoRepository结尾,如:$testRepo
  6. 仓库的命名必须用Repository结尾,如:TestRepository,需要继承BaseRepository,如果用到服务需要@property \APP\Core\Services\TestService $testService目的是可以让phpstorm可以函数间跳转
  7. 仓内调用服务的变量需要Service结尾,如:$testService
  8. 服务的命名必须用Service结尾,如:TestService,需要继承BaseService,如果用到model需要@property \APP\Models\Category $categoryModel, 目的是可以让phpstorm可以函数间跳转。
  9. 服务调用model的变量需要Model结尾,如:$categoryModel
  1. 贴代码

    class BaseController extends AbstractController
    {
         /**
          * __get 
          * 隐式注入仓库类 
          * User:YM 
          * Date:2019/11/21 
          * Time:上午9:27 
          * @param $key
          * @return \Psr\Container\ContainerInterface|void
          */
         public function __get($key)
          {
             if ($key == 'app') {
                 return $this->container;
               } else {
                 $suffix = strstr($key,'Repo');
               if ($suffix && ($suffix == 'Repo' || $suffix == 'Repository')) {
                 $repoName = $suffix == 'Repo' ? $key.'sitory':$key;
                 return $this->getRepositoriesInstance($repoName);
               } else {
                 throw new \RuntimeException("仓库{$key}不存在,书写错误!", StatusCode::ERR_SERVER);
               }
         }
    
         /**
          * getRepositoriesInstance 
          * 获取仓库类实例 
          * User:YM
          * Date:2019/11/21
          * Time:上午10:30
          * @param $key
          * @return mixed
          */
         public function getRepositoriesInstance($key)
         {
             $key = ucfirst($key);
             $module = $this->getModuleName();
           if (!empty($module)) {
                 $module = "{$module}";
           } else {
                 $module = "";
           }
         if ($module) {
             $filename = BASE_PATH."/app/Core/Repositories/{$module}/{$key}.php";
             $classname = "App\\Core\\Repositories\\{$module}\\{$key}";
         } else {
             $filename = BASE_PATH."/app/Core/Repositories/{$key}.php";
             $classname = "App\\Core\\Repositories\\{$key}";
         }
         if (file_exists($filename)) {
              return $this->container->get($classname);
           } else {
             throw new \RuntimeException("仓库{$key}不存在,文件不存在!", StatusCode::ERR_SERVER);
           }
         }
         /**
          * getModuleName 
          * 获取所属模块
          * User:YM 
          * Date:2019/11/21
          * Time:上午9:32 
          * @return string
          */
         private function getModuleName()
         {
             $classname = get_called_class();
           $name = substr($classname, 15);
           $space = explode('\\', $name);
           if(count($space) > 1){
                 return $space[0];
           }else{
                 return '';
           }
         }
    }
    /**
    * IndexController 
    * 类简介
    * @package App\Controller
    * User:YM 
    * Date:2019/11/12 
    * Time:下午5:03 
    * @property \APP\Core\Repositories\TestRepository $testRepo
    */
    class IndexController extends BaseController 
    {
         public function index()
         {
             $this->testRepo->test();
         }
    }
    namespace App\Core\Repositories;
    use Psr\Container\ContainerInterface;
    use Hyperf\Di\Annotation\Inject;
    use App\Constants\StatusCode;
    /**
    * BaseRepository 
    * 仓库基类 
    * @package App\Core\Repositories
    * User:YM
    * Date:2019/11/21
    * Time:下午2:36 
    */
    class BaseRepository
    {
    /**
    * @Inject
    * @var ContainerInterface
    */  
    protected $container;
    
    /**
    * __get
    * 隐式注入服务类 
    * User:YM 
    * Date:2019/11/21
    * Time:上午9:27 
    * @param $key
    * @return \Psr\Container\ContainerInterface|void
    */  
    public function __get($key)
    {
       if ($key == 'app') {
             return $this->container;
       } elseif (substr($key, -7) == 'Service') {
             return $this->getServiceInstance($key);
       } else {
             throw new \RuntimeException("服务{$key}不存在,书写错误!", StatusCode::ERR_SERVER);
       }
    }
    
    /**
    * getServiceInstance 
    * 获取服务类实例 
    * User:YM
    * Date:2019/11/21 
    * Time:上午10:30 
    * @param $key
    * @return mixed
    */  
    public function getServiceInstance($key)
    {
         $key = ucfirst($key);
          $fileName = BASE_PATH."/app/Core/Services/{$key}.php";
         $className = "App\\Core\\Services\\{$key}";
    
       if (file_exists($fileName)) {
                 return $this->container->get($className);
       } else {
                 throw new \RuntimeException("服务{$key}不存在,文件不存在!", StatusCode::ERR_SERVER);
       }
     }
    }
    namespace App\Core\Repositories;
    /**
    * TestRepository
    * 类的介绍
    * @package App\Core\Repositories
    * User:YM
    * Date:2019/11/21
    * Time:上午10:25
    * @property \APP\Core\Services\TestService $testService
    */
    class TestRepository extends BaseRepository
    {
         public function test()
         {
             $tmp = $this->testService->test();
             return $tmp;
         }
    }
    namespace App\Core\Services;
    use Psr\Container\ContainerInterface;
    use Hyperf\Di\Annotation\Inject;
    use App\Constants\StatusCode;
    /**
    * BaseService
    * 服务基类
    * @package App\Core\Services
    * User:YM
    * Date:2019/11/21
    * Time:下午3:21
    */
    class BaseService
    {
     /**
      * @Inject
      * @var ContainerInterface
      */
     protected $container;
    
     /**
      * __get
      * 隐式注入服务类
      * User:YM
      * Date:2019/11/21
      * Time:上午9:27
      * @param $key
      * @return \Psr\Container\ContainerInterface|void
      */
     public function __get($key)
     {
         if ($key == 'app') {
             return $this->container;
         } elseif (substr($key, -5) == 'Model') {
             $key = strstr($key,'Model',true);
             return $this->getModelInstance($key);
         } elseif (substr($key, -7) == 'Service') {
             return $this->getServiceInstance($key);
         } else {
             throw new \RuntimeException("服务/模型{$key}不存在,书写错误!", StatusCode::ERR_SERVER);
         }
     }
    
     /**
      * getModelInstance
      * 获取数据模型类实例
      * User:YM
      * Date:2019/11/21
      * Time:上午10:30
      * @param $key
      * @return mixed
      */
     public function getModelInstance($key)
     {
         $key = ucfirst($key);
         $fileName = BASE_PATH."/app/Models/{$key}.php";
         $className = "App\\Models\\{$key}";
         if (file_exists($fileName)) {
             return $this->container->get($className);
         } else {
             throw new \RuntimeException("服务/模型{$key}不存在,文件不存在!", StatusCode::ERR_SERVER);
         }
     }
    
     /**
      * getServiceInstance
      * 获取服务类实例
      * User:YM
      * Date:2019/11/21
      * Time:上午10:30
      * @param $key
      * @return mixed
      */
     public function getServiceInstance($key)
     {
         $key = ucfirst($key);
         $fileName = BASE_PATH."/app/Services/{$key}.php";
         $className = "App\\Services\\{$key}";
    
         if (file_exists($fileName)) {
             return $this->container->get($className);
         } else {
             throw new \RuntimeException("服务/模型{$key}不存在,文件不存在!", StatusCode::ERR_SERVER);
         }
      }
    }
    namespace App\Core\Services;
    
    

/**

  • TestServices
  • 类的介绍
  • @package App\Services
  • User:YM
  • Date:2019/11/21
  • Time:下午2:46
  • @property \APP\Models\Category $categoryModel
  • /
    class TestService extends BaseService
    {
    public function test()
    {
      $tmp = $this->categoryModel->getList();
      return $tmp;
    }
    }
    
    
本作品采用《CC 协议》,转载必须注明作者和本文链接
小尹你好! 成功细中取,宝贵险中求;细节决定成败,态度决定一切。
本帖由系统于 4个月前 自动加精
xiaoyin199
讨论数量: 2
994914376

phpstrom跳转在方法里面还是无法识别出来

3个月前 评论

controller一把嗦

2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!