视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何写出高质量的PHP代码
2020-11-02 22:07:01 责编:小采
文档


前言

经常会有人问

  • 目录如何设计比较好?
  • 代码如何分布好?
  • 怎么写一个可维护的项目?
  • “烂”项目我也没少写,以下是参考互联网各大佬的文章总结及个人开发经验而来.

    Controller

    Controller顾名思义是控制器,在入门PHP的时候,就知道Controller代表MVC中的C层,MVC本身的概念就代码分离,教你如何如何将业务分开,但面临着业务的不断发展,代码的复杂度也随之提高,功能与功能之间的链接错综复杂,最后你的MVC就变成了下图,所以仅仅依托MVC的设计思想已经无法支撑不断发展的业务。

    现在我们将Controller的任务和能力重新定义,控制器仅仅控制Http Reqeust的请求,这样就符合了SOLID 单一功能原则.

    直接将业务代码写在Controller中,会使得代码及其臃肿,不易于维护和扩展

    <?php
    	namespace AppHttpController;
    
    	class UserController extends Controller{
    
    	public function register(Request $request){	$user = new User();	$user->username = $request->input('username');	$user->password = $request->input('password');	$result = $user->save();	return $result;
    	}
    
    	}复制代码

    这时就应该思考如何分离业务代码,我们引入Service的概念

    Service

    Service本身译为服务

  • 将外部方法,公共方法注入到Service
  • 将Service注入到控制器
  • 像上图这样

    UserController

    <?php
    	namespace AppHttpController;
    
    	class UserController extends Controller{
    
    	public $request;
    	
    	protected $userService;
    	
    	public function __construct(Request $request, UserService $userService)
    	{	$this->request = $request;	
    	$this->userService = $userService;
    	}
    	
    	public function register()
    	{
    	//... validation	return $this->userService->register ($this->request->all());
    	}
    
    	}复制代码

    UserService

    <?php
    	namespace AppService;
    
     class UserService{
     
     public function register($data)
    	{ $username = $data['username']; $password = $data['password']; 
    	$password = encrypt ($password);	
    	$user = new User();	$user->username = $username;	$user->password = $password;	$result = $user->save();	return $result;
    	}
    
     }复制代码

    到现在为止,我们至少将业务与请求彻底分开了。但还是不如人意,如果把所有的业务及CURD全部写在Service中,那只不过是将Controller的臃肿转移到了Service,那Service就没有什么存在意义了。 所以我们需要继续分割Service,将对数据库的R操作出来,因为CUD的操作基本是一贯不变的,而R操作根据业务的复杂度则变的多姿多彩。所以R操作。这个时候我们引用Repository的概念。

    Repository

    我们使用Repository辅助Model,将相关的查询逻辑封装到不同的repository中,方便逻辑代码的维护

  • 符合SOLID的单一原则
  • 符合SOLID的依赖反转
  • UserController

    <?php
    	namespace AppHttpController;
    
    	class UserController extends Controller{
    
    	public $request;
    	
    	protected $userService;
    	
    	public function __construct(Request $request, UserService $userService)
    	{	$this->request = $request;	
    	$this->userService = $userService;
    	}
    	
    	public function getUserInfo()
    	{
    	//... validation	return $this->userService->getUserInfo ($this->request->all());
    	}
    
    	}复制代码

    UserService

    <?php
    	namespace AppService;
    
     class UserService{
     public $userRepository;
     
     public function __construct(UserRepository $userRepository){ $this->userRepository = $userRepository;
     }
     public function getUserInfo()
    	{ return $this->userRepository->getUserInfo($data);
    	}
    
     }复制代码

    UserRepository

    <?php
    	namespace AppRepository;
    
     class UserRepository{
     
     public function getUserInfo($data)
    	{ $userId = $data['user_id']; $result = User::where('id',$userId)->first();	
    	return $result;
    	}
    
     }复制代码

    解决了R的问题,有人就问了,难道因为CUD比较统一简单就可以放在一起了吗?答案是NO,我们引用一个新的名词Action。

    Action

    这是看了@Charlie_Jade的文章才学到的

    每个操作文件,例如CreateUser,DeleteUser,UpdateUser

  • 符合SOLID的单一原则
  • UserController

    <?php
    	namespace AppHttpController;
    
    	class UserController extends Controller{
    
    	public $request;
    	
    	protected $userService;
    	
    	public function __construct(Request $request, UserService $userService)
    	{	$this->request = $request;	
    	$this->userService = $userService;
    	}
    	
     public function register(){
     //... validation return $this->userService->register($this->request->all());
     }
    
    	public function getUserInfo()
    	{	return $this->userService->getUserInfo ($this->request->all());
    	}
    
    	}复制代码

    UserService

    <?php
    	namespace AppService;
    
     class UserService{
     
     public function getUserInfo(UserRepository $userRepository)
    	{ return $this->userRepository->getUserInfo($data);
    	}
    
     public function register(){ $result = (new CreateUser())->execute($this->request->all()); 
     return $result;
     }
    
     }复制代码

    UserRepository

    <?php
    	namespace AppRepository;
    
     class UserRepository{
     
     public function getUserInfo($data)
    	{ $userId = $data['user_id']; $result = User::where('id',$userId)->first();	
    	return $result;
    	}
    
     }复制代码

    CreateUser

    <?php
    
    	namespace AppAction;
    	
    	use AppModelMember;
    	
    	class CreateUser extends CreateUserWallet
    	{
    	public function execute(array $data)
    	{	$models = new Member();	$models->tel = $data['tel'];	$models->password = $data['password'];	$result = $models->save ();	
    	return $result;
    	}
    	}复制代码

    以上代码逻辑见下图

    除模版(V)等HTML,JS等,还需要一些其他的规则,或者说是方式去实现一些代码的解耦合,以下不再提供代码案例。

    Common

    译为公共的,常用的,再部分开发中,你可能需要一些公共的方法(并非公共的类,例如邮件发送等,用他并不合适),比如查询用户余额,查询用户是否注册或者是否在线,生成订单号等。使用Common更要简单。他更像一个公共函数库的样子

    Event

    不关心执行结果时可以选使用,不过Event的Listen也是提供了队列。

    Exception

    不要将你的所有错误提示都使用Return返回,很多时候你的返回未必是你的返回

    致谢

    感谢各位同学看完这篇文章,如果你有新的想法欢迎在评论区讨论.

    推荐教程:《php教程》

    下载本文
    显示全文
    专题