rkljw 1 ngày trước cách đây
mục cha
commit
4c4658392d
2 tập tin đã thay đổi với 204 bổ sung7 xóa
  1. 1 0
      app/Controller/MinioController.php
  2. 203 7
      app/Controller/PublicController.php

+ 1 - 0
app/Controller/MinioController.php

@@ -38,6 +38,7 @@ class MinioController extends AbstractController
         if ($uploadedFile && $uploadedFile->isValid()) {
             $filename = $uploadedFile->getClientFilename();
             $fileContent = base64_encode(file_get_contents($uploadedFile->getRealPath()));
+            var_dump("look============:",$fileContent);
             $mimeType = $uploadedFile->getMimeType();
 //            var_dump("大小:",$uploadedFile->getSize());
             if($uploadedFile->getSize()>2097152){

+ 203 - 7
app/Controller/PublicController.php

@@ -381,23 +381,219 @@ class PublicController extends AbstractController
 
         if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
             // 将要下载的文件逐个添加到zip文件中
-//            $string = trim($requireData['files'], "[]'"); // 去掉最外层的方括号和单引号(注意:这里假设了单引号,如果是双引号则替换为 ")
-//            $string = str_replace("'", '', $string); // 去掉所有剩余的单引号(如果原字符串中使用的是双引号,则替换为双引号)
-//            $filePaths = explode(',', $string);
-            foreach ($requireData['files'] as $filePathu) {
-                // $attachmentItem = 'public/' . $filePathu;
-                $zip->addFile($filePathu, pathinfo($filePathu, PATHINFO_BASENAME));
+            /** @var array<string> $files */
+            $files = [];
+            if (is_array($requireData['files'])) {
+                $files = $requireData['files'];
+            } elseif (is_string($requireData['files'])) {
+                $files = [$requireData['files']];
+            }
+            
+            foreach ($files as $key => $filePathu) {
+                if (!is_string($filePathu)) {
+                    continue;
+                }
+                
+                // 生成文件名:key + 1
+                $fileName = ($key + 1) . $this->getFileExtension($filePathu);
+                
+                // 处理base64数据
+                if ($this->isBase64Data($filePathu)) {
+                    $this->addBase64FileToZip($zip, $filePathu, $fileName);
+                }
+                // 处理远程URL文件
+                if (filter_var($filePathu, FILTER_VALIDATE_URL)) {
+                    $this->addRemoteFileToZip($zip, $filePathu, $fileName);
+                } else {
+                    // 处理本地文件
+                    if (!file_exists($filePathu)) {
+                        // 尝试添加public前缀
+                        $fullPath = 'public/' . $filePathu;
+                        if (!file_exists($fullPath)) {
+                            // 尝试使用绝对路径
+                            $fullPath = BASE_PATH . '/public/' . $filePathu;
+                            if (!file_exists($fullPath)) {
+                                continue; // 跳过不存在的文件
+                            }
+                        }
+                        $filePathu = $fullPath;
+                    }
+                    
+                    // 确保文件存在且可读
+                    if (is_file($filePathu) && is_readable($filePathu)) {
+                        $zip->addFile($filePathu, $fileName);
+                    }
+                }
             }
             // 关闭zip文件
             $zip->close();
             // 将zip文件提供给用户进行下载
-//            readfile($zipFileName);
             $fileUrlName = explode("public", $zipFileName);
             return Result::success(['fileUrl' => env('HOST') . $fileUrlName[1]]);
         } else {
             return Result::error('无法创建zip文件');
         }
     }
+    
+    /**
+     * 添加远程文件到zip
+     */
+    private function addRemoteFileToZip($zip, $url, $fileName = null): void
+    {
+        try {
+            // 创建临时文件
+            $tempFile = tempnam(sys_get_temp_dir(), 'remote_file_');
+            
+            // 设置更长的超时时间和更好的下载参数
+            $context = stream_context_create([
+                'http' => [
+                    'timeout' => 120, // 增加到120秒
+                    'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
+                    'follow_location' => true, // 允许重定向
+                    'max_redirects' => 5,
+                    'protocol_version' => 1.1,
+                    'header' => [
+                        'Accept: */*',
+                        'Accept-Encoding: gzip, deflate',
+                        'Connection: keep-alive'
+                    ]
+                ],
+                'ssl' => [
+                    'verify_peer' => false,
+                    'verify_peer_name' => false,
+                    'allow_self_signed' => true
+                ]
+            ]);
+            
+            // 使用cURL作为备选方案
+            $fileContent = $this->downloadFileWithCurl($url);
+            if ($fileContent === false) {
+                // 如果cURL失败,尝试file_get_contents
+                $fileContent = file_get_contents($url, false, $context);
+            }
+            
+            if ($fileContent === false) {
+                error_log("Failed to download remote file: " . $url);
+                return; // 下载失败,跳过
+            }
+            
+            // 验证文件内容
+            if (empty($fileContent) || strlen($fileContent) < 100) {
+                error_log("Downloaded file is too small or empty: " . $url);
+                return;
+            }
+            
+            // 写入临时文件并验证
+            $bytesWritten = file_put_contents($tempFile, $fileContent);
+            if ($bytesWritten === false || $bytesWritten !== strlen($fileContent)) {
+                error_log("Failed to write file content: " . $url);
+                return;
+            }
+            
+            // 验证文件是否可读
+            if (!is_readable($tempFile) || filesize($tempFile) < 100) {
+                error_log("Temporary file is not readable or too small: " . $tempFile);
+                return;
+            }
+            
+            // 获取文件名
+            if ($fileName === null) {
+                $fileName = basename(parse_url($url, PHP_URL_PATH));
+                if (empty($fileName)) {
+                    $fileName = 'remote_file_' . time() . '.jpg';
+                }
+            }
+            
+            // 添加到zip并验证
+            if (!$zip->addFile($tempFile, $fileName)) {
+                error_log("Failed to add file to zip: " . $fileName);
+                return;
+            }
+            
+        } catch (\Exception $e) {
+            // 记录错误但继续处理其他文件
+            error_log("Failed to download remote file: " . $url . " - " . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 使用cURL下载文件
+     */
+    private function downloadFileWithCurl($url): string|false
+    {
+        if (!function_exists('curl_init')) {
+            return false;
+        }
+        
+        $ch = curl_init();
+        curl_setopt_array($ch, [
+            CURLOPT_URL => $url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_TIMEOUT => 120, // 120秒超时
+            CURLOPT_CONNECTTIMEOUT => 30, // 连接超时30秒
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_MAXREDIRS => 5,
+            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_SSL_VERIFYHOST => false,
+            CURLOPT_ENCODING => '', // 自动处理编码
+            CURLOPT_HTTPHEADER => [
+                'Accept: image/*, */*',
+                'Accept-Encoding: gzip, deflate',
+                'Connection: keep-alive',
+                'Cache-Control: no-cache'
+            ]
+        ]);
+        
+        $content = curl_exec($ch);
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        $contentLength = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
+        $actualLength = strlen($content);
+        curl_close($ch);
+        
+        // 检查HTTP状态码和内容长度
+        if ($content === false || $httpCode !== 200) {
+            error_log("cURL download failed for URL: $url, HTTP Code: $httpCode");
+            return false;
+        }
+        
+        // 检查内容长度是否匹配
+        if ($contentLength > 0 && $actualLength !== $contentLength) {
+            error_log("Content length mismatch for URL: $url, Expected: $contentLength, Actual: $actualLength");
+            return false;
+        }
+        
+        // 检查文件是否为空或太小
+        if (empty($content) || $actualLength < 100) {
+            error_log("File too small or empty for URL: $url, Size: $actualLength");
+            return false;
+        }
+        
+        return $content;
+    }
+    
+    /**
+     * 获取文件扩展名
+     */
+    private function getFileExtension($filePath): string
+    {
+        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
+        if (empty($extension)) {
+            // 如果是URL,尝试从URL中获取扩展名
+            if (filter_var($filePath, FILTER_VALIDATE_URL)) {
+                $parsedUrl = parse_url($filePath, PHP_URL_PATH);
+                $extension = pathinfo($parsedUrl, PATHINFO_EXTENSION);
+            }
+            
+            // 如果还是没有扩展名,默认为jpg
+            if (empty($extension)) {
+                $extension = 'jpg';
+            }
+        }
+        
+        return '.' . $extension;
+    }
+    
     /**
      * 检测是否被处理
      * @return array