---
url: /docs/5.0/plugin/hook.md
---
# 插件生命周期钩子

> 钩子（Hook）是插件与 CatchAdmin 系统交互的桥梁，让你可以在插件安装、更新、卸载的各个阶段执行自定义逻辑。

## 钩子文件

每个插件根目录下都有一个 `hook.php` 文件，包含一个 `Hook` 类：

```php
<?php

class Hook
{
    public function beforeInstall(array $context): void { }
    
    public function afterInstall(array $context): void { }
    
    public function beforeUpdate(array $context): void { }
    
    public function afterUpdate(array $context): void { }
    
    public function beforeUninstall(array $context): void { }
    
    public function afterUninstall(array $context): void { }
}
```

## 钩子方法一览

| 钩子方法 | 触发时机 | 常见用途 |
|----------|----------|----------|
| `beforeInstall` | 安装前 | 检查安装条件、验证环境依赖 |
| `afterInstall` | 安装后 | 创建菜单、初始化数据、发布配置 |
| `beforeUpdate` | 更新前 | 备份数据、记录旧版本信息 |
| `afterUpdate` | 更新后 | 执行数据迁移、更新缓存 |
| `beforeUninstall` | 卸载前 | 备份用户数据、确认卸载 |
| `afterUninstall` | 卸载后 | 清理菜单、删除相关数据 |

## Context 参数

每个钩子方法都会接收一个 `$context` 数组，包含插件的基本信息：

```php
$context = [
    'name'      => 'test/test',           // 包名
    'version'   => '1.0.0',               // 版本号
    'path'      => 'vendor/.../test',     // 安装路径
    'namespace' => 'Test\Test',           // 根命名空间
];
```

## 常见应用场景

### 1. 安装时自动创建菜单

```php
public function afterInstall(array $context): void
{
    Plugin::createMenus([
        Plugin::createMenu('我的插件', '/my-plugin', $context['namespace'], children: [
            Plugin::createMenu('用户管理', 'users', $context['namespace'],
                controller: 'UserController',
                controllerMethod: 'index',
                type: 2,
                component: Plugin::view('my/plugin', 'users.index')
            )
        ])
    ]);
}
```

### 2. 卸载时清理菜单

```php
public function afterUninstall(array $context): void
{
    // 删除该插件创建的所有菜单
    Permissions::where('module', $context['namespace'])->delete();
}
```

### 3. 安装前检查条件

```php
public function beforeInstall(array $context): void
{
    // 检查 PHP 版本
    if (version_compare(PHP_VERSION, '8.1', '<')) {
        throw new \RuntimeException('此插件需要 PHP 8.1 或更高版本');
    }
    
    // 检查依赖扩展
    if (!extension_loaded('redis')) {
        throw new \RuntimeException('此插件需要 Redis 扩展');
    }
}
```

### 4. 安装后初始化数据

```php
public function afterInstall(array $context): void
{
    // 执行数据库迁移
    Artisan::call('migrate', [
        '--path' => $context['path'] . '/migrations'
    ]);
    
    // 发布配置文件
    Artisan::call('vendor:publish', [
        '--tag' => 'my-plugin-config'
    ]);
    
    // 初始化默认数据
    \DB::table('settings')->insert([
        'key' => 'my_plugin_enabled',
        'value' => 'true'
    ]);
}
```

### 5. 更新前备份数据

```php
public function beforeUpdate(array $context): void
{
    // 备份配置
    $config = config('my-plugin');
    file_put_contents(
        storage_path('backups/my-plugin-config.json'),
        json_encode($config)
    );
}
```

### 6. 卸载前确认并备份

```php
public function beforeUninstall(array $context): void
{
    // 导出用户数据
    $users = \DB::table('my_plugin_users')->get();
    file_put_contents(
        storage_path('backups/my-plugin-users.json'),
        json_encode($users)
    );
}
```

## 注意事项

:::warning ⚠️ 重要提示

1. **钩子中可以使用 Laravel 功能**：包括 Eloquent、Artisan、配置、日志等
2. **beforeInstall 抛出异常可阻止安装**：用于环境检查
3. **afterUninstall 时包文件仍存在**：可以访问插件的静态资源
4. **钩子方法是实例方法**：不是静态方法
   :::

## 下一步

* 了解如何开发完整插件：[插件开发实战](./practice.md)
* 从零开始创建插件：[快速入门](./quickstart.md)
