news 2026/6/2 8:38:16

PHP持续集成与自动化部署流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP持续集成与自动化部署流程

PHP持续集成与自动化部署流程

持续集成和自动化部署是现代软件开发的标准实践。每次代码提交后自动运行测试、代码检查、构建和部署。今天说说PHP项目的CI/CD流程搭建。

一个完整的CI/CD流程包括代码检查、测试、构建和部署几个阶段。用GitHub Actions可以轻松实现。

```yaml
# .github/workflows/deploy.yml
name: CI/CD Pipeline

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, pdo_mysql, redis, gd
tools: composer, phpstan, phpcs

- run: composer install --prefer-dist --no-progress

- name: 代码规范检查
run: phpcs src --standard=PSR12 --extensions=php

- name: 静态分析
run: phpstan analyse src --level=8 --no-progress

- name: 单元测试
run: vendor/bin/phpunit --coverage-clover=coverage.xml

- name: 上传覆盖率
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml

build:
needs: quality
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: 构建Docker镜像
run: |
docker build -t app:latest .
docker tag app:latest registry.example.com/app:${{ github.sha }}

- name: 推送到镜像仓库
run: |
docker push registry.example.com/app:${{ github.sha }}

deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: SSH部署
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
script: |
cd /var/www/app
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
sudo supervisorctl restart all
echo "部署完成"
```

PHP代码中的部署状态检查:

```php
class DeploymentStatus
{
private string $deployDir;

public function __construct(string $deployDir = __DIR__)
{
$this->deployDir = rtrim($deployDir, '/');
}

public function getCurrentRelease(): string
{
$releaseFile = $this->deployDir . '/RELEASE_VERSION';
if (file_exists($releaseFile)) {
return trim(file_get_contents($releaseFile));
}
return 'unknown';
}

public function getDeployTime(): string
{
$deployFile = $this->deployDir . '/DEPLOY_TIME';
if (file_exists($deployFile)) {
return trim(file_get_contents($deployFile));
}
return 'unknown';
}

public function getGitCommit(): string
{
$gitDir = $this->deployDir . '/.git';
if (is_dir($gitDir)) {
$headFile = $gitDir . '/HEAD';
if (file_exists($headFile)) {
$head = trim(file_get_contents($headFile));
if (str_starts_with($head, 'ref: ')) {
$refPath = $gitDir . '/' . substr($head, 5);
if (file_exists($refPath)) {
return trim(file_get_contents($refPath));
}
}
}
}
return 'unknown';
}

public function getDeployLog(): array
{
$logFile = $this->deployDir . '/storage/logs/deploy.log';
if (!file_exists($logFile)) return [];

$lines = file($logFile);
$entries = [];

foreach (array_slice($lines, -50) as $line) {
$entry = json_decode(trim($line), true);
if ($entry) {
$entries[] = $entry;
}
}

return $entries;
}

public function healthCheck(): array
{
$checks = [
'app_version' => $this->getCurrentRelease(),
'git_commit' => $this->getGitCommit(),
'deploy_time' => $this->getDeployTime(),
'php_version' => PHP_VERSION,
'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . 'MB',
'disk_free' => round(disk_free_space('/') / 1024 / 1024 / 1024, 2) . 'GB',
];

return $checks;
}
}

class DeployLogger
{
public static function log(string $stage, string $status, string $message): void
{
$entry = [
'time' => date('Y-m-d H:i:s'),
'stage' => $stage,
'status' => $status,
'message' => $message,
'user' => get_current_user(),
];

$logDir = __DIR__ . '/storage/logs';
if (!is_dir($logDir)) mkdir($logDir, 0755, true);

file_put_contents(
$logDir . '/deploy.log',
json_encode($entry, JSON_UNESCAPED_UNICODE) . "\n",
FILE_APPEND | LOCK_EX
);
}
}

$status = new DeploymentStatus();
print_r($status->healthCheck());
?>
```

零停机部署的实现。常见的方式有蓝绿部署和金丝雀部署。PHP应用由于是无状态的(PHP-FPM模式),实现平滑部署相对简单。只需先启动新版本实例,再切换流量,最后关闭旧版本即可。

自动化部署脚本示例:

```bash
#!/bin/bash
# deploy.sh

set -e

echo "开始部署..."
DEPLOY_DIR="/var/www/app"
RELEASE_DIR="/var/www/releases/$(date +%Y%m%d%H%M%S)"

# 拉取代码
echo "拉取代码..."
git clone -b main git@github.com:org/app.git $RELEASE_DIR

# 安装依赖
echo "安装依赖..."
cd $RELEASE_DIR
composer install --no-dev --optimize-autoloader

# 创建存储链接
ln -nfs $DEPLOY_DIR/storage $RELEASE_DIR/storage
ln -nfs $DEPLOY_DIR/.env $RELEASE_DIR/.env

# 设置权限
chmod -R 775 $RELEASE_DIR/storage
chmod -R 775 $RELEASE_DIR/bootstrap/cache

# 运行迁移
php artisan migrate --force

# 切换版本
ln -nfs $RELEASE_DIR $DEPLOY_DIR/current

# 重启PHP-FPM
sudo service php8.2-fpm reload

# 清理旧版本
ls -t /var/www/releases | tail -n +6 | xargs -I {} rm -rf /var/www/releases/{}

echo "部署完成"
```

CI/CD流程让代码从提交到上线变得自动化、标准化。每次部署都可追溯,出了问题也能快速回滚。虽然搭建CI/CD需要一些前期投入,但长期来看能极大提升团队的交付效率和代码质量。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 8:38:00

早期初创公司如何选择AI营销助手:从需求分析到选型落地指南

1. 项目概述:为什么早期初创公司需要AI营销助手?在早期创业阶段,你和我一样,每天都在和时间、预算、人力这三座大山搏斗。营销,这个听起来就“烧钱”的活儿,往往是创始人最头疼但又绕不开的环节。没钱请一个…

作者头像 李华
网站建设 2026/6/2 8:37:57

OpenCASCADE 7.8.0编译踩坑实录:CMake配置项详解与第三方库避坑指南

OpenCASCADE 7.8.0编译实战:CMake关键配置解析与疑难解决方案在三维建模与CAD开发领域,OpenCASCADE(简称OCCT)作为开源的几何内核引擎,其强大的B-rep建模和可视化能力吸引了大量工程师。然而,当7.8.0版本取…

作者头像 李华
网站建设 2026/6/2 8:35:54

眼科医生的‘新手术刀’:达芬奇FEMTO LDV Z8飞秒激光在角膜移植与白内障手术中的实战应用与参数设置心得

眼科医生的‘新手术刀’:达芬奇FEMTO LDV Z8飞秒激光在角膜移植与白内障手术中的实战应用与参数设置心得作为一名在屈光手术领域深耕十余年的眼科医生,第一次接触达芬奇FEMTO LDV Z8飞秒激光系统时的震撼感至今难忘。这台被誉为"眼科手术革命性工具…

作者头像 李华