问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何写出好的 PHP 代码?

发布网友 发布时间:2022-04-06 10:12

我来回答

2个回答

懂视网 时间:2022-04-06 14:33

前言

经常会有人问

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

    Controller

    clipboard.png

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

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

    clipboard.png

    直接将业务代码写在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注入到控制器
  • clipboard.png

    像上图这样

    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的依赖反转
  • clipboard.png

    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的单一原则
  • clipboard.png

    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;
    		}
    	}复制代码

    以上代码逻辑见下图

    clipboard.png

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

    Common

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

    clipboard.png

    Event

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

    Exception

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

    致谢

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

    推荐教程:《php教程》

    热心网友 时间:2022-04-06 11:41

    编写良好的代码是一种艺术。如果一个程序员遵循一些良好的编程习惯,那么他就可以成为一个优秀的程序员。实际上,相对于你写代码的时间,你很可能会花更多的时间在代码维护上;更不用说整个应用程序的维护。建立良好的编码习惯,能够提高像模块化这样的设计因素,你的代码也将更容易理解,因此,维护起来更容易、成本更低。而不良的编码习惯会在代码中存在缺陷,并可能导致代码很难维护。在本文中,我们将探讨一些良好的编程习惯,这将帮助你避免代码中的缺陷。1- 编写模块化代码 良好的PHP代码应该是模块化代码。PHP的面向对象的编程功能是一些特别强大的工具,可以把你的应用程序分解成函数或方法。你应该尽可能多的从你的应用程序的服务器端分开前端的HTML/CSS/JavaScript代码。你也可以在任何PHP框架上遵循MVC(模型-视图-控制器)模式。2- 代码编写规范 良好的PHP代码应该有一套完整的代码编写规范。通过对变量和函数的命名,统一的方法访问数据库和对错误的处理,以及同样的代码缩进方式等来达到编程规范,这样可以使你的代码更具可读性。3- 编写可移植代码 良好的PHP代码应该是可移植的。你可以使用php的现有功能,如魔术引号和短标签。试着了解你的需求,然后通过适应PHP特性来编写代码让代码独立、可移植。4- 编写安全代码 良好的PHP代码应该是安全的。PHP5提供了出色的性能和灵活性。但是安全问题完全在于开发人员。对于一个专业的PHP开发人员来说,深入理解重大安全漏洞是至关重要的,如:跨站点脚本(XSS)、跨站请求伪造(CSRF)、代码注入漏洞、字符编码漏洞。通过使用PHP的特殊功能和函数,如:mysql_real_escape_string等等,你可以编写出安全的代码。6- 避免短标签 把所有用到短标签的替换成完整的PHP标签。7- 使用单引号代替双引号 字符串始终使用单引号代替双引号,以避免PHP搜索字符串内的变量导致的性能下降。8- 转义字符串输出 使用ENT_QUOTES作参数传递给htmlspecialchars函数,以确保单引号(')也转换成HTML实体,这是一个好习惯。9- 使用逗号分隔字符串输出 通过echo语句输出使用逗号(,)分隔的字符串,要比使用字符串连接操作符(.)的性能更好。10- 输出前检查传来的值输出前检查传过来的值$_GET['query']。使用isset或empty函数,可以用来检查变量是否为null值。
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    电脑开机时怎么进入安全模式 广东医学院大一新生宿舍怎么样,是不是都是学校分配,不能自己选择_百度... 2012高考理科 考到545 想知道怎么填志愿 我的分数545可以报广东医学院边d专业?我系广东考生 高考排名。高考报志愿。广东医学院。 今年545分补录广东医学院还有机会吗? 徒步穿什么鞋 夫妻之间感情再不好都不要去互相伤害 平时可以穿登山鞋吗 大学生都爱去哪些网站? 养虾怎么养 蜂蜜和干柠檬水怎么泡 求正确的蜂蜜泡柠檬片的做法~~~ 新买的保鲜盒套装太紧,拔不出来,怎么办呢? 如何写高质量的PHP代码 行政执法局协管 公安协警辅警笔试综合基础知识 谁有“交通行政执法人员业务考试题库4 ”,发给我 ,谢谢 wzf6146@sina.com 2011年福建省行政执法资格考试综合法律知识试题 河南省行政执法人员公共法律知识考试合格线多少分 急,求2010年苏州城管考行政执法的考试试题 网上怎么申请支付宝 怎么弄支付宝账号啊 支付宝怎样注册账号的?是要身份证吗?没有银行卡可以进行正常网购么? 支付宝账号怎么注册?怎么申请支付宝个人账户 笔记本电脑怎么开不了热点了 急急急!笔记本电脑无法开热点了,怎么办? 笔记本开不了热点怎么解决 我的笔记本开不了热点,这该怎么解决? 腾讯时光是腾讯的软件吗?他们客服关于腾讯时光的问题回答吗? 枸杞原浆什么成分能美白? 泡沫箱发豆芽需在箱底打漏洞排水吗?需要盖子盖住吗? 怎么种黑豆芽??? 泡沫箱种菜还要钻眼吗? 昨晚做梦,梦见被两只老虎咬代表什么? 梦见两只大老虎向咬我但没出血后来被两个人给吓着了打老虎 的是针状焦,石墨电极,跟石墨烯有什么关系 梦见两只老虎,我以为它会过来咬我,但是我摸摸它们的头,就很温顺。请问代表什么?本人女。 石墨电极是不是石墨烯 梦见自己老公被两只老虎咬死吃是什么意识 梦见家里厨房进了两只老虎的还和我要吃的 石墨烯电池有什么原理 纽扣电池半电池 锂过量什么意思,石墨电极面积为什么需要和锂片面积一致,且与电极厚度有什么关系 石墨烯电池的原理是什么? 石墨烯电池的电极材料与电池容量的关系 急性非淋巴细胞白血病的介绍 急性非淋巴白血病治愈率有多少?治好后是否有后遗症? 美国买阿迪达斯大椰子,中国码43应该选多大的美国码 羽毛球“三对三”的比赛规则是什么? 急性非淋巴细胞白血病(M4)怎么治疗?我弟妹26岁刚确诊,小侄子刚两岁... 有谁知道羽毛球3打3的换位规则吗?急需