You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PHP含特殊字符的mkdir创建乱码目录问题及解决方案咨询

不用禁止特殊字符!用「展示/存储分离」方案解决问题

你完全不用限制用户输入带变音符号的名称,咱们可以通过**「展示用原始名称,存储/URL用标准化名称」**的思路,既满足用户的命名需求,又避开特殊字符在文件系统和URL里的兼容性、安全性问题。

核心思路

当用户提交带变音符号的图库名称时:

  1. 把用户输入的**原始名称(带变音符号)**存在数据库里,用来在页面上展示
  2. 生成一个标准化的slug(不含特殊字符的ASCII名称),用来创建实际的文件夹、拼接URL和数据库表名(如果必须用动态表的话)

这样用户看到的是自己输入的带变音符号的名称,但后台存储和URL里用的都是安全的标准化名称,完美兼顾两者。

具体修改步骤

1. 先处理用户创建图库的环节(补充你没贴的代码)

当用户提交命名时,先生成标准化slug,并存入数据库:

// 生成slug的工具函数:把变音符号转成对应ASCII,清理特殊字符
function createSafeSlug($originalName) {
    // 把变音符号转成近似ASCII(比如ö→o,č→c)
    $slug = iconv('UTF-8', 'ASCII//TRANSLIT', $originalName);
    // 只保留字母、数字、连字符,去掉其他特殊字符
    $slug = preg_replace('/[^a-zA-Z0-9\-]/', '', $slug);
    // 转小写、去首尾连字符、合并重复连字符
    $slug = strtolower(trim($slug, '-'));
    $slug = preg_replace('/-+/', '-', $slug);
    return $slug;
}

// 假设用户提交的原始名称是$userInputName
$userInputName = $_POST['gallery_name'];
$folderSlug = createSafeSlug($userInputName);

// 存入数据库:同时保存原始名称和slug
Db::query('INSERT INTO galleries (original_name, folder_slug, table_name) VALUES (?, ?, ?)', [
    $userInputName,
    $folderSlug,
    $folderSlug // 用slug作为数据库表名,避免特殊字符
]);

// 创建实际文件夹:用slug命名
mkdir("/path/to/galleries/$folderSlug", 0755, true);

2. 修改你现有的展示代码

从数据库取出原始名称用于展示,用slug拼接文件路径和URL:

// 先处理SQL注入风险:动态表名绝对不能直接用用户输入!必须做白名单验证
$allowedTables = ['summer_gallery', 'winter_gallery']; // 替换成你的合法表名列表
$foldername = $_GET['tabl'] ?? '';
if (!in_array($foldername, $allowedTables)) {
    die('Invalid gallery name');
}

// 处理路径遍历风险:限制$meno为合法的根目录
$baseGalleryPath = realpath('/path/to/galleries');
$meno = $_GET['meno'] ?? '';
$meno = realpath("$baseGalleryPath/$meno");
if (!$meno || strpos($meno, $baseGalleryPath) !== 0) {
    die('Invalid path');
}

// 从数据库取出原始名称和slug
$gallery = Db::queryAll('SELECT original_name, folder_slug FROM ' . $foldername); 
foreach ($gallery as $u) { 
    // 展示用原始名称,必须用htmlspecialchars转义防止XSS
    echo '<div class="section active" id=""><h1 class="headingfirst">' . htmlspecialchars($u["original_name"]) . '</h1>'; 
    
    // 实际文件路径用slug
    $folderSlug = $u["folder_slug"];
    $globPath = "$meno/$folderSlug/*.{png,jpg,jpeg,gif}";
    
    foreach (glob($globPath, GLOB_BRACE) as $filename) { 
        // 获取文件名(不带后缀)作为标题
        $title = pathinfo($filename, PATHINFO_FILENAME);
        // URL里用实际文件路径,同样转义输出
        echo '<div class="slide"><img class="" src="/' . htmlspecialchars($filename) . '" alt="' . htmlspecialchars($title) . '"/><p class="imagetitle">' . htmlspecialchars($title) . '</p></div>'; 
    }
}

关键注意事项

  • 绝对不能直接用用户输入做表名/文件夹名:哪怕是带变音符号的名称,直接用会导致SQL注入、路径遍历、文件系统兼容性问题(比如不同系统对特殊字符的支持不同)
  • 必须做安全验证:动态表名要白名单验证,路径要限制在合法目录内,所有输出到页面的内容都要用htmlspecialchars转义防止XSS
  • slug生成要稳定:确保同一个原始名称每次生成的slug一致,避免用户后续访问时找不到文件夹

这样处理后,用户既能用自己喜欢的带变音符号的名称命名图库,你的系统也能安全稳定地运行~

内容的提问来源于stack exchange,提问作者rebosha

火山引擎 最新活动