蓝科迪梦-一个分享学习的网站-迪梦网络科技工作室学习分享网 - 蓝科迪梦
type: channel
link: http://bv87.top/author/1/
description: 蓝科迪梦
items: API文档自动生成与维护
items: PHP开发中的缓存穿透、击穿与雪崩防护解决方案
items: 文件上传安全性与大文件处理
items: PHP中的异步处理与消息队列集成
items: PHP中Composer依赖冲突与版本管理
items: PHP开发中：Session共享与分布式部署
items: PHP开发中数据库事务死锁与并发控制
items: PHP开发中API接口限流与并发控制
items: PHP循环依赖与依赖注入解决方案
items: PHP开发中的内存泄漏与性能优化实战解决方案

API文档自动生成与维护
type: item
date: 2025-10-16T10:48:00+08:00
description: PHP开发中的复杂问题及解决方案：API文档自动生成与维护在PHP项目开发中，API文档的维护是一个常见且耗时的问题。随着项目迭代，API接口不断变化，手工维护文档容易出现不同步、不完整等问题，影响开发效率和团队协作。常见的API文档问题1. 文档与代码不同步// 代码已更新，但文档忘记更新 /** * @deprecated 使用新的getUserProfile替代 */ class OldUserController { public function getUserInfo($id) { // 实现... } }2. 文档格式不统一// 不同开发者编写的文档风格不一致 /** * 获取用户信息 * 参数: $id 用户ID * 返回: 用户数据 */ function getUser($id) { } /** * Get user details * @param int $userId The user identifier * @return array User information */ function getUserDetails($userId) { }解决方案方案一：基于注解的API文档生成<?php /** * OpenAPI/Swagger注解定义 */ namespace App\Annotations; /** * @Annotation * @Target({"METHOD"}) */ class ApiOperation { /** @var string */ public $summary; /** @var string */ public $description; /** @var string */ public $tags = []; } /** * @Annotation * @Target({"METHOD"}) */ class ApiResponse { /** @var int */ public $code; /** @var string */ public $description; /** @var string */ public $schema; } /** * @Annotation * @Target({"METHOD"}) */ class ApiParameter { /** @var string */ public $name; /** @var string */ public $in; // path, query, body, header /** @var string */ public $description; /** @var bool */ public $required = false; /** @var string */ public $type; }<?php /** * 用户控制器 - API文档示例 */ class UserController { /** * @ApiOperation( * summary="获取用户信息", * description="根据用户ID获取详细的用户信息", * tags={"Users"} * ) * @ApiParameter( * name="id", * in="path", * description="用户ID", * required=true, * type="integer" * ) * @ApiResponse( * code=200, * description="成功返回用户信息", * schema="User" * ) * @ApiResponse( * code=404, * description="用户不存在" * ) */ public function getUser($id) { // 实现逻辑 return [ 'id' => $id, 'name' => 'John Doe', 'email' => 'john@example.com' ]; } /** * @ApiOperation( * summary="创建新用户", * description="创建一个新的用户账户", * tags={"Users"} * ) * @ApiParameter( * name="user", * in="body", * description="用户信息", * required=true, * type="UserCreateRequest" * ) * @ApiResponse( * code=201, * description="用户创建成功", * schema="User" * ) * @ApiResponse( * code…

PHP开发中的缓存穿透、击穿与雪崩防护解决方案
type: item
date: 2025-10-15T10:48:00+08:00
description: PHP开发中的复杂问题及解决方案：缓存穿透、击穿与雪崩防护在高并发的PHP应用中，缓存系统的三个经典问题——缓存穿透、缓存击穿和缓存雪崩——是影响系统稳定性的关键因素。这些问题可能导致数据库压力骤增，甚至系统崩溃。三大缓存问题解析1. 缓存穿透查询不存在的数据，请求直接打到数据库，缓存形同虚设。2. 缓存击穿热点数据过期瞬间，大量请求同时查询数据库。3. 缓存雪崩大量缓存同时过期，数据库面临瞬时高压。解决方案方案一：布隆过滤器防止缓存穿透<?php /** * 布隆过滤器实现 */ class BloomFilter { private array $bitArray; private int $size; private array $hashFunctions; public function __construct(int $size = 1000000) { $this->size = $size; $this->bitArray = array_fill(0, $size, 0); $this->hashFunctions = [ [$this, 'hash1'], [$this, 'hash2'], [$this, 'hash3'] ]; } /** * 添加元素到布隆过滤器 */ public function add(string $item): void { foreach ($this->hashFunctions as $hashFunc) { $index = $hashFunc($item) % $this->size; $this->bitArray[$index] = 1; } } /** * 检查元素是否存在 */ public function mightContain(string $item): bool { foreach ($this->hashFunctions as $hashFunc) { $index = $hashFunc($item) % $this->size; if ($this->bitArray[$index] === 0) { return false; } } return true; } private function hash1(string $item): int { return crc32($item); } private function hash2(string $item): int { return abs(crc32(strrev($item))); } private function hash3(string $item): int { return abs(crc32($item . strrev($item))); } } /** * 防止缓存穿透的服务层 */ class CachePenetrationProtection { private \Redis $redis; private BloomFilter $bloomFilter; public function __construct(\Redis $redis) { $this->redis = $redis; $this->bloomFilter = new BloomFilter(); $this->initializeBloomFilter(); } /** * 初始化布隆过滤器（从持久化存储加载） */ private function initializeBloomFilter(): void { $existingKeys = $this->redis->smembers('valid_keys'); foreach ($existingKeys as $key) { $this->bloomFilter->add($key); } } /** * 安全获取数据 */ public function getDataSafely(string $key) { // 布隆过滤器快速检查 if (!$this->bloomFilter->mightContain($key)) { // 肯定不存在，直接返回空值并缓存 $this->cacheEmptyResult($key); return null; } // 缓存中查找 $cachedData = $this->redis->get($key); if ($cachedData !== false) { return $cachedData === 'NULL_VALUE' ? null : json_decode($cachedData, true); } // 数据库查询 $data = $this-…

文件上传安全性与大文件处理
type: item
date: 2025-10-14T10:56:00+08:00
description: PHP开发中的复杂问题及解决方案：文件上传安全性与大文件处理在PHP Web应用开发中，文件上传功能既是核心需求也是安全隐患最多的环节之一。不当的文件上传处理可能导致恶意文件上传、服务器资源耗尽、目录遍历攻击等问题。常见的安全风险1. 恶意文件上传// 危险示例：未验证文件类型直接保存 if (isset($_FILES['upload'])) { move_uploaded_file($_FILES['upload']['tmp_name'], 'uploads/' . $_FILES['upload']['name']); }2. 大文件导致的资源耗尽// 上传超大文件可能导致内存溢出或磁盘空间不足解决方案方案一：安全的文件上传验证<?php /** * 安全文件上传处理器 */ class SecureFileUpload { private array $allowedMimeTypes; private array $allowedExtensions; private int $maxFileSize; private string $uploadDirectory; public function __construct( array $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'], array $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'], int $maxFileSize = 5242880, // 5MB string $uploadDirectory = 'uploads/' ) { $this->allowedMimeTypes = $allowedMimeTypes; $this->allowedExtensions = $allowedExtensions; $this->maxFileSize = $maxFileSize; $this->uploadDirectory = rtrim($uploadDirectory, '/') . '/'; // 确保上传目录存在且安全 $this->ensureUploadDirectory(); } /** * 处理文件上传 */ public function handleUpload(array $file): array { try { // 1. 基础验证 $this->validateUploadError($file); // 2. 文件大小验证 $this->validateFileSize($file); // 3. 文件类型验证 $this->validateFileType($file); // 4. 安全命名 $safeFilename = $this->generateSafeFilename($file); // 5. 移动文件 $uploadPath = $this->uploadDirectory . $safeFilename; if (!move_uploaded_file($file['tmp_name'], $uploadPath)) { throw new Exception('Failed to move uploaded file'); } // 6. 文件完整性验证 $this->validateFileIntegrity($uploadPath, $file['type']); return [ 'success' => true, 'filename' => $safeFilename, 'path' => $uploadPath, 'size' => filesize($uploadPath), 'mime_type' => mime_content_type($uploadPath) ]; } catch (Exception $e) { return [ 'success' => false, 'error' => $e->getMessage() ]; } } /** * 验证上传错误 */ private function validateUploadError(array $file): void { if (!isset($file['error']) || is_array($file['error'])) { throw new Exception('Invalid file upload'); } switch ($file['error']) { case UPLOAD_ERR_OK: return; case UPLOAD_ERR_INI_SIZE: ca…

PHP中的异步处理与消息队列集成
type: item
date: 2025-10-13T10:48:00+08:00
description: PHP开发中的复杂问题及解决方案：异步处理与消息队列集成在现代PHP应用开发中，异步处理和消息队列集成是提升系统性能和用户体验的重要技术。当面对耗时操作时，同步处理会导致用户等待，影响系统响应速度。常见的异步处理场景1. 邮件发送阻塞// 用户注册后需要发送欢迎邮件，但SMTP连接慢导致页面响应延迟 class UserController { public function register() { // 用户注册逻辑 $this->createUser($userData); // 同步发送邮件，阻塞用户响应 $this->sendWelcomeEmail($userEmail); return response()->json(['status' => 'success']); } }2. 文件处理耗时// 图片上传后需要进行复杂的图像处理操作 class ImageController { public function upload() { // 上传文件 $file = $this->uploadFile(); // 同步处理图片，耗时长 $this->processImage($file); return response()->json(['url' => $processedImageUrl]); } }解决方案方案一：基于Redis的消息队列实现<?php /** * Redis消息队列处理器 */ class RedisMessageQueue { private \Redis $redis; private string $queueName; public function __construct(\Redis $redis, string $queueName = 'default') { $this->redis = $redis; $this->queueName = $queueName; } /** * 发布消息到队列 */ public function publish(array $message): bool { $message['created_at'] = time(); $message['id'] = uniqid(); return $this->redis->lpush($this->queueName, json_encode($message)) > 0; } /** * 从队列消费消息 */ public function consume(int $timeout = 0): ?array { $message = $this->redis->brpop($this->queueName, $timeout); if ($message === false) { return null; } return json_decode($message[1], true); } /** * 获取队列长度 */ public function length(): int { return $this->redis->llen($this->queueName); } /** * 延迟消息发布 */ public function publishDelayed(array $message, int $delaySeconds): bool { $executeAt = time() + $delaySeconds; $delayedQueue = "{$this->queueName}:delayed"; $message['execute_at'] = $executeAt; return $this->redis->zadd($delayedQueue, $executeAt, json_encode($message)) > 0; } /** * 处理延迟消息 */ public function processDelayedMessages(): int { $delayedQueue = "{$this->queueName}:delayed"; $now = time(); $messages = $this->redis->zrangebyscore($delayedQueue, 0, $now); $processed = 0; foreach ($messages as $messageJson) { $message = json_decode($messageJson, true); if ($this->publish($message)) { $this->redis->zrem($delayedQueue, $messageJson); $pro…

PHP中Composer依赖冲突与版本管理
type: item
date: 2025-10-11T10:48:00+08:00
description: PHP开发中的复杂问题及解决方案：Composer依赖冲突与版本管理在PHP项目开发中，Composer依赖冲突是一个常见且令人头疼的问题。当项目依赖的包存在版本冲突时，会导致安装失败或运行时错误。常见的依赖冲突场景1. 直接依赖版本冲突{ "require": { "monolog/monolog": "^1.0", "some/package": "^2.0" } }其中 some/package 需要 monolog/monolog ^2.0，与直接声明的版本冲突。2. 间接依赖版本不兼容# composer install 时出现类似错误 Your requirements could not be resolved to an installable set of packages.解决方案方案一：依赖版本分析与解决<?php /** * Composer依赖冲突分析工具 */ class DependencyConflictAnalyzer { private string $composerJsonPath; private array $installedPackages; public function __construct(string $composerJsonPath = 'composer.json') { $this->composerJsonPath = $composerJsonPath; $this->loadInstalledPackages(); } /** * 加载已安装的包信息 */ private function loadInstalledPackages(): void { if (file_exists('vendor/composer/installed.json')) { $content = file_get_contents('vendor/composer/installed.json'); $this->installedPackages = json_decode($content, true)['packages'] ?? []; } } /** * 分析依赖冲突 */ public function analyzeConflicts(): array { $conflicts = []; $requirements = $this->getProjectRequirements(); $dependencyTree = $this->buildDependencyTree(); foreach ($requirements as $package => $versionConstraint) { $conflictingDeps = $this->findConflictingDependencies( $package, $versionConstraint, $dependencyTree ); if (!empty($conflictingDeps)) { $conflicts[$package] = [ 'required_version' => $versionConstraint, 'conflicts_with' => $conflictingDeps ]; } } return $conflicts; } /** * 获取项目直接依赖 */ private function getProjectRequirements(): array { if (!file_exists($this->composerJsonPath)) { return []; } $composerJson = json_decode(file_get_contents($this->composerJsonPath), true); return array_merge( $composerJson['require'] ?? [], $composerJson['require-dev'] ?? [] ); } /** * 构建依赖树 */ private function buildDependencyTree(): array { $tree = []; foreach ($this->installedPackages as $package) { $packageName = $package['name']; $tree[$packageName] = [ 'version' => $package['version'], 'requires' => $package['require'] ?? [], 'dev_requires' => $packag…

PHP开发中：Session共享与分布式部署
type: item
date: 2025-10-10T10:48:00+08:00
description: PHP开发中的复杂问题及解决方案：Session共享与分布式部署在分布式PHP应用部署中，session共享是一个常见且复杂的问题。当应用部署在多台服务器上时，用户的session数据可能存储在不同的服务器上，导致用户状态不一致。问题场景分析1. 负载均衡下的Session丢失// 用户登录后跳转到不同服务器，Session数据无法共享 session_start(); $_SESSION['user_id'] = 123; // 用户下次请求可能被分配到另一台服务器，Session丢失2. 多服务器Session不一致// 服务器A和服务器B各自维护独立的Session存储 // 用户在A服务器登录，在B服务器无法识别登录状态解决方案方案一：Redis Session存储/** * 基于Redis的Session处理器 */ class RedisSessionHandler implements SessionHandlerInterface { private Redis $redis; private int $ttl; public function __construct(Redis $redis, int $ttl = 1440) { $this->redis = $redis; $this->ttl = $ttl; } /** * 打开Session */ public function open(string $savePath, string $sessionName): bool { return true; } /** * 关闭Session */ public function close(): bool { return true; } /** * 读取Session数据 */ public function read(string $id): string { $data = $this->redis->get("sessions:{$id}"); return $data ?: ''; } /** * 写入Session数据 */ public function write(string $id, string $data): bool { return $this->redis->setex("sessions:{$id}", $this->ttl, $data); } /** * 销毁Session */ public function destroy(string $id): bool { return $this->redis->del("sessions:{$id}") > 0; } /** * 垃圾回收 */ public function gc(int $maxlifetime): int { // Redis会自动过期，这里返回0表示无需清理 return 0; } } // 配置使用Redis Session $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $handler = new RedisSessionHandler($redis); session_set_save_handler($handler, true); session_start();方案二：数据库Session存储/** * 基于MySQL的Session处理器 */ class DatabaseSessionHandler implements SessionHandlerInterface { private PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } public function open(string $savePath, string $sessionName): bool { return true; } public function close(): bool { return true; } public function read(string $id): string { $stmt = $this->pdo->prepare(" SELECT session_data FROM sessions WHERE session_id = ? AND expires_at > NOW() "); $stmt->execute([$id]); $result = $stmt->fetch(PDO::FETCH_ASSOC); return $result ? $result['session_data'] : ''; } …

PHP开发中数据库事务死锁与并发控制
type: item
date: 2025-10-08T10:40:00+08:00
description: PHP开发中的复杂问题及解决方案：数据库事务死锁与并发控制在复杂的Web应用中，数据库事务死锁是一个常见且难以调试的问题。当多个事务同时竞争相同的资源时，可能会导致系统性能下降甚至完全阻塞。死锁产生的原因1. 交叉锁定资源// 事务A: 先更新用户表，再更新订单表 // 事务B: 先更新订单表，再更新用户表 // 这种情况下容易产生死锁2. 不一致的访问顺序class OrderService { public function updateOrderAndUser($orderId, $userId) { // 不同的操作顺序可能导致死锁 $this->updateOrder($orderId); $this->updateUser($userId); } }解决方案方案一：统一资源访问顺序/** * 死锁预防 - 统一资源访问顺序 */ class DeadlockPreventionService { private PDO $db; public function __construct(PDO $db) { $this->db = $db; } /** * 按照固定顺序访问资源 */ public function updateUserAndOrder($userId, $orderId, $userData, $orderData) { // 始终按照ID大小顺序访问资源 $resources = [ ['type' => 'user', 'id' => $userId], ['type' => 'order', 'id' => $orderId] ]; // 按ID排序确保访问顺序一致 usort($resources, function($a, $b) { return $a['id'] <=> $b['id']; }); try { $this->db->beginTransaction(); foreach ($resources as $resource) { if ($resource['type'] === 'user') { $this->updateUserRecord($resource['id'], $userData); } elseif ($resource['type'] === 'order') { $this->updateOrderRecord($resource['id'], $orderData); } } $this->db->commit(); return true; } catch (Exception $e) { $this->db->rollback(); throw $e; } } private function updateUserRecord($userId, $userData) { $stmt = $this->db->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?"); $stmt->execute([$userData['name'], $userData['email'], $userId]); } private function updateOrderRecord($orderId, $orderData) { $stmt = $this->db->prepare("UPDATE orders SET status = ?, amount = ? WHERE id = ?"); $stmt->execute([$orderData['status'], $orderData['amount'], $orderId]); } }方案二：重试机制处理死锁/** * 死锁自动重试机制 */ class DeadlockRetryHandler { private PDO $db; private int $maxRetries; private int $baseDelayMs; public function __construct(PDO $db, int $maxRetries = 3, int $baseDelayMs = 100) { $this->db = $db; $this->maxRetries = $maxRetries; $this->baseDelayMs = $baseDelayMs; } /** * 执行带死锁重试的数据库操作 */ public function executeWithRetry(callable $operation) { $attempt = 0; while ($attempt < $this->maxRetries) { try…

PHP开发中API接口限流与并发控制
type: item
date: 2025-10-08T10:40:00+08:00
description: PHP开发中的复杂问题及解决方案在高并发的Web应用中，API接口的限流和并发控制是保证系统稳定性的关键问题。当大量请求同时涌入时，如果没有适当的保护机制，很容易导致系统崩溃或响应缓慢。常见的并发问题场景1. 接口被恶意刷取// 用户反馈：某个API接口被频繁调用，导致服务器负载过高 class ApiController { public function getData() { // 复杂的数据处理逻辑 $result = $this->heavyDatabaseQuery(); return json_encode($result); } }2. 秒杀活动中的超卖问题class OrderController { public function createOrder($productId, $quantity) { $product = ProductModel::find($productId); if ($product->stock >= $quantity) { // 可能在高并发下出现超卖 $product->stock -= $quantity; $product->save(); return ['status' => 'success']; } return ['status' => 'failed']; } }解决方案方案一：基于Redis的令牌桶算法/** * 令牌桶限流器 */ class TokenBucketRateLimiter { private Redis $redis; private string $key; private int $capacity; // 桶容量 private int $rate; // 令牌生成速率(每秒) public function __construct(Redis $redis, string $key, int $capacity, int $rate) { $this->redis = $redis; $this->key = $key; $this->capacity = $capacity; $this->rate = $rate; } /** * 尝试获取令牌 */ public function acquire(int $tokens = 1): bool { $now = microtime(true); $key = "rate_limiter:{$this->key}"; // 使用Lua脚本保证原子性 $script = ' local key = KEYS[1] local capacity = tonumber(ARGV[1]) local rate = tonumber(ARGV[2]) local tokens = tonumber(ARGV[3]) local now = tonumber(ARGV[4]) local data = redis.call("HMGET", key, "tokens", "timestamp") local current_tokens = tonumber(data[1]) or capacity local last_timestamp = tonumber(data[2]) or now -- 计算新增的令牌数 local elapsed = now - last_timestamp local new_tokens = math.floor(elapsed * rate) -- 更新令牌数量 current_tokens = math.min(capacity, current_tokens + new_tokens) if current_tokens >= tokens then current_tokens = current_tokens - tokens redis.call("HMSET", key, "tokens", current_tokens, "timestamp", now) redis.call("EXPIRE", key, 86400) -- 24小时过期 return 1 else redis.call("HMSET", key, "tokens", current_tokens, "timestamp", now) redis.call("EXPIRE", key, 86400) return 0 end '; return (bool) $this->redis->eval($script, [$key, $this->capacity, $this->rate, $tokens, $now], 1); } } // 使用示例 class Rat…

PHP循环依赖与依赖注入解决方案
type: item
date: 2025-10-06T10:40:00+08:00
description: PHP开发中的复杂问题及解决方案：循环依赖与依赖注入在PHP项目开发中，循环依赖是一个常见且棘手的问题，特别是在使用依赖注入容器时。这个问题会导致应用程序无法正常启动，甚至引发致命错误。什么是循环依赖？循环依赖发生在两个或多个类相互依赖对方时：class UserService { public function __construct(private EmailService $emailService) {} } class EmailService { public function __construct(private UserService $userService) {} }上面的代码会产生循环依赖：UserService 依赖 EmailService，而 EmailService 又依赖 UserService。常见的循环依赖场景1. 构造函数注入循环依赖// 错误示例 class OrderService { public function __construct( private PaymentService $paymentService, private NotificationService $notificationService ) {} public function processOrder($order) { // 处理订单逻辑 $this->paymentService->processPayment($order); } } class PaymentService { public function __construct( private OrderService $orderService, private LoggerInterface $logger ) {} public function processPayment($order) { // 支付处理逻辑 $this->orderService->updateOrderStatus($order, 'paid'); } }2. 服务层相互调用class UserService { public function __construct( private RoleService $roleService ) {} public function getUserPermissions($userId) { $user = $this->getUserById($userId); return $this->roleService->getRolePermissions($user->roleId); } } class RoleService { public function __construct( private UserService $userService ) {} public function assignRoleToUser($userId, $roleId) { $user = $this->userService->getUserById($userId); // 分配角色逻辑 } }解决方案方案一：重构设计模式1. 提取公共依赖// 创建独立的服务处理共同逻辑 class UserPermissionService { public function __construct( private UserRepository $userRepository, private RoleRepository $roleRepository ) {} public function getUserPermissions($userId) { $user = $this->userRepository->findById($userId); return $this->roleRepository->getRolePermissions($user->roleId); } } class UserService { public function __construct( private UserRepository $userRepository, private UserPermissionService $permissionService ) {} } class RoleService { public function __construct( private RoleRepository $roleRepository, private UserPermissionService $permissionService ) {} }2. 使用接口抽象interface UserProviderInte…

PHP开发中的内存泄漏与性能优化实战解决方案
type: item
date: 2025-10-01T10:40:00+08:00
description: PHP开发中的复杂问题及解决方案：内存泄漏与性能优化实战在PHP开发过程中，我们经常会遇到各种复杂的技术挑战。今天我们将深入探讨一个常见但极具挑战性的问题——PHP内存泄漏，并提供一套完整的解决方案。问题背景PHP作为一门广泛使用的服务器端脚本语言，在处理大量数据或长时间运行的脚本时，经常会出现内存消耗过高的问题。特别是在以下场景中：处理大文件上传或导入执行批量数据处理任务运行长时间执行的后台脚本处理复杂的递归算法典型案例分析案例场景：大数据量Excel文件解析导致的内存溢出// 问题代码示例 function processLargeExcelFile($filePath) { $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filePath); $worksheet = $spreadsheet->getActiveSheet(); // 直接加载所有数据到内存中 $data = $worksheet->toArray(); foreach ($data as $row) { // 处理每一行数据 processRowData($row); } }上述代码在处理大型Excel文件时会遇到致命错误：Fatal error: Allowed memory size of 134217728 bytes exhausted解决方案详解方案一：分块处理（Chunk Processing）/** * 使用分块读取避免内存溢出 * * @param string $filePath Excel文件路径 * @param int $chunkSize 每次处理的行数 */ function processExcelInChunks($filePath, $chunkSize = 1000) { try { $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($filePath); $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); $reader->setReadDataOnly(true); // 只读取数据，不读取样式 $chunkFilter = new ChunkReadFilter(); $reader->setReadFilter($chunkFilter); $startRow = 1; do { $chunkFilter->setRows($startRow, $chunkSize); $spreadsheet = $reader->load($filePath); $worksheet = $spreadsheet->getActiveSheet(); $highestRow = $worksheet->getHighestRow(); $endRow = min($startRow + $chunkSize - 1, $highestRow); for ($row = $startRow; $row <= $endRow; ++$row) { $rowData = $worksheet->rangeToArray('A' . $row . ':' . $worksheet->getHighestColumn() . $row, null, true, false); processRowData($rowData[0]); // 显式清理变量 unset($rowData); } // 清理对象引用 $spreadsheet->disconnectWorksheets(); unset($spreadsheet); $startRow += $chunkSize; } while ($startRow <= $highestRow); } catch (Exception $e) { throw new Exception("处理Excel文件失败：" . $e->getMessage()); } } /** * 分块读取过滤器 */ class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter { private $startRow = 0; private $endRow = 0; public function setRows($startRow, $chunkSize) { $this->startRow = $startRow; $this->endRow = $startR…