本文目录导读:

在PHP项目中,Composer的脚本钩子(Script Hooks)是一个非常强大的功能,它允许你在Composer执行特定操作时自动运行自定义脚本,以下是详细的指南:
脚本钩子类型
安装/更新相关钩子
{
"scripts": {
"pre-install-cmd": "Your\\Class\\Method",
"post-install-cmd": "Your\\Class\\Method",
"pre-update-cmd": "Your\\Class\\Method",
"post-update-cmd": "Your\\Class\\Method",
"pre-install-package": "Your\\Class\\Method",
"post-install-package": "Your\\Class\\Method",
"pre-update-package": "Your\\Class\\Method",
"post-update-package": "Your\\Class\\Method",
"pre-package-install": "Your\\Class\\Method",
"post-package-install": "Your\\Class\\Method"
}
}
包管理钩子
{
"scripts": {
"pre-autoload-dump": "Your\\Class\\Method",
"post-autoload-dump": "Your\\Class\\Method",
"post-root-package-install": "Your\\Class\\Method",
"post-create-project-cmd": "Your\\Class\\Method",
"pre-archive-cmd": "Your\\Class\\Method",
"post-archive-cmd": "Your\\Class\\Method"
}
}
自定义脚本
{
"scripts": {
"dev-server": "php -S localhost:8000 -t public",
"test": "phpunit",
"lint": "phpcs --standard=PSR2 src/",
"fix": "phpcbf --standard=PSR2 src/"
}
}
执行时机
| 钩子名称 | 触发时机 |
|---|---|
pre-install-cmd |
composer install 执行前 |
post-install-cmd |
composer install 执行后 |
pre-update-cmd |
composer update 执行前 |
post-update-cmd |
composer update 执行后 |
pre-autoload-dump |
生成自动加载文件前 |
post-autoload-dump |
生成自动加载文件后 |
pre-package-install |
安装包之前(每个包触发) |
post-package-install |
安装包之后(每个包触发) |
pre-package-update |
更新包之前(每个包触发) |
post-package-update |
更新包之后(每个包触发) |
实际应用示例
基础用法
{
"scripts": {
"post-install-cmd": [
"php artisan migrate",
"php artisan cache:clear"
],
"post-update-cmd": [
"@php artisan optimize",
"@php artisan config:cache"
]
}
}
使用PHP类方法
创建自定义脚本类:
<?php
// src/Composer/Scripts.php
namespace App\Composer;
class Scripts
{
public static function postInstall()
{
// 设置目录权限
$dirs = ['storage', 'bootstrap/cache'];
foreach ($dirs as $dir) {
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}
chmod($dir, 0755);
}
// 创建.env文件
if (!file_exists('.env')) {
copy('.env.example', '.env');
echo ".env file created\n";
}
// 执行特定命令
self::runCommand('php artisan key:generate');
self::runCommand('php artisan migrate --seed');
}
public static function postUpdate()
{
// 清理缓存
self::runCommand('php artisan cache:clear');
self::runCommand('php artisan config:clear');
self::runCommand('php artisan view:clear');
}
private static function runCommand($command)
{
echo "Running: $command\n";
passthru($command);
}
}
在composer.json中引用:
{
"scripts": {
"post-install-cmd": [
"App\\Composer\\Scripts::postInstall"
],
"post-update-cmd": [
"App\\Composer\\Scripts::postUpdate"
]
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
条件执行脚本
{
"scripts": {
"post-update-cmd": [
"@php -r \"if (file_exists('artisan')) { passthru('php artisan migrate --force'); }\"",
"@if [ -f artisan ]; then php artisan optimize; fi"
]
}
}
执行其他Composer命令
{
"scripts": {
"full-install": [
"@composer install --no-dev",
"@composer dump-autoload --optimize",
"@composer run-script post-install"
]
}
}
环境特定脚本
{
"scripts": {
"post-install-cmd": [
"@php -r \"if (getenv('APP_ENV') === 'production') { passthru('php artisan config:cache'); }\"",
"@php artisan storage:link"
]
}
}
脚本中的特殊命令
{
"scripts": {
"test": [
"@phpunit", // 执行phpunit命令
"@php -l src/", // 执行PHP命令
"@composer validate", // 执行composer命令
"@php -r \"echo 'Hello World';\"" // 执行PHP代码
],
"dev": [
"@composer run-script setup-db",
"@php -S localhost:8000"
]
}
}
最佳实践
安全的脚本配置
{
"scripts": {
"post-install-cmd": [
"@php artisan config:cache || true", // 失败继续
"@php artisan route:cache || true"
],
"post-update-cmd": [
"@php artisan migrate --force || exit 1" // 失败停止
]
},
"scripts-descriptions": {
"post-install-cmd": "Post install commands",
"test": "Run PHPUnit tests"
}
}
避免常见错误
- 不要在钩子中执行交互式命令
- 确保脚本在Windows和Linux下都可执行
- 使用
@php前缀代替直接的php命令 - 考虑脚本的执行时间
- 添加错误处理
使用事件机制
{
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"post-autoload-dump": [
"@php artisan package:discover --ansi"
]
}
}
脚本分组
{
"scripts": {
"setup": [
"@php artisan migrate",
"@php artisan db:seed",
"@php artisan key:generate"
],
"setup:dev": [
"@composer run-script setup",
"@php artisan serve"
],
"setup:prod": [
"@php artisan migrate --force",
"@php artisan config:cache",
"@php artisan route:cache"
]
}
}
调试脚本
# 查看所有可用的脚本 composer list # 运行特定脚本 composer run-script post-install-cmd # 显示脚本执行的详细输出 composer run-script test --verbose # 跳过脚本执行 composer install --no-scripts composer update --no-scripts # 只执行特定脚本 composer run-script --help
注意事项
- 版本兼容性:确保Composer版本支持所有使用的钩子
- 执行顺序:多个脚本按数组顺序执行
- 错误处理:一个脚本失败可能中断后续执行
- 性能考虑:避免在钩子中执行耗时操作
- 安全风险:hook可以执行任意命令,确保composer.json不被篡改
通过合理使用Composer脚本钩子,可以自动化项目开发中的重复性任务,提高开发效率。