dootask/app/Module/Apps/Volumes.php
2025-05-05 08:25:21 +08:00

113 lines
4.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Module\Apps;
class Volumes
{
/**
* 处理卷挂载配置,将相对路径转换为绝对路径
*
* @param array $volumes 原始卷挂载配置
* @param string $hostPwd 主机路径
* @return array 处理后的卷挂载配置
*/
public static function processVolumeConfigurations(array $volumes, string $hostPwd): array
{
return array_map(function ($volume) use ($hostPwd) {
// 短语法格式:字符串形式如 "./src:/app"
if (is_string($volume)) {
return self::processShortSyntaxVolume($volume, $hostPwd);
} // 长语法格式:数组形式包含 source 键
elseif (is_array($volume) && isset($volume['source'])) {
return self::processLongSyntaxVolume($volume, $hostPwd);
}
// 其他格式保持不变
return $volume;
}, $volumes);
}
/**
* 处理短语法格式的卷挂载
*
* @param string $volume 原始卷配置字符串
* @param string $hostPwd 主机路径
* @return string 处理后的卷配置字符串
*/
private static function processShortSyntaxVolume(string $volume, string $hostPwd): string
{
$parts = explode(':', $volume, 3);
$sourcePath = $parts[0];
$newSourcePath = self::convertRelativePathToAbsolute($sourcePath, $hostPwd);
// 如果路径已更改,重建挂载配置
if ($newSourcePath !== $sourcePath) {
$parts[0] = $newSourcePath;
return implode(':', $parts);
}
return $volume;
}
/**
* 处理长语法格式的卷挂载
*
* @param array $volume 原始卷配置数组
* @param string $hostPwd 主机路径
* @return array 处理后的卷配置数组
*/
private static function processLongSyntaxVolume(array $volume, string $hostPwd): array
{
$newSourcePath = self::convertRelativePathToAbsolute($volume['source'], $hostPwd);
// 如果路径已更改更新source
if ($newSourcePath !== $volume['source']) {
$volume['source'] = $newSourcePath;
}
return $volume;
}
/**
* 将相对路径转换为绝对路径
*
* @param string $path 原始路径
* @param string $hostPwd 主机路径
* @return string 处理后的路径
*/
private static function convertRelativePathToAbsolute(string $path, string $hostPwd): string
{
// 判断是否为相对路径Docker卷挂载有以下几种情况
// 1. 环境变量路径:包含${PWD}的路径,如 "${PWD}/data:/app/data"
// 这也是一种相对路径表示方式,需要标准化处理
// 2. 显式相对路径:以./或../开头的路径,如 "./data:/app/data" 或 "../logs:/var/log"
// 3. 隐式相对路径:不以/开头,但中间包含/的路径,如 "data/logs:/app/logs"
// (纯名称如"data"没有/,通常是命名卷而非相对路径)
// 4. 绝对路径:以/开头的路径,如 "/var/run/docker.sock:/var/run/docker.sock"
// 绝对路径已经是完整路径,不需要转换
//
// 注Docker Compose在解析路径时相对路径是相对于docker-compose.yml文件所在目录的
// 我们需要将这些相对路径转换为绝对路径,以确保在不同环境中能正确挂载目录
// 处理${PWD}路径
if (str_contains($path, '${PWD}')) {
// 将${PWD}替换为我们的标准路径格式
return str_replace('${PWD}', $hostPwd, $path);
}
// 处理./或../开头的显式相对路径
if (str_starts_with($path, './') || str_starts_with($path, '../')) {
$cleanPath = ltrim($path, './');
return $hostPwd . '/' . $cleanPath;
}
// 处理不以/开头的路径,且要么包含/(明确是路径而非命名卷)
if (!str_starts_with($path, '/') && str_contains($path, '/')) {
return $hostPwd . '/' . $path;
}
// 命名卷或绝对路径,保持不变
return $path;
}
}