部署与维护
恭喜你完成了PHP项目的开发!现在让我们学习如何将项目部署到服务器,并进行日常维护。本章将详细介绍从开发环境到生产环境的完整流程。
学习目标
完成本章后,你将能够:
- 选择合适的 hosting 服务商
- 配置生产环境的服务器
- 使用 Git 进行版本控制部署
- 实施自动化部署流程
- 监控和维护线上项目
- 处理常见的服务器问题
部署前的准备工作
1. 项目检查清单
在部署之前,让我们确保项目已经准备就绪:
功能完整性检查
## 功能检查清单
### 核心功能
- [ ] 用户注册和登录功能正常
- [ ] 密码重置功能可用
- [ ] 邮件发送功能正常
- [ ] 文件上传功能安全可靠
### 安全检查
- [ ] SQL注入防护已实施
- [ ] XSS攻击防护已开启
- [ ] CSRF保护已配置
- [ ] 密码已正确加密存储
- [ ] 敏感信息已移出代码
### 性能优化
- [ ] 数据库查询已优化
- [ ] 图片文件已压缩
- [ ] 静态资源已合并/压缩
- [ ] 缓存机制已实现
### 配置文件
- [ ] 数据库配置正确
- [ ] 错误报告已关闭(生产环境)
- [ ] 日志记录已启用
- [ ] 时区设置正确
安全配置检查
// config/security.php - 安全配置示例
<?php
return [
// 强制HTTPS
'force_https' => true,
// 安全头设置
'security_headers' => [
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
'X-Content-Type-Options' => 'nosniff',
'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains'
],
// Session安全
'session' => [
'cookie_httponly' => true,
'cookie_secure' => true,
'use_strict_mode' => true,
'gc_maxlifetime' => 1440 // 24分钟
],
// 文件上传限制
'upload' => [
'max_size' => 5 * 1024 * 1024, // 5MB
'allowed_types' => ['jpg', 'jpeg', 'png', 'gif', 'pdf'],
'path' => '/var/www/uploads/'
]
];
2. 代码优化
关闭调试模式
// 环境检测和配置
define('ENVIRONMENT', isset($_SERVER['ENVIRONMENT']) ? $_SERVER['ENVIRONMENT'] : 'development');
if (ENVIRONMENT === 'development') {
error_reporting(E_ALL);
ini_set('display_errors', 1);
define('DEBUG', true);
} else {
error_reporting(0);
ini_set('display_errors', 0);
define('DEBUG', false);
}
// 错误处理函数
function handleError($errno, $errstr, $errfile, $errline) {
if (!DEBUG) {
// 生产环境记录错误到日志
error_log("Error [$errno]: $errstr in $errfile on line $errline");
// 显示友好的错误页面
include __DIR__ . '/views/errors/500.php';
exit();
}
}
set_error_handler('handleError');
优化数据库配置
// config/database.php - 生产环境数据库配置
<?php
return [
'host' => $_ENV['DB_HOST'] ?? 'localhost',
'port' => $_ENV['DB_PORT'] ?? '3306',
'database' => $_ENV['DB_NAME'] ?? 'myapp',
'username' => $_ENV['DB_USER'] ?? 'root',
'password' => $_ENV['DB_PASS'] ?? '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
// 生产环境优化配置
'options' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 防止SQL注入
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
PDO::ATTR_PERSISTENT => true // 使用持久连接
]
];
选择合适的托管方案
1. 共享主机 (Shared Hosting)
适合初学者和小型项目:
优点
- 价格便宜(通常每月 $5-$20)
- 无需服务器管理经验
- 提供控制面板(cPanel/Plesk)
- 技术支持
缺点
- 资源受限
- 性能不稳定
- 自定义配置受限
- 安全性较低
推荐服务商
1. Bluehost
- 价格:$2.75/月起
- 特点:WordPress优化,免费SSL
2. HostGator
- 价格:$2.75/月起
- 特点:无限带宽,45天退款保证
3. SiteGround
- 价格:$3.99/月起
- 特点:优秀的客服,每日备份
2. VPS (Virtual Private Server)
适合中型项目和有一定技术基础的开发者:
优点
- 独立的资源
- 完全的控制权
- 更好的性能
- 可扩展性强
缺点
- 需要技术知识
- 需要自己管理服务器
- 价格较高
推荐VPS提供商
1. DigitalOcean
- 价格:$5/月起
- 特点:简单易用,文档丰富
2. Linode
- 价格:$5/月起
- 特点:高性能,24/7支持
3. Vultr
- 价格:$2.50/月起
- 特点:全球多数据中心
3. 云服务
适合大型项目和高可用性要求:
AWS (Amazon Web Services)
// AWS部署脚本示例
<?php
// deploy-aws.sh
#!/bin/bash
# 1. 安装LAMP栈
sudo apt update
sudo apt install -y apache2 mysql-server php libapache2-mod-php php-mysql
# 2. 配置Apache
sudo a2enmod rewrite
sudo systemctl restart apache2
# 3. 配置MySQL
sudo mysql -e "CREATE DATABASE myapp;"
sudo mysql -e "CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'securepassword';"
sudo mysql -e "GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'localhost';"
# 4. 部署代码
sudo git clone https://github.com/username/myapp.git /var/www/html/
sudo chown -R www-data:www-data /var/www/html/
echo "AWS部署完成!"
服务器环境配置
1. LAMP 环境搭建
安装 Apache
# Ubuntu/Debian
sudo apt update
sudo apt install -y apache2
# 启用必要模块
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
# 配置虚拟主机
sudo nano /etc/apache2/sites-available/myapp.conf
Apache虚拟主机配置:
# /etc/apache2/sites-available/myapp.conf
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/myapp/public
<Directory /var/www/myapp/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# 日志配置
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# 安全头
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
</VirtualHost>
# HTTPS配置
<VirtualHost *:443>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
DocumentRoot /var/www/myapp/public
SSLEngine on
SSLCertificateFile /etc/ssl/certs/yourdomain.crt
SSLCertificateKeyFile /etc/ssl/private/yourdomain.key
# 安全配置
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
</VirtualHost>
启用站点:
sudo a2ensite myapp
sudo a2dissite 000-default
sudo systemctl reload apache2
安装 PHP
# 安装PHP和常用扩展
sudo apt install -y php php-cli php-fpm php-mysql php-curl php-gd \
php-mbstring php-xml php-zip php-intl php-bcmath
# 配置PHP
sudo nano /etc/php/8.0/apache2/php.ini
PHP生产环境配置:
# /etc/php/8.0/apache2/php.ini
; 基本设置
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
; 错误显示
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
; 文件上传
upload_max_filesize = 5M
post_max_size = 6M
max_file_uploads = 20
; Session配置
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
; OPcache优化
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
安装和配置 MySQL
# 安装MySQL
sudo apt install -y mysql-server
# 安全配置
sudo mysql_secure_installation
# 登录MySQL创建数据库
sudo mysql -u root -p
MySQL安全配置:
-- 创建专用数据库用户
CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
-- 导入数据库结构
USE myapp;
SOURCE /path/to/your/database.sql;
2. Nginx + PHP-FPM 配置
安装 Nginx:
sudo apt install -y nginx php-fpm
Nginx配置文件:
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
root /var/www/myapp/public;
index index.php index.html;
# SSL配置
ssl_certificate /etc/ssl/certs/yourdomain.crt;
ssl_certificate_key /etc/ssl/private/yourdomain.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 安全头
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# PHP处理
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS on;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 禁止访问敏感文件
location ~ /\. {
deny all;
}
location ~ /(config|\.env) {
deny all;
}
}
启用配置:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
SSL证书配置
1. 使用 Let's Encrypt (免费)
安装 Certbot:
sudo apt install -y certbot python3-certbot-apache
# 或
sudo apt install -y certbot python3-certbot-nginx
获取并安装证书:
# Apache
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
# Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 自动续期
sudo crontab -e
# 添加:0 12 * * * /usr/bin/certbot renew --quiet
2. 手动配置SSL证书
生成CSR:
# 生成私钥
sudo openssl genrsa -out yourdomain.key 2048
# 生成CSR
sudo openssl req -new -key yourdomain.key -out yourdomain.csr
# 将CSR提交给CA购买证书
安装证书:
# 将证书文件复制到服务器
sudo cp yourdomain.crt /etc/ssl/certs/
sudo cp yourdomain.key /etc/ssl/private/
# 设置权限
sudo chmod 644 /etc/ssl/certs/yourdomain.crt
sudo chmod 600 /etc/ssl/private/yourdomain.key
域名和DNS配置
1. 域名购买与配置
推荐域名注册商
1. Namecheap
- 价格:$8.98/年起
- 特点:免费WHOIS隐私保护
2. GoDaddy
- 价格:$12.99/年起
- 特点:世界最大注册商
3. Cloudflare
- 价格:免费注册
- 特点:集成CDN和DDoS防护
2. DNS记录配置
## 基本DNS记录
@ (A) 服务器IP地址
www (A) 服务器IP地址
mail (A) 邮件服务器IP
* (CNAME) yourdomain.com
## 邮件记录(如果需要)
@ (MX) mail.yourdomain.com (优先级 10)
## 验证记录
@ (TXT) "v=spf1 include:_spf.google.com ~all"
## 安全记录
@ (DMARC) "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"
部署流程
1. 使用 Git 部署
初始化Git仓库:
# 在本地项目目录
git init
git add .
git commit -m "Initial commit"
# 添加远程仓库
git remote add origin https://github.com/username/myapp.git
git push -u origin master
服务器配置:
# 登录服务器
ssh user@yourserver
# 克隆代码
cd /var/www
sudo git clone https://github.com/username/myapp.git
sudo chown -R www-data:www-data myapp
2. 自动化部署脚本
创建部署脚本:
#!/bin/bash
# deploy.sh
# 配置变量
PROJECT_DIR="/var/www/myapp"
BACKUP_DIR="/var/backups/myapp"
BRANCH="main"
COMMIT_HASH=$(git rev-parse HEAD)
echo "开始部署项目..."
# 1. 备份当前版本
if [ -d "$PROJECT_DIR" ]; then
echo "备份当前版本..."
sudo cp -r $PROJECT_DIR $BACKUP_DIR/backup-$(date +%Y%m%d-%H%M%S)
fi
# 2. 拉取最新代码
echo "拉取最新代码..."
cd $PROJECT_DIR
sudo git pull origin $BRANCH
# 3. 安装依赖
if [ -f "composer.json" ]; then
echo "安装PHP依赖..."
sudo composer install --no-dev --optimize-autoloader
fi
# 4. 运行数据库迁移
if [ -f "database/migrate.php" ]; then
echo "运行数据库迁移..."
sudo php database/migrate.php
fi
# 5. 清除缓存
echo "清除缓存..."
sudo rm -rf cache/*
sudo chmod -R 755 cache/
# 6. 设置权限
echo "设置文件权限..."
sudo chown -R www-data:www-data $PROJECT_DIR
sudo find $PROJECT_DIR -type d -exec chmod 755 {} \;
sudo find $PROJECT_DIR -type f -exec chmod 644 {} \;
# 7. 重启服务
echo "重启服务..."
sudo systemctl reload apache2
# 或 sudo systemctl reload nginx
echo "部署完成!Commit: $COMMIT_HASH"
3. 使用 Composer 进行依赖管理
创建 composer.json:
{
"name": "yourname/myapp",
"description": "My PHP Application",
"require": {
"php": ">=7.4",
"phpmailer/phpmailer": "^6.5",
"vlucas/phpdotenv": "^5.4",
"twig/twig": "^3.3"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.6"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"scripts": {
"deploy": [
"composer install --no-dev --optimize-autoloader",
"php -v"
]
}
}
生产环境安装:
# 只安装生产依赖,优化自动加载
composer install --no-dev --optimize-autoloader
# 更新依赖
composer update --no-dev
监控和维护
1. 日志管理
配置日志轮转:
# /etc/logrotate.d/myapp
/var/www/myapp/logs/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 www-data www-data
postrotate
systemctl reload apache2
endscript
}
查看日志:
# Apache访问日志
sudo tail -f /var/log/apache2/access.log
# Apache错误日志
sudo tail -f /var/log/apache2/error.log
# PHP错误日志
sudo tail -f /var/log/php_errors.log
# MySQL日志
sudo tail -f /var/log/mysql/error.log
2. 性能监控
创建监控脚本:
<?php
// monitor.php - 服务器状态监控
class ServerMonitor
{
private $thresholds = [
'cpu_usage' => 80, // CPU使用率阈值
'memory_usage' => 85, // 内存使用率阈值
'disk_usage' => 90, // 磁盘使用率阈值
'load_avg' => 5.0 // 负载平均值
];
public function checkSystem()
{
$checks = [
'cpu' => $this->checkCpuUsage(),
'memory' => $this->checkMemoryUsage(),
'disk' => $this->checkDiskUsage(),
'load' => $this->checkLoadAverage(),
'services' => $this->checkServices()
];
$this->sendAlert($checks);
return $checks;
}
private function checkCpuUsage()
{
$load = sys_getloadavg();
return [
'current' => $load[0],
'threshold' => $this->thresholds['load_avg'],
'status' => $load[0] < $this->thresholds['load_avg'] ? 'OK' : 'CRITICAL'
];
}
private function checkMemoryUsage()
{
$free = shell_exec('free -m');
$lines = explode("\n", $free);
$memory = explode(" ", $lines[1]);
$memory = array_filter($memory);
$memory = array_values($memory);
$total = $memory[1];
$used = $memory[2];
$usage = ($used / $total) * 100;
return [
'current' => round($usage, 2),
'threshold' => $this->thresholds['memory_usage'],
'status' => $usage < $this->thresholds['memory_usage'] ? 'OK' : 'WARNING'
];
}
private function checkDiskUsage()
{
$diskFree = disk_free_space('/');
$diskTotal = disk_total_space('/');
$usage = (($diskTotal - $diskFree) / $diskTotal) * 100;
return [
'current' => round($usage, 2),
'threshold' => $this->thresholds['disk_usage'],
'status' => $usage < $this->thresholds['disk_usage'] ? 'OK' : 'CRITICAL'
];
}
private function checkServices()
{
$services = ['apache2', 'mysql', 'nginx'];
$results = [];
foreach ($services as $service) {
$status = shell_exec("systemctl is-active $service");
$results[$service] = trim($status) === 'active' ? 'OK' : 'DOWN';
}
return $results;
}
private function sendAlert($checks)
{
foreach ($checks as $check => $value) {
if (is_array($value)) {
foreach ($value as $service => $status) {
if ($status === 'CRITICAL' || $status === 'DOWN') {
$this->sendEmail("$check: $service is $status");
}
}
}
}
}
private function sendEmail($message)
{
// 发送告警邮件
mail('admin@yourdomain.com', '服务器监控告警', $message);
}
}
// 运行监控
$monitor = new ServerMonitor();
$results = $monitor->checkSystem();
// 输出JSON格式供API调用
header('Content-Type: application/json');
echo json_encode($results, JSON_PRETTY_PRINT);
3. 自动化任务(Cron Jobs)
设置定时任务:
# 编辑crontab
crontab -e
# 每天凌晨2点备份数据库
0 2 * * * /usr/bin/mysqldump -u appuser -p'password' myapp | gzip > /var/backups/myapp/db-$(date +\%Y\%m\%d).sql.gz
# 每小时检查服务器状态
0 * * * * /usr/bin/php /var/www/myapp/monitor.php >> /var/log/monitor.log 2>&1
# 每天清理临时文件
0 3 * * * /usr/bin/find /tmp -type f -mtime +7 -delete
# 每周重启服务(可选)
0 4 * * 0 /usr/sbin/service apache2 restart
4. 数据库维护
自动备份脚本:
#!/bin/bash
# backup.sh
# 配置
DB_NAME="myapp"
DB_USER="appuser"
DB_PASS="password"
BACKUP_DIR="/var/backups/myapp"
RETENTION_DAYS=30
# 创建备份目录
mkdir -p $BACKUP_DIR
# 生成备份文件名
DATE=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="$BACKUP_DIR/db_backup_$DATE.sql"
# 备份数据库
mysqldump --single-transaction --routines --triggers -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_FILE
# 压缩备份文件
gzip $BACKUP_FILE
# 删除旧备份
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +$RETENTION_DAYS -delete
# 上传到云存储(可选)
# aws s3 cp $BACKUP_FILE.gz s3://your-backup-bucket/
echo "数据库备份完成: $BACKUP_FILE.gz"
安全加固
1. 防火墙配置
使用 UFW (Ubuntu):
# 安装UFW
sudo apt install ufw
# 默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 允许SSH
sudo ufw allow ssh
# 允许HTTP和HTTPS
sudo ufw allow 80
sudo ufw allow 443
# 启用防火墙
sudo ufw enable
# 查看状态
sudo ufw status
2. 防止DDoS攻击
Nginx限制请求率:
# 在nginx.conf的http块中
limit_req_zone $binary_remote_addr zone=limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
# 应用限制
limit_req zone=limit burst=20 nodelay;
limit_conn addr 10;
# 其他配置...
}
3. 文件权限安全
设置正确的文件权限:
#!/bin/bash
# set-permissions.sh
PROJECT_DIR="/var/www/myapp"
# 设置目录权限
find $PROJECT_DIR -type d -exec chmod 755 {} \;
# 设置文件权限
find $PROJECT_DIR -type f -exec chmod 644 {} \;
# 特殊权限设置
chmod 600 $PROJECT_DIR/config/database.php
chmod 600 $PROJECT_DIR/.env
chmod 755 $PROJECT_DIR/storage
chmod 755 $PROJECT_DIR/cache
chmod 755 $PROJECT_DIR/uploads
# 设置所有者
chown -R www-data:www-data $PROJECT_DIR
echo "文件权限设置完成!"
性能优化
1. 数据库优化
创建索引:
-- 为常用查询字段添加索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at);
CREATE INDEX idx_comments_post_id ON comments(post_id);
-- 复合索引
CREATE INDEX idx_posts_status_created ON posts(status, created_at);
-- 分析查询性能
EXPLAIN SELECT * FROM posts WHERE status = 'published' ORDER BY created_at DESC LIMIT 10;
2. 缓存优化
OPcache配置:
; /etc/php/8.0/mods-available/opcache.ini
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.save_comments=1
3. 静态资源优化
Nginx静态资源缓存:
# 缓存图片、CSS、JS等静态文件
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary Accept-Encoding;
}
# 启用Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
故障排除
1. 常见问题诊断
502 Bad Gateway
# 检查PHP-FPM状态
sudo systemctl status php8.0-fpm
# 查看PHP-FPM日志
sudo tail -f /var/log/php8.0-fpm.log
# 重启PHP-FPM
sudo systemctl restart php8.0-fpm
数据库连接错误
<?php
// debug-db.php - 数据库连接测试
try {
$pdo = new PDO(
"mysql:host=localhost;dbname=myapp",
"appuser",
"password"
);
echo "数据库连接成功!";
// 测试查询
$stmt = $pdo->query("SELECT COUNT(*) FROM users");
echo "用户总数:" . $stmt->fetchColumn();
} catch (PDOException $e) {
echo "数据库连接失败:" . $e->getMessage();
// 检查常见问题
if (strpos($e->getMessage(), "Access denied") !== false) {
echo "\n提示:检查用户名和密码";
} elseif (strpos($e->getMessage(), "Unknown database") !== false) {
echo "\n提示:数据库不存在,需要创建";
}
}
文件权限问题
# 检查文件权限
ls -la /var/www/myapp/
# 修复权限
sudo chown -R www-data:www-data /var/www/myapp/
sudo chmod -R 755 /var/www/myapp/
2. 日志分析
创建日志分析脚本:
<?php
// log-analyzer.php - 分析Apache访问日志
class LogAnalyzer
{
private $logFile;
private $analysis = [];
public function __construct($logFile)
{
$this->logFile = $logFile;
}
public function analyze()
{
$lines = file($this->logFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$this->parseLine($line);
}
return $this->generateReport();
}
private function parseLine($line)
{
// Apache log格式: IP - - [date] "method url protocol" status size "referer" "user-agent"
if (preg_match('/^(\S+) \S+ \S+ \[([^\]]+)\] "(\S+) (\S+) \S+" (\d+) (\d+) "([^"]*)" "([^"]*)"/', $line, $matches)) {
$ip = $matches[1];
$date = $matches[2];
$method = $matches[3];
$url = $matches[4];
$status = $matches[5];
$size = $matches[6];
$referer = $matches[7];
$userAgent = $matches[8];
// 统计状态码
$this->analysis['status_codes'][$status] = ($this->analysis['status_codes'][$status] ?? 0) + 1;
// 统计热门页面
$this->analysis['popular_pages'][$url] = ($this->analysis['popular_pages'][$url] ?? 0) + 1;
// 统计IP访问
$this->analysis['ip_visits'][$ip] = ($this->analysis['ip_visits'][$ip] ?? 0) + 1;
// 检测可疑活动
if ($status >= 400) {
$this->analysis['errors'][] = [
'ip' => $ip,
'url' => $url,
'status' => $status,
'time' => $date
];
}
}
}
private function generateReport()
{
// 排序
arsort($this->analysis['popular_pages']);
arsort($this->analysis['ip_visits']);
// 生成报告
$report = [
'total_visits' => array_sum($this->analysis['ip_visits']),
'unique_ips' => count($this->analysis['ip_visits']),
'errors' => count($this->analysis['errors'] ?? []),
'top_pages' => array_slice($this->analysis['popular_pages'], 0, 10),
'top_ips' => array_slice($this->analysis['ip_visits'], 0, 10),
'status_codes' => $this->analysis['status_codes']
];
return $report;
}
}
// 使用示例
$analyzer = new LogAnalyzer('/var/log/apache2/access.log');
$report = $analyzer->analyze();
echo "访问日志分析报告\n";
echo "==================\n";
echo "总访问次数:{$report['total_visits']}\n";
echo "独立IP数:{$report['unique_ips']}\n";
echo "错误数:{$report['errors']}\n\n";
echo "热门页面(Top 10):\n";
foreach ($report['top_pages'] as $page => $count) {
echo " $page: $count 次\n";
}
应急响应
1. 网站被黑处理
应急处理步骤:
#!/bin/bash
# emergency-response.sh
echo "开始应急响应..."
# 1. 立即备份现场
echo "1. 备份当前数据..."
mkdir -p /var/backups/emergency/$(date +%Y%m%d_%H%M%S)
cp -r /var/www/myapp /var/backups/emergency/$(date +%Y%m%d_%H%M%S)/
# 2. 暂停网站访问
echo "2. 暂停网站服务..."
sudo systemctl stop apache2
# 3. 检查最近修改的文件
echo "3. 检查可疑文件..."
find /var/www/myapp -type f -mtime -7 -ls
# 4. 检查可疑PHP文件
echo "4. 搜索可疑PHP代码..."
grep -r "eval\|base64_decode\|shell_exec\|passthru" /var/www/myapp/ --include="*.php"
# 5. 清理缓存
echo "5. 清理缓存..."
rm -rf /var/www/myapp/cache/*
# 6. 重置密码
echo "6. 重置所有密码..."
sudo mysql -e "ALTER USER 'appuser'@'localhost' IDENTIFIED BY 'NewStrongPassword123!';"
echo "应急响应完成!请手动审查代码后恢复服务。"
2. 数据恢复
从备份恢复:
#!/bin/bash
# restore.sh
BACKUP_FILE=$1
DB_NAME="myapp"
DB_USER="appuser"
if [ -z "$BACKUP_FILE" ]; then
echo "用法: ./restore.sh backup_file.sql.gz"
exit 1
fi
echo "开始恢复数据库..."
# 1. 创建当前数据库备份
mysqldump -u$DB_USER -p $DB_NAME > /var/backups/emergency/current_backup.sql
# 2. 恢复数据库
gunzip -c $BACKUP_FILE | mysql -u$DB_USER -p $DB_NAME
# 3. 检查数据完整性
mysql -u$DB_USER -p $DB_NAME -e "SELECT COUNT(*) FROM users;"
echo "数据库恢复完成!"
总结
通过本章的学习,你掌握了:
部署技能
- 选择合适的托管方案
- 配置生产环境服务器
- 使用Git进行代码部署
- 配置SSL证书
- 管理域名和DNS
维护技能
- 监控服务器性能
- 管理日志文件
- 自动化备份
- 性能优化
- 安全加固
应急处理
- 诊断常见问题
- 处理安全事件
- 数据恢复
持续改进
部署不是结束,而是开始。持续改进你的运维技能:
- 学习自动化工具:Ansible, Puppet, Chef
- 掌握容器化:Docker, Kubernetes
- 使用CI/CD:Jenkins, GitLab CI
- 监控和告警:Prometheus, Grafana
- 云服务:AWS, Google Cloud, Azure
记住,一个稳定的生产环境需要持续的关注和维护。不断学习新的技术和最佳实践,让你的PHP应用运行得更稳定、更安全!
恭喜完成所有章节的学习! 你现在已经从一个PHP初成长为具备完整项目开发、部署和维护能力的PHP开发者了!
继续探索PHP的世界,创造更多精彩的应用吧!🎉