PHP 项目预提交钩子

wen PHP项目 2

本文目录导读:

PHP 项目预提交钩子

  1. 基础 PHP 语法检查钩子
  2. 带有代码风格检查的完整钩子
  3. 安装脚本
  4. 配置文件 (.php-cs-fixer.php)
  5. 高级版本(支持多个校验工具)
  6. 安装到项目
  7. 使用说明

我来提供一个完整的 PHP 项目 Git 预提交钩子(pre-commit hook)方案。

基础 PHP 语法检查钩子

#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 运行 PHP 预提交检查..."
# 获取暂存区中的 PHP 文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.php$')
if [ -z "$STAGED_FILES" ]; then
    echo "✓ 没有 PHP 文件需要检查"
    exit 0
fi
# 1. PHP 语法检查
echo "📝 检查 PHP 语法..."
ERRORS=0
for FILE in $STAGED_FILES; do
    if [ -f "$FILE" ]; then
        OUTPUT=$(php -l "$FILE" 2>&1)
        if [ $? -ne 0 ]; then
            echo "❌ 语法错误: $FILE"
            echo "$OUTPUT"
            ERRORS=$((ERRORS + 1))
        fi
    fi
done
if [ $ERRORS -gt 0 ]; then
    echo "❌ 发现 $ERRORS 个语法错误,提交已阻止"
    exit 1
fi
echo "✓ 所有 PHP 文件语法正确"
exit 0

带有代码风格检查的完整钩子

#!/bin/bash
# .git/hooks/pre-commit - 完整版
echo "🚀 开始 PHP 预提交检查..."
# 设置颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 获取暂存区中的 PHP 文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.php$')
if [ -z "$STAGED_FILES" ]; then
    echo -e "${GREEN}✓ 没有 PHP 文件需要检查${NC}"
    exit 0
fi
ERRORS=0
WARNINGS=0
echo "📁 待检查的文件:"
echo "$STAGED_FILES" | sed 's/^/   - /'
# 1. PHP 语法检查
echo -e "\n${YELLOW}[1/3] PHP 语法检查${NC}"
for FILE in $STAGED_FILES; do
    if [ -f "$FILE" ]; then
        OUTPUT=$(php -l "$FILE" 2>&1)
        if [ $? -ne 0 ]; then
            echo -e "${RED}❌ $FILE: ${NC}$OUTPUT"
            ERRORS=$((ERRORS + 1))
        else
            echo -e "${GREEN}✓ $FILE${NC}"
        fi
    else
        echo -e "${YELLOW}⚠ 文件不存在: $FILE${NC}"
    fi
done
# 2. PHP CS Fixer 风格检查(如果安装了)
echo -e "\n${YELLOW}[2/3] 代码风格检查 (PHP CS Fixer)${NC}"
if command -v php-cs-fixer &> /dev/null; then
    for FILE in $STAGED_FILES; do
        if [ -f "$FILE" ]; then
            # 检查模式而非自动修复
            OUTPUT=$(php-cs-fixer fix "$FILE" --dry-run --diff 2>&1)
            if [ $? -ne 0 ]; then
                echo -e "${YELLOW}⚠ 风格问题: $FILE${NC}"
                echo "$OUTPUT" | tail -5
                WARNINGS=$((WARNINGS + 1))
            else
                echo -e "${GREEN}✓ $FILE 风格正确${NC}"
            fi
        fi
    done
else
    echo -e "${YELLOW}⚠ php-cs-fixer 未安装,跳过风格检查${NC}"
fi
# 3. PHPStan 静态分析(可选)
echo -e "\n${YELLOW}[3/3] PHPStan 静态分析${NC}"
if [ -f "vendor/bin/phpstan" ]; then
    # 只分析暂存的文件
    PHPSTAN_OUTPUT=$(vendor/bin/phpstan analyse $STAGED_FILES --no-progress 2>&1)
    if [ $? -ne 0 ]; then
        echo -e "${RED}$PHPSTAN_OUTPUT${NC}"
        ERRORS=$((ERRORS + 1))
    else
        echo -e "${GREEN}✓ PHPStan 分析通过${NC}"
    fi
else
    echo -e "${YELLOW}⚠ PHPStan 未安装,跳过静态分析${NC}"
fi
# 最终结果
echo -e "\n${YELLOW}📊 检查结果总结:${NC}"
if [ $ERRORS -gt 0 ]; then
    echo -e "${RED}❌ $ERRORS 个错误${NC}"
    echo -e "${YELLOW}⚠ $WARNINGS 个警告${NC}"
    echo -e "${RED}🚫 提交被阻止,请先修复错误${NC}"
    exit 1
else
    echo -e "${GREEN}✓ 没有错误,$WARNINGS 个警告${NC}"
    echo -e "${GREEN}✅ 可以提交${NC}"
    exit 0
fi

