6.6 KiB
6.6 KiB
PHP 代码检查样板和常见问题
目录
- 关键规则:仅检查特定文件
- 常见 PHP 代码检查问题及修复
- 译: 评论位置
- PSR-12 文件头部顺序
- 包含故意违规的模拟类
- 多行条件对齐
- 未使用的闭包参数
- 数组和运算符对齐
- 缩进规则
- 修复 PHP 代码检查问题的工作流程
- 快速命令参考
关键规则:仅对特定文件进行代码检查
切勿对整个代码库运行代码检查。 始终仅对特定文件、已更改的文件或暂存的文件进行代码检查。
# ✅ 正确:仅在分支级别检查已更改的文件
pnpm lint:php:changes
# ✅ 正确:仅检查已暂存的更改文件
pnpm lint:php:changes:staged
# ✅ 正确:检查特定文件
pnpm lint:php -- path/to/file.php
pnpm lint:php:fix -- path/to/file.php
# ❌ 错误:检查整个代码库
pnpm lint:php
pnpm lint:php:fix
常见 PHP 代码检查问题与修复
快速参考表
| 问题 | 错误示例 | 正确示例 |
|---|---|---|
| 译: 评论 | 在 return 前 | 在函数调用前 |
| 文件文档区块 (PSR-12) | 在 declare() 后 |
在 declare() 前 |
| 缩进 | 使用空格 | 仅使用标签 |
| 数组对齐 | 不一致 | 根据上下文对齐 => |
| 等于号对齐 | 不一致 | 匹配周围风格 |
译: 评论位置
译: 评论必须放在翻译函数调用之前,而不是 return 语句之前。
错误 - 评论在 return 前
/* translators: %s: Gateway name. */
return sprintf(
esc_html__( '%s is not supported.', 'woocommerce' ),
'Gateway'
);
正确 - 在翻译函数前添加评论
return sprintf(
/* translators: %s: 网关名称。 */
esc_html__( '%s 不受支持。', 'woocommerce' ),
'Gateway'
);
多个参数
return sprintf(
/* translators: 1: 网关名称, 2: 国家代码。 */
esc_html__( '%1$s 在 %2$s 无法使用。', 'woocommerce' ),
$gateway_name,
$country_code
);
PSR-12 文件顶部顺序
文件文档块必须位于 declare() 语句前,而不是之后。
错误 - 文档块在 declare() 后
<?php
declare( strict_types=1 );
/**
* File docblock
*
* @package WooCommerce
*/
正确 - 在 declare() 前使用文档块
<?php
/**
* 文件文档块
*
* @package WooCommerce
*/
declare( strict_types=1 );
包含故意违规的模拟类
当创建必须匹配外部类名的模拟类时,请使用 phpcs:disable 注释:
if ( ! class_exists( 'WC_Payments_Utils' ) ) {
/**
* 用于测试的模拟类。
*
* phpcs:disable Squiz.Classes.ClassFileName.NoMatch
* phpcs:disable Suin.Classes.PSR4.IncorrectClassName
* phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
*/
class WC_Payments_Utils {
/**
* 模拟实现。
*/
public static function supported_countries() {
return array( 'US', 'GB' );
}
}
}
多行条件对齐
在多行条件中使用制表符进行续行对齐:
// 正确 - 使用制表符进行续行
if ( class_exists( '\WC_Payments_Utils' ) &&
is_callable( '\WC_Payments_Utils::supported_countries' ) ) {
// code
}
// 同样正确 - 与左括号对齐
if ( class_exists( '\WC_Payments_Utils' ) &&
is_callable( '\WC_Payments_Utils::supported_countries' ) ) {
// code
}
未使用的闭包参数
当创建带有签名要求但未使用的参数闭包时,使用 unset() 来避免 PHPCS 错误:
问题
// ❌ 错误 - PHPCS 错误:Generic.CodeAnalysis.UnusedFunctionParameter
'callback' => function ( string $return_url ) {
return array( 'success' => true );
},
解决方案
// ✅ 正确 - 取消设置未使用的参数
'callback' => function ( string $return_url ) {
unset( $return_url ); // 避免参数未使用的 PHPCS 错误。
return array( 'success' => true );
},
多个未使用参数
'callback' => function ( $arg1, $arg2, $arg3 ) {
unset( $arg1, $arg2 ); // 避免参数未使用的 PHPCS 错误。
return $arg3;
},
常见场景
- PHPUnit 测试中的模拟方法回调
- 签名固定的数组/过滤器回调
- 包含未使用参数的接口实现
参考: tests/php/src/Internal/Admin/Settings/PaymentsRestControllerIntegrationTest.php:1647-1655
数组和运算符对齐
数组箭头对齐
在每个数组上下文中一致地对齐 => 箭头:
// 正确 - 箭头已对齐
$options = array(
'gateway_id' => 'stripe',
'enabled' => true,
'country_code' => 'US',
);
// 也正确 - 短数组无需对齐
$small = array(
'id' => 123,
'name' => 'Test',
);
赋值运算符对齐
匹配周围代码风格:
// 当周围代码对齐时,对齐:
$gateway_id = 'stripe';
$enabled = true;
$country_code = 'US';
// 当周围代码不对齐时,不对齐:
$gateway_id = 'stripe';
$enabled = true;
$country_code = 'US';
缩进规则
总是使用制表符进行缩进,从不使用空格。
// ✅ 正确 - 使用制表符缩进
public function process_payment( $order_id ) {
→ $order = wc_get_order( $order_id );
→
→ if ( ! $order ) {
→ → return false;
→ }
→
→ return true;
}
// ❌ 错误 - 使用空格缩进
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) {
return false;
}
return true;
}
修复 PHP 代码检查问题的工作流程
-
对更改的文件运行代码检查:
pnpm lint:php:changes -
自动修复可以修复的问题:
pnpm lint:php:fix -- path/to/file.php -
审查剩余错误 - 需要手动修复的常见问题:
- 译: 评论位置
- 文件文档区块顺序 (PSR-12)
- 未使用的闭包参数 (添加
unset())
-
手动处理剩余问题
-
验证输出是干净的:
pnpm lint:php -- path/to/file.php -
提交
快速命令参考
# 检查更改的文件
pnpm lint:php:changes
# 检查特定文件
pnpm lint:php -- src/Internal/Admin/ClassName.php
# 修复特定文件
pnpm lint:php:fix -- src/Internal/Admin/ClassName.php
# 检查并显示错误详情
vendor/bin/phpcs -s path/to/file.php