PHP/JAVA 杂谈 一(php 槽点)

【本文为个人意见,不喜就喷吧!】

最近,同事问到我,『那时候为什么从PHP转成Java?』,我想了很久,且撇开主观上的原因,当初业务重构使用java确实有很多可以说道的地方。

槽点1:哪有最好的语言,只有最合适的语言

2017年的3月份,我所维护的业务,跑的是php,使用的是thinkphp3.2 框架。刚接手的时候,这个业务还是单机,还记得有同事笑道:『这台机厉害哈,单机一年能跑出200多万的流水来!』我当然是一笑置之。可是随着业务组扩展外部渠道,开始发展这个业务,我慢慢发现这样子的系统很难搞:难维护,难扩展,难自定义,不稳定。这样子的系统,每次改到支付功能,上线都是心虚的,就怕突然出现问题,影响用户体验。于是在一段煎熬的思索和过渡后,老大开始带着我进行重构。最开始的一套方案,是准备放弃原有的tp 框架,转而使用 yii2,但由于人手不够,老大亲自操刀,架起了一套 play1.4.3(业务端) + spring-mvc(后台管理) 的一套系统,所以,我也转到了java。

我这里想说的是,一个项目选择啥语言,需要考虑团队的配置,不能上来就搞一套不切实际的东西,从实际出发,找到适合自己的语言。曾几何时,我也觉得php是世界上最好的语言,还没有之一,现在只觉得哪有最好的语言,只有最合适的语言。

......

槽点2:面向对象编程,而不是面向数组编程

也许你一定很想知道,如何才能完成从php 到 java 的转身呢?

说实话,一开始的时候,确实很痛苦,基础薄弱就不说了,精神上还有压力,因为全世界都知道【你是写java的 php程序员】。举个特别糗的例子,刚刚写spring-mvc 的时候,不知道如何接收10多个参数,于是我很活该的使用了map, 我当时想啊,这不就是我们php 的 $_GET 和 $_POST 么【想当然害死人呀!】。可是写着写着我就发现不妥了,首先,别人并不知道你的map里面有啥子参数;然后,从map取出来的值不一定有值,如果是null,还要做逻辑判断,这样子代码又麻烦了。所以呀,虽然这个代码顺利上线了,也没发生过大的故障,但是我一直把这份代码当成我的【眼中钉,肉中刺】。后面我是知道了,其实用一个对象来接收这些参数,既优雅,有便于维护,可读性也好。

下面,我把自己最恨的一段代码贴出来,告诫小伙伴们,【别这样子干啊】

   // 控制器 
  @RequestMapping(value = "/list", method = RequestMethod.GET)
@ResponseBody
public AjaxResponse getOrderList(@RequestParam Map<String, String> searchMap) {
return orderService.getListsData(searchMap);
}

  

 // 恶心的逻辑
  /**
* 解析搜索关键词, 组装matches
*
* @param matches
* @param searchKey
* @param searchVal
* @return
*/
public Matches getMatchesBySearchMapEntry(Matches matches, String searchKey, String searchVal) {
switch (searchKey) { case Properties.tradeType:
if (Integer.parseInt(searchVal) > 0) {
matches.eq(Columns.tradeType, searchVal);
}
break;
case Properties.state:
int state = Integer.parseInt(searchVal);
if (state == 4) {
matches.match("complete_status", 1); // 表示已完成
} else if (state == 3) {
matches.match("order_status", 0); // 0 表示已下单
} else if (state == 1) {
matches.match("order_status", 1); // 1 表示已支付
} else if (state == 2) {
matches.match("order_status", 2); // 2 表示已退款
}
break;
case Properties.channelId: List<Long> belongIds = accountService.getChannelIdBelongThisUser(HttpSessionUtils.getUseAccountId());
if (belongIds == null) {
if (GeneralUtil.isObjNotZero(searchVal)) {
matches.match("channel_id", searchVal);
}
} else if (belongIds.size() > 0) {
Long id = Long.parseLong(searchVal);
if (belongIds.contains(id)) {
matches.match("channel_id", id);
} else {
matches.match("channel_id", belongIds);
}
}
break;
case Properties.cepingId:
if (GeneralUtil.isObjNotZero(searchVal)) { List<Long> cepingIds = scalePoolDao.findIdsByParentId(Long.parseLong(searchVal));
matches.match("ceping_id", cepingIds); }
break;
case Properties.orderNo:
matches.match("order_no", searchVal);
break;
case Properties.openId:
String userKey = userDao.getUserKeyByOpenidAndUserType(searchVal, 1);
matches.match("user_key", userKey);
break;
case Properties.userKey:
matches.match("user_key", searchVal);
break;
case Properties.createStartTime: // 下单时间
Date createStartTime = DateTimeHelper.timeFormatStringToDate(searchVal);
matches.gte("create_time", createStartTime);
break;
case Properties.createEndTime:
Date createEndTime = DateTimeHelper.timeFormatStringToDate(searchVal);
matches.lte("create_time", createEndTime);
break;
case Properties.payStartTime: // 支付时间
Date payStartTime = DateTimeHelper.timeFormatStringToDate(searchVal);
matches.gte("pay_time", payStartTime);
break;
case Properties.payEndTime:
Date payEndTime = DateTimeHelper.timeFormatStringToDate(searchVal);
matches.lte("pay_time", payEndTime);
break;
case Properties.userType:
int userType = Integer.parseInt(searchVal);
if (userType > 0) {
matches.eq(Columns.userType, searchVal);
}
break;
case Properties.buyType:
int buyType = Integer.valueOf(searchVal);
if (buyType > 0) {
if (buyType == BuyType.DEFAULT_COPY_ORDER.getCode()) {
buyType = 0;
}
matches.eq(Columns.buyType, buyType);
} break; }
return matches;
}

  

我现在用又臭又长来形容,这样子的code 既不方便阅读,出问题了也不好排查。而且这个代码,我还是放在个循环中来拼接的,可读性之烂可想而知。唉,要是我如果有时间了,就把这段代码改了。

其实呢,说了这么多,我就想说,包括我在内的部分 phper额,太过分依赖数组了。是啊,在php里面,没有啥是一个数组搞不定的,如果有,那就俩个。我走心看了下其它业务线的php代码,哎哟喂,好家伙。推送服务配置用数组,微信公众号配置用数组,接受请求用数组,传参用数组(个人最不喜欢的方式),好像数组少些,项目就不能正常运行了。

我并不是说不该用数组,但是数组确实不好维护。当我们思绪乱的时候,你根本记不清这个数组中有哪些参数,你也可能想不起这个return的对象有哪些对象,特别是return json的时候,如果一个数组不存在,这时候返回了null,这样子返回的接口数据,对客户端的同学来说就是一种灾难。

槽点3:一包不扫,何以扫天下

除此之外,也是我最想吐槽的一点,就是php的命名空间和包管理。虽然php现在也有了composer,但是部分包载入时,还是需要做一下手动处理的,如果是一些小白的话,那久很尴尬了。相对于php呢,java就很成熟了,maven 一出,问题基本就解决了。而php的命名空间呢,我最不爽的一点是,明明一个包没关联上,项目居然还若无其事的走着,之前没觉得咋样,写java后就觉得,这样子特别不严谨,对于我这样的强迫症者来说,不能接受!

PHP/JAVA 杂谈 一(php 槽点)

还有就是,需要手动载入 扩展,关于这点,php做的不够好

PHP/JAVA 杂谈 一(php 槽点)

槽点4:定时任务 

此外呢,php有一点做的不够好的,定时任务!(且不说用swoole做定时任务哈,毕竟swoole还是需要点学习成本的呢!)

之前我很少用php做定时任务,如果要做的话,就要依赖linux系统crontab,或者用swoole 了。

但是在java里面,完全不是这样子的体验,在play 或者 spring-mvc ,完全就是一个job 就搞定了,哪里要这般麻烦!

槽点 5:必不可少的单元测试

然后呢,php 在单元测试方面比java 差挺多的。这里我不否认有idea 的功能,但是想要用phpunit 测试一个方法,我感觉千难万难,但是在java里,很容易就实现了!除此之外,包括我在内的部分phper,很少写单元测试,甚至有些压根就不知道这是咋回事!我觉得这是个可怕的现象,这样子的代码,连自己这关都没过,如何敢上线,如何能稳呢!基本上走过单元测试的代码,基本不存在啥语法错误,这就是妥妥的保障啊!

PHP/JAVA 杂谈 一(php 槽点)

槽点6:你debug都不用,就不要假装在搬砖了

接下来, 包括我在内的部分phper 呢,很少去debug,有些甚至从来没这么搞过。在那段维护 thinkphp的时间了,我开始使用phpstrom的debug,说实话,代码质量,开发效率都有很大的提升!我实在不能再接受自己用 echo, var_dump 这样子去调试代码,这样子会让人觉得,这是个门外汉呢!

槽点7:php是世界上最好的语言

请放下这个想法,你会发现,无论是python,golang,java 都不比咱php差,你不知,只因你未接触!

槽点8:php代码打包功能弱

在写java前呢,每次遇到要复用的php代码呢,我都是直接copy,但是写java 一段时间后,我就觉得java 这方面比较好了,我可以通过maven 对共用的包进行打包,放到另一个项目中去,这样子既方便管理,又利于版本的迭代,省时省力!

好了,就到这里吧,接下来还会有一篇吐槽java的。

上一篇:Vue一个案例引发「内容分发slot」的最全总结


下一篇:创建 Spring容器的三种方式