安装脚本

#!/bin/bash
# install-hooks.sh - 安装钩子脚本
echo "📦 正在安装 Git 预提交钩子..."
# 复制钩子文件
cp pre-commit .git/hooks/pre-commit
# 设置执行权限
chmod +x .git/hooks/pre-commit
# 确保 PHP 相关工具已安装
echo "🔍 检查 PHP 工具..."
if ! command -v php &> /dev/null; then
    echo "❌ PHP 未安装"
    exit 1
else
    echo "✓ PHP $(php --version | head -n 1)"
fi
# 可选工具检查
if ! command -v composer &> /dev/null; then
    echo "⚠ Composer 未安装"
else
    echo "✓ Composer 已安装"
fi
echo "✅ 钩子安装完成!"
echo "您现在可以尝试提交代码来测试钩子"

配置文件 (.php-cs-fixer.php)

<?php
// .php-cs-fixer.php
$finder = PhpCsFixer\Finder::create()
    ->in(__DIR__)
    ->exclude('vendor')
    ->exclude('storage')
    ->exclude('node_modules')
    ->name('*.php')
    ->notName('*.blade.php')
    ->ignoreDotFiles(true)
    ->ignoreVCS(true);
return (new PhpCsFixer\Config())
    ->setRules([
        '@PSR12' => true,
        'array_syntax' => ['syntax' => 'short'],
        'no_unused_imports' => true,
        'ordered_imports' => ['sort_algorithm' => 'alpha'],
        'single_quote' => true,
        'trailing_comma_in_multiline' => true,
        'phpdoc_align' => true,
        'blank_line_before_statement' => true,
        'no_extra_blank_lines' => true,
        'return_type_declaration' => ['space_before' => 'none'],
        'no_whitespace_before_comma_in_array' => true,
        'whitespace_after_comma_in_array' => true,
        'concat_space' => ['spacing' => 'one'],
        'cast_spaces' => true,
        'lowercase_cast' => true,
        'magic_constant_casing' => true,
        'native_function_casing' => true,
        'function_typehint_space' => true,
        'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
        'class_attributes_separation' => ['elements' => ['method' => 'one']],
    ])
    ->setFinder($finder);

高级版本(支持多个校验工具)

#!/bin/bash
# .git/hooks/pre-commit - 高级版本
set -e
echo "🔍 开始全面的 PHP 代码检查..."
# 获取暂存的文件
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.php$')
ERRORS=0
# 检查函数
check_syntax() {
    local file=$1
    if ! php -l "$file" 2>&1; then
        echo "❌ 语法错误: $file"
        return 1
    fi
    return 0
}
check_code_sniffer() {
    local file=$1
    if [ -f "vendor/bin/phpcs" ]; then
        if ! vendor/bin/phpcs "$file" --standard=PSR2 2>&1; then
            echo "❌ PSR2 规范违规: $file"
            return 1
        fi
    else
        echo "⚠ PHPCS 未安装,跳过"
    fi
    return 0
}
# 主检查流程
for FILE in $STAGED_FILES; do
    echo "检查: $FILE"
    # 1. 语法检查
    check_syntax "$FILE" || ERRORS=$((ERRORS + 1))
    # 2. 代码规范检查
    check_code_sniffer "$FILE" || ERRORS=$((ERRORS + 1))
    # 3. 安全检查(可选)
    if [ -f "vendor/bin/phpstan" ]; then
        vendor/bin/phpstan analyse "$FILE" || ERRORS=$((ERRORS + 1))
    fi
done
if [ $ERRORS -gt 0 ]; then
    echo "❌ 发现 $ERRORS 个问题,禁止提交"
    exit 1
fi
echo "✅ 所有检查通过,可以提交!"

安装到项目

# 1. 创建钩子目录
mkdir -p .git/hooks
# 2. 下载或创建钩子脚本
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# ... 脚本内容 ...
EOF
# 3. 设置权限
chmod +x .git/hooks/pre-commit
# 4. 可选:提交钩子到仓库
# 创建 hooks 目录并保存脚本
mkdir -p .githooks
# 然后把钩子脚本放到该目录
# 配置 Git 使用该目录
git config core.hooksPath .githooks

使用说明

  1. 临时跳过钩子(不推荐):

    git commit --no-verify -m "提交信息"
  2. 查看钩子状态

    ls -la .git/hooks/pre-commit
  3. 测试钩子

    # 故意创建一个语法错误
    echo "<?php echo 'test';" >> test.php
    git add test.php
    git commit -m "测试钩子"

这个预提交钩子将帮助你:

  • ✅ 验证 PHP 语法
  • ✅ 检查代码风格规范
  • ✅ 运行静态分析
  • ✅ 防止提交错误代码
  • ✅ 保持代码质量一致性

请根据项目需求选择适当的钩子版本。

抱歉,评论功能暂时关闭!