对 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 协议》,转载必须注明作者和本文链接

小尹你好!
成功细中取,宝贵险中求;细节决定成败,态度决定一切。

xiaoyin199
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!