Discuz!应用商城(DisMall)Discuz!应用商城(DisMall)

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 958|回复: 2

[杂谈] 【开发指南】X3.5插件适配之LSP(Liskov 替代原则)

[复制链接]

4

主题

28

帖子

55

积分

开发者

Rank: 6Rank: 6Rank: 6

贡献
1 点
金币
19 个
发表于 2021-4-13 18:12:20 | 显示全部楼层 |阅读模式
x3.5新增了插件的审核要求:
自带表类必须兼容 LSP ( Liskov 替代原则 )。如果依赖于主线表,不允许依赖 table 表的兼容性命名。兼容多版本需要自行判定并调用不同名称的方法,或开启不同分支版本维护

很多开发者反应看不懂这句,或者不知道应该如何适配,这里给大家提供一个较为简单的解释和适配方法的指导。

什么是Liskov替代原则:
这里就不用那些术语来解释了,简单的说就是,你所实现的类继承的“基类”能做到的事情,放到你所实现的类里面也必须可以做到。
对插件来说,此处主要指的是你的 source/plugin/你的插件/table/table_xxxxxx.php 这些文件。他们都是在extends discuz_table。

举个例子:
discuz_table里有这样一个方法:
  1. public function insert($data, $return_insert_id = false, $replace = false, $silent = false)
复制代码

那么你所extends的类里如果也定义了一个 insert ,那么首先,上面的代码里所接收的参数,你的实现里也全都得有(顺序一致,数量足够);
并且,传入这些参数,在discuz_table里所能做的事情,你的实现里也必须能做到(即兼容)。

做不到怎么办?
  • 改名,比如改成insert_extend
  • 修改实现,调整输入参数保持兼容


为什么要适配Liskov替代原则?
这是php 8的新要求,不适配的话会导致无法正常使用。而且随着php的不断发展,这些要求只会变得越来越严格,遵守规范才能让应用长久发展。
顺便说一句,虽说x3.4不支持php 8,但开发3.4应用时也建议留意这些规定,方便未来的迁移。

我一个插件好几十张表,改不动啊!有没有简单一点的办法?
如果你想修改实现的话,这个只能手动来搞了。
优点:可以正确识别不需要修改的部分并予以保留,针对性对需要修改的部分做优化

如果你想改名,那还真有办法:批量替换。
优点:快
缺点:即便是兼容的也会被改掉,可能造成不少不必要的改动。

正则在这里提供给大家了,具体是用php转换,还是把正则复制出来扔vscode里都可以的,相信各位开发者这个一定还是会的吧

适用于source/plugin/你的插件/table/table_xxxxxx.php部分的:
  1. preg_replace('/function\s+(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', 'function $1_extend(', '你的内容')
复制代码


适用于其他地方的:
  1. preg_replace('/(C::t\(\'[^\']+\'\)\s*->\s*)(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', '$1$2_extend(', '你的内容')
复制代码


注意:
  • 替换字符串里的_extend可以更换成其他你喜欢的后缀
  • 正则无法保证100%完美替换,建议用Git或者beyond compare等工具会替换前后的内容进行对比,并进行适当的修改,切勿盲目相信本替换工具。
回复

使用道具 举报

4

主题

28

帖子

55

积分

开发者

Rank: 6Rank: 6Rank: 6

贡献
1 点
金币
19 个
 楼主| 发表于 2021-4-13 18:34:55 | 显示全部楼层
提醒:
第二个正则,也就是适用于其他地方的,会同时给调用系统表C::t的地方也加上后缀,这会导致相关代码无法运行。

但开发者并不是不需要关注这些地方,开发者需要到source/class/table里面,找到原来此处写法所对应的方法,看它是否被标记为DISCUZ_DEPRECATED。
如果有,请务必按照方法内实际调用的新方法,对代码进行修改。
回复 支持 反对

使用道具 举报

4

主题

28

帖子

55

积分

开发者

Rank: 6Rank: 6Rank: 6

贡献
1 点
金币
19 个
 楼主| 发表于 2021-4-13 23:55:02 | 显示全部楼层
如果不需要工具修改到系统表以便定位相关修改位置的话,可以在正则里加入#号,即:
  1. preg_replace('/(C::t\(\'#[^\']+\'\)\s*->\s*)(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', '$1$2_extend(', '你的内容')
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz!应用中心 ( 皖ICP备16010102号 )|网站地图star

GMT+8, 2022-5-25 13:54 , Processed in 0.028825 second(s), 9 queries , Yac On.

Powered by Discuz!

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表