PHP basename() 和 pathinfo() 与多字节 UTF-8 文件名

2023-11-25

我发现 PHP 函数 basename() 以及 pathinfo() 对于多字节 utf-8 名称有奇怪的行为。 它们删除所有非拉丁字符,直到第一个拉丁字符或标点符号。但是,此后,后续的非拉丁字符将被保留。

basename("àxà"); // returns "xà", I would expect "àxà" or just "x" instead
pathinfo("àyà/àxà", PATHINFO_BASENAME); // returns "xà", same as above

但奇怪的是 pathinfo() 的 dirname 部分工作正常:

pathinfo("àyà/àxà", PATHINFO_DIRNAME); // returns "àyà"

PHP 文档警告说基本名称() and 路径信息()函数是区域设置感知的,但这并不能证明之间的不一致pathinfo(..., PATHINFO_BASENAME) and pathinfo(..., PATHINFO_DIRNAME),更不用说相同的非拉丁字符被丢弃或接受的事实,具体取决于它们相对于拉丁字符的位置。

听起来像是一个 PHP 错误。

由于“基本名称”检查对于避免目录遍历的安全问题非常重要,因此是否有任何可靠的基本名称过滤器可以与 unicode 输入正常工作?


我发现更改区域设置可以解决所有问题。

虽然 Apache 默认使用“C”语言环境运行,但 cli 脚本默认使用 utf-8 语言环境运行,例如“en_US.UTF-8”(或者在我的情况下为“it_IT.UTF-8”)。在这些条件下,不会出现该问题。

因此,Apache 的解决方法包括在调用这些函数之前将区域设置从“C”更改为“C.UTF-8”。

setlocale(LC_ALL,'C.UTF-8');
basename("àxà"); // now returns "àxà", which is correct
pathinfo("àyà/àxà", PATHINFO_BASENAME); // now returns "àxà", which is correct

或者更好的是,如果您想备份当前区域设置并在完成后恢复它:

$lc = new LocaleManager();
$lc->doBackup();
$lc->fixLocale();
basename("àxà/àyà");
$lc->doRestore();


class LocaleManager
{
    /** @var array */
    private $backup;


    public function doBackup()
    {
        $this->backup = array();
        $localeSettings = setlocale(LC_ALL, 0);
        if (strpos($localeSettings, ";") === false)
        {
            $this->backup["LC_ALL"] = $localeSettings;
        }
        // If any of the locales differs, then setlocale() returns all the locales separated by semicolon
        // Eg: LC_CTYPE=it_IT.UTF-8;LC_NUMERIC=C;LC_TIME=C;...
        else
        {
            $locales = explode(";", $localeSettings);
            foreach ($locales as $locale)
            {
                list ($key, $value) = explode("=", $locale);
                $this->backup[$key] = $value;
            }
        }
    }


    public function doRestore()
    {
        foreach ($this->backup as $key => $value)
        {
            setlocale(constant($key), $value);
        }
    }


    public function fixLocale()
    {
        setlocale(LC_ALL, "C.UTF-8");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP basename() 和 pathinfo() 与多字节 UTF-8 文件名 的相关文章

  • 自定义 WP 主题时,我应该将导航栏放在“”标签之前还是之后?

    我正在通过制作子主题来自定义 WP 主题 我将 Bootstrap 中的导航栏放入子主题目录中的 header php 文件中 但是 我不确定在哪里放置导航栏代码 我可以把它都放在前面and之后标记成功 例如 无论我选择哪一个 导航栏都显示
  • 为什么我不能在 TCPDF 表中使用 č,ć,đ 图表?

    我正在为我的网站构建一个 tcpdf 文件 该 tcpdf 文件中有一个包含一些数据的表格 但我无法使该章程正常工作 对于编码 我使用 windows 1250 宪章女巫不起作用 我已经尝试过 utf 8 但仍然没有得到这个章程 tcpdf
  • Smarty输出空白页

    已解决 模板文件错误 我有这样的 Smarty 设置 require once smarty Smarty class php smarty new Smarty smarty gt compile dir compile dir smar
  • 如何复制 ArrayIterator 以保留其当前迭代位置?

    因为这似乎是我必须做的才能达到这种效果 arr a gt first b gt second iter new ArrayIterator arr Do a bunch of iterations iter gt next new iter
  • 在值中包含换行符

    我有一个 Word 模板 其中 php 代码中定义了值 在PHP代码中 document gt setValue Value1 value1 在word模板中 Value1 如何将包含两个值之间的断线的值包含在单词的值中 Replace n
  • 从 octobercms 中的非 ajax 表单获取输入值

    我正在尝试构建一个简单的搜索功能 下面是我的搜索表格
  • PHP 或 WAMP 不确定是什么

    我已经安装了 WAMP 服务器 2 0 PHP 5 4 3 安装WAMP后我已经重新启动了所有服务并且可以打开 phpinfo 显示良好 phpmyadmin 它也显示得很好 我可以使用数据库 然而 当在 Chrome 中运行简单的 php
  • 负载平衡集群中的 PHP 会话 - 如何?

    好的 我得到了这个完全罕见的负载平衡 PHP 网站的独特场景 令人遗憾的是 它过去没有进行负载平衡 现在我们开始遇到问题 目前唯一的问题是 PHP 会话 当然 一开始没有人想到这个问题 因此 PHP 会话配置保留为默认值 因此 两台服务器都
  • 如何在类似 MVC 的页面中加载基于漂亮 URL 的类?

    我想请教一些关于如何解决这个问题的提示 我正在尝试构建自己的 MVC 网站 我了解了 URL 的基础知识 http example com blog cosplay cosplayer expo today 博客 gt 控制器cosplay
  • 如何在 PHP 中使用 cURL 发出同时包含 GET 和 POST 参数的请求?

    其他人已经问过如何从 perl java bash 等执行此操作 但我需要在 PHP 中执行此操作 并且我没有看到任何已提出的专门与 PHP 相关的问题 或包含 PHP 的答案 My code ch curl init url curl s
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • MySQL PHP邮政编码比较具体距离

    我试图找出比较一个邮政编码 用户提供的 和一大堆其他邮政编码 现在大约有 200 个邮政编码 之间的距离的最有效方法 相对于加载时间 但它会随着时间的推移而增加 我不需要任何精确的东西 只是在球场上 我下载了整个美国的邮政编码 csv 文件
  • JavaScript 验证和 PHP 验证?

    我正在使用 jquery 验证插件来验证空表单 我还应该在 PHP 中检查一下以确保 100 正确吗 或者用 javascript 验证就可以了 谢谢 您应该始终在服务器上进行验证 如果用户以某种方式不使用 Javascript 提交表单
  • MVC 模式中的验证层

    验证模型将使用的数据的最佳位置在哪里 例如 考虑登记表 我们有一些来自注册表的数据 那么验证这些数据的最佳位置在哪里 我们应该通过 if 语句或特殊的验证器类来检查每个数据 这意味着大量的编码 所以我想了解在哪里可以做到这一点 在控制器中
  • WordPress 插件中的类自动加载器

    我想编写一个类自动加载器以在 WordPress 插件中使用 该插件将安装在多个站点上 我想尽量减少与其他插件发生冲突的机会 自动加载器将是这样的 function autoload name some code here 我的主要问题是
  • suhosin.mt_srand.ignore 在 PHP 中一致洗牌数组的解决方法?

    我有一个 PHP 脚本 需要随机化一个具有一致结果的数组 这样它就可以向用户呈现前几个项目 然后如果他们愿意 他们可以从同一个打乱的集合中提取更多结果 我目前使用的是这个 基于我相信的 Fisher Yates 算法 function sh
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int
  • 从 PHP 数组生成 HTML 表

    我不明白这一点 我需要解决看似简单的问题 但这超出了我的逻辑 我需要编写一个函数 table columns input cols 它将输出一个表 示例 input array apple orange monkey potato chee
  • 如何在laravel中注册后自动登录

    我在 laravel 中注册用户时遇到问题 user假设是包含所有数组元素的数组 同时自动登录以下代码结果false 数据库中保存的密码是hash make password user id this gt user model gt ad
  • 使用 php-ews(Exchange Web 服务)在特定日期后获取电子邮件

    在我的 PHP 脚本中 我需要弄清楚如何检索指定消息 ID 之后或特定日期之后的所有电子邮件 两者都可以 我只需要检索自上次抓取收件箱以来的新电子邮件 这个收件箱每天收到数千封电子邮件 而且我在 30 天内无法删除任何电子邮件 对于初始导入

随机推荐

  • 当 printf 的相应参数不是短/字符时,使用 h 或 hh 长度修饰符是否非法?

    The printf函数族提供了一系列长度修饰符 其中两个是hh 表示一个signed char or unsigned char论点提升为int and h 表示一个signed short or unsigned short论点提升为i
  • PHP 电子邮件正文解码为纯文本

    我正在用 php 绑定一些相同电子邮件的提取内容 但我不能 接着就 随即 body imap body imap o email n I get Pour le r E9cup E9rer il suffit de le t E9l E9c
  • 批量“计数器”

    我正在尝试制作一个批处理文件 每次循环时都会将变量加 1 然后检查该变量是否等于 5 如果不等于 则再次循环 我知道这可能需要一个 while 循环 但我不知道该怎么做 而且我现在只是享受学习 Batch 的乐趣 这是代码 它没有按应有的方
  • C# MySQL like查询不带参数

    我正在使用查询来查找特定字段中的关键字 当我输入 parameter 然后添加带有值的参数时 它不起作用 但是当我直接输入值时 它起作用 任何人都可以帮助我将值作为参数传递给我的请询问 下面是我的代码 这可以工作并检索标题中包含 我的 一词
  • 如何防止使用 JPA 保存子对象?

    我在学校和学生实体之间建立了 OneToMany 关系 我想要做的是 当我保存学校对象时 不要保存或更新学生对象 当然也不要删除它们 当我尝试保存如下所示的学校对象时 它也会更新我的学生对象 但我不希望它们被更新 而只是可连接 有什么办法吗
  • C# 拦截WebBrowser发出的请求

    是否可以拦截所有的请求WebBrowser控制 我想修改每个请求的请求URI 包括图像 脚本 样式表等的请求 有一个活动叫 导航2之前 在发出任何请求之前调用 您可以使用它来修改传出请求
  • 无形状映射中的子类型多态性

    我构建了以下内容 import shapeless import poly object Main def main args Array String object iterateOverHList extends List gt Ite
  • 在未找到匹配项的 OPTIONAL MATCH 之后创建

    我正在尝试编写一个查询 如果另一个关系已经存在 它将创建一些关系 START a node 1 b node 2 c node 3 OPTIONAL MATCH a r1 RELATIONSHIP optional1 OPTIONAL MA
  • 判断CGPoint是否在图像区域内

    我试图弄清楚 CGPoint 是否位于图像的形状内 该图像是一个简单的黑色形状 如下面所附的两个 我想创建一个方法来确定 CGPoint 是否位于该形状的黑色区域内 我认为这需要两件事 1 将图像变成可以用代码读取的东西 不确定这将使用哪种
  • Flask 中的大文件上传

    我正在尝试实现一个烧瓶应用程序来上传文件 该文件可能非常大 比如差不多2G大小 我已经完成了服务器端处理功能 如下所示 app route upload
  • Volley 服务器错误,网络响应为空

    每次我尝试在 Volley 中使用 POST 方法时 都会出现严重错误 我在 getCause 中得到 null 值 在 get Network Response toString 中得到一些默认值 如果我使用 GET 方法 效果很好 我从
  • PUT POST 具有幂等性 (REST)

    我不太明白 HTTP 动词是如何定义为幂等的 我读到的只是 GET 和 PUT 是幂等的 POST 不是幂等的 但是您可以使用 POST 创建一个不会更改任何内容 例如在数据库中 的 REST API 或者为 PUT 创建一个在每次调用时都
  • pandas 数据框,按值复制

    我注意到我的程序中存在一个错误 它发生的原因是因为 pandas 似乎是通过引用而不是通过值复制 pandas 数据框 我知道不可变对象总是通过引用传递 但 pandas 数据帧不是不可变的 所以我不明白为什么它通过引用传递 有人可以提供一
  • Inno Setup,[Run] 中的空格和双引号

    我正在尝试在 Windows 上安排任务 但不幸的是 它不起作用 任务已创建 但不正确 当我查看任务的参数时 它说 PROGRAM C Program ARGUMENTS Files x86 AppName executable exe 我
  • C++11 中的命名空间问题?

    有人可以解释一下以下内容吗 cat test cpp include
  • 使用 LinkMovementMethod 时可以禁用 TextView 中的滚动吗?

    我在 textView 中使用可点击范围来仅允许部分文本可点击 它工作正常 只是 textView 向下滚动 这是我不想要的 发生这种情况是因为我使用 LinkMovementMethod 在需要时滚动 有没有办法取消滚动 Spannabl
  • 使用 Javascript 播放 HTML5 视频 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我该如何使用JavaScript播放 HTML5
  • 作为“本地系统”运行 Windows 服务有哪些安全风险?

    我编写了一个作为 本地系统 运行的 NET Windows 服务 最近我读到 作为本地系统运行可能会将系统凭据暴露给黑客 使他们能够接管系统 当我作为本地系统运行服务时 涉及哪些风险以及如何预防这些风险 服务运行为LocalSystem是系
  • kubernetes 部署-容器未启动-错误- InvalidImageName

    以下是 Kubernetes 部署 yaml 文件 container图片部分 image https registry ng bluemix net test service test branch 67 imagePullPolicy
  • PHP basename() 和 pathinfo() 与多字节 UTF-8 文件名

    我发现 PHP 函数 basename 以及 pathinfo 对于多字节 utf 8 名称有奇怪的行为 它们删除所有非拉丁字符 直到第一个拉丁字符或标点符号 但是 此后 后续的非拉丁字符将被保留 basename x returns x