插件开发规范
This content is not available in your language yet.
📏 开发规范
编写高质量、易维护的插件代码
-
✅ 推荐:小写英文 + 下划线
json_format/qr_code/ip_lookup/ -
❌ 避免:
JsonFormat/ # 大驼峰qr-code/ # 中横线JSON_FORMAT/ # 全大写二维码/ # 中文
| 文件类型 | 命名规范 | 示例 |
|---|---|---|
| PHP 类文件 | 大驼峰 | App.php |
| HTML 文件 | 小写 + 下划线 | index.html, config.html |
| CSS 文件 | 小写 + 下划线 | style.css, theme_dark.css |
| JS 文件 | 小写 + 下划线 | main.js, utils.js |
| 图片文件 | 小写 + 下划线 | logo.png, icon_search.png |
<?php// ✅ 正确:大驼峰,与文件名一致namespace plugin\dev\json_format;
class App extends Plugin{ // ...}
// ✅ 正确:辅助类class JsonFormatter{ // ...}
// ❌ 错误:小写class app extends plugin{ // ...}<?phpclass App extends Plugin{ // ✅ 正确:小驼峰 public function formatJson() { // ... }
// ✅ 正确:动词开头 public function validateInput() { // ... }
// ❌ 错误:下划线 public function format_json() { // ... }
// ❌ 错误:大驼峰 public function FormatJson() { // ... }}<?php// ✅ 正确:小驼峰$userName = '张三';$jsonData = '{"key": "value"}';$isValid = true;
// ✅ 正确:有意义的名称$inputData = $_POST['data'];$formattedResult = $this->format($inputData);
// ❌ 错误:无意义$a = '张三';$x = '{"key": "value"}';$data1 = $_POST['data'];
// ❌ 错误:匈牙利命名法$strUserName = '张三';$bIsValid = true;<?php// ✅ 正确:全大写 + 下划线const MAX_FILE_SIZE = 1048576;const API_BASE_URL = 'https://api.example.com';const DEFAULT_TIMEOUT = 30;
// ❌ 错误:小写const max_file_size = 1048576;
// ❌ 错误:驼峰const maxFileSize = 1048576;PHP 代码规范
Section titled “PHP 代码规范”<?php/** * JSON 格式化工具 * * 提供 JSON 数据的格式化、压缩、验证功能 * * @author 张三 <zhangsan@example.com> * @version 1.0.0 * @license MIT * @copyright 2024 Toolbox Team */
namespace plugin\dev\json_format;
use app\Plugin;
class App extends Plugin{ // ...}<?phpclass App extends Plugin{ /** * 格式化 JSON 数据 * * 将输入的 JSON 字符串格式化输出,支持缩进和排序 * * @param string $json 输入的 JSON 字符串 * @param bool $sort 是否按键名排序 * @param int $indent 缩进空格数 * @return array 包含格式化结果和状态码 * - code: 0 成功,1 失败 * - data: 格式化后的 JSON 字符串 * - message: 错误信息(失败时) */ public function formatJson($json, $sort = false, $indent = 4) { // ... }}<?phpclass App extends Plugin{ // 使用 4 个空格缩进 public function index() { // 一级缩进 if ($condition) { // 二级缩进 foreach ($items as $item) { // 三级缩进 $result = $this->process($item); } } }}<?php// ✅ 正确:每行不超过 120 个字符$longVariableName = $this->someMethod($param1, $param2, $param3);
// ✅ 正确:长参数换行$result = $this->someMethod( $param1, $param2, $param3, $param4);
// ❌ 错误:行过长$result = $this->someMethod($param1, $param2, $param3, $param4, $param5, $param6, $param7, $param8);HTML 代码规范
Section titled “HTML 代码规范”<!-- ✅ 正确:2 个空格缩进 --><div class="container"> <div class="row"> <div class="col"> <h1>标题</h1> </div> </div></div>
<!-- ❌ 错误:混用空格和 Tab --><div class="container"> <div class="row"> <div class="col"> <h1>标题</h1> </div> </div></div><!-- ✅ 正确:按优先级排序 --><input type="text" name="username" id="username" class="form-control" placeholder="请输入用户名" required>
<!-- 属性顺序:type → name → id → class → 其他属性 → 布尔属性 --><!-- ✅ 正确:双引号 --><div class="container" data-value="test"></div>
<!-- ❌ 错误:单引号 --><div class='container' data-value='test'></div>CSS 代码规范
Section titled “CSS 代码规范”/* ✅ 正确:BEM 命名法 */.block { }.block__element { }.block--modifier { }
/* 示例 */.tool-card { }.tool-card__title { }.tool-card__content { }.tool-card--highlighted { }
/* ❌ 错误:无意义命名 */.a { }.b { }.red { }.big { }/* ✅ 正确:按类型分组 */.tool-card { /* 定位 */ position: relative; z-index: 10;
/* 盒模型 */ display: flex; width: 100%; height: auto; margin: 10px; padding: 20px;
/* 视觉 */ background: #fff; border: 1px solid #ddd; border-radius: 8px;
/* 文字 */ font-size: 14px; color: #333;
/* 其他 */ cursor: pointer; transition: all 0.3s;}JavaScript 代码规范
Section titled “JavaScript 代码规范”// ✅ 正确:使用 const 和 letconst API_URL = 'https://api.example.com';let count = 0;let userName = '张三';
// ❌ 错误:使用 varvar apiUrl = 'https://api.example.com';
// ❌ 错误:重复声明let count = 0;let count = 1;// ✅ 正确:函数表达式const formatJson = (json) => { try { return JSON.stringify(JSON.parse(json), null, 4); } catch (e) { return null; }};
// ✅ 正确:箭头函数(简单场景)const double = x => x * 2;
// ❌ 错误:函数声明(推荐用表达式)function formatJson(json) { // ...}// ✅ 正确:使用模板字符串const message = `你好,${userName}!今天是 ${date}`;
// ❌ 错误:字符串拼接const message = '你好,' + userName + '!今天是 ' + date;<?phpclass App extends Plugin{ public function process() { // ✅ 正确:验证输入 $input = input('post.data');
if (empty($input)) { return json(['code' => 1, 'message' => '输入不能为空']); }
if (strlen($input) > 10000) { return json(['code' => 1, 'message' => '输入内容过长']); }
// 处理数据 $result = $this->processData($input);
return json(['code' => 0, 'data' => $result]); }}<?php// ✅ 正确:输出转义public function index(){ $userInput = '<script>alert("xss")</script>';
return $this->view()->assign([ 'content' => htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8') ]);}SQL 注入防护
Section titled “SQL 注入防护”<?php// ✅ 正确:使用参数绑定$result = Db::name('users') ->where('id', $userId) ->where('status', 1) ->find();
// ✅ 正确:使用查询构造器$result = Db::name('users') ->where('name', 'like', '%' . $keyword . '%') ->select();
// ❌ 错误:直接拼接 SQL$result = Db::query("SELECT * FROM users WHERE id = $userId");文件操作安全
Section titled “文件操作安全”<?php// ✅ 正确:验证文件类型public function upload(){ $file = request()->file('image');
// 验证文件类型 $allowedTypes = ['jpg', 'jpeg', 'png', 'gif']; $ext = strtolower($file->getOriginalExtension());
if (!in_array($ext, $allowedTypes)) { return json(['code' => 1, 'message' => '不支持的文件类型']); }
// 验证文件大小 if ($file->getSize() > 2 * 1024 * 1024) { return json(['code' => 1, 'message' => '文件大小超过限制']); }
// 生成随机文件名 $newName = md5(uniqid()) . '.' . $ext;
// 移动文件 $file->move('./uploads/', $newName);
return json(['code' => 0, 'url' => '/uploads/' . $newName]);}XSS 防护
Section titled “XSS 防护”<!-- ✅ 正确:输出转义 --><div class="content">{$content|htmlspecialchars}</div>
<!-- ✅ 正确:使用 text() 而不是 html() --><script>$('#result').text(userInput);
// ❌ 错误:$('#result').html(userInput);</script>数据库查询优化
Section titled “数据库查询优化”<?php// ✅ 正确:指定字段$result = Db::name('users') ->field('id, name, email') ->where('status', 1) ->select();
// ❌ 错误:查询所有字段$result = Db::name('users')->where('status', 1)->select();
// ✅ 正确:使用索引$result = Db::name('users') ->where('id', $id) // id 是主键,有索引 ->find();
// ✅ 正确:分页查询$result = Db::name('users') ->where('status', 1) ->page($page, 20) ->select();<?php// ✅ 正确:使用缓存public function getConfig(){ $key = 'plugin_config_' . $this->pluginName;
$config = Cache::get($key);
if (empty($config)) { $config = Db::name('plugin_config') ->where('plugin', $this->pluginName) ->column('value', 'key');
Cache::set($key, $config, 3600); }
return $config;}静态资源优化
Section titled “静态资源优化”<!-- ✅ 正确:压缩后的资源 --><script src="/plugin/dev/json_format/static/js/main.min.js"></script>
<!-- ✅ 正确:使用 CDN --><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- ✅ 正确:异步加载 --><script src="/plugin/dev/json_format/static/js/lazy.js" async></script>✅ 推荐做法
Section titled “✅ 推荐做法”-
代码复用
- 提取公共函数
- 使用继承和 trait
- 避免重复代码
-
错误处理
- 使用 try-catch
- 记录错误日志
- 友好的错误提示
-
代码注释
- 复杂逻辑添加注释
- 说明函数用途
- 标注注意事项
-
版本控制
- 使用 Git 管理代码
- 编写清晰的提交信息
- 使用分支管理功能
❌ 避免做法
Section titled “❌ 避免做法”-
代码混乱
- 一个函数做太多事
- 嵌套层级过深
- 魔法数字和字符串
-
安全隐患
- 不验证用户输入
- 直接输出用户数据
- 暴露敏感信息
-
性能问题
- N+1 查询问题
- 大量数据一次性加载
- 不做缓存
📏 规范是代码质量的保证!
接下来学习调试技巧,快速定位问题~