【问题标题】:file_exists() for a file that contains (&) in filenamefile_exists() 用于文件名中包含 (&) 的文件
【发布时间】:2010-12-07 16:00:26
【问题描述】:
$filename = "Sara & I.mp3";
if (file_exists($filename)) {
 ...
}

如果文件名有“&”,PHP 不会为 file_exists 返回 true

如何在 $filename 中转义“&”以使file_exists 正常工作?

已经尝试过urlecode()urlrawencode()htmlentities(),并用反斜杠 (\&) 转义“&”...不行

ps。这是在运行 RedHat5 的 linux 系统上

提前致谢

【问题讨论】:

  • 这并不能回答您的问题,但“测试并执行操作”模式使您的代码对竞争条件开放。在您致电file_exists 之后但在您致电filesize 之前,有人可能会删除该文件。此外,文件存在这一事实并不意味着您有权访问它。如果您删除 file_exists 调用并为 filesize 失败做好准备,您的代码将更加健壮。
  • 回到您的问题,听起来您没有正确转义/取消转义$path。这个变量从何而来?
  • Correct 无法反驳 :) 然而,这段代码只是取自我不是原作者的 wordpress 插件...
  • 我试了一下,好像没问题。所以它必须是别的东西。您使用的文件系统是什么?确切的文件名是什么?提供更多使用信息。
  • @NawaMan,你到底尝试了什么?您试图在文件名中包含“&”字符的文件上 file_exists?

标签: php algorithm character filenames file-exists


【解决方案1】:

这些文件是用户上传的吗?我通常将任何上传的文件重命名为仅使用字母 A-Z、数字 0-9 和 _ 或 - 加上 .pdf 等文件扩展名,以避免特殊字符出现问题。空格被转换为_。

TYPO3,例如一个基于 PHP 的大型 CMS,使用这些正则表达式来清理文件名:

$fileName = preg_replace('/[^.[:alnum:]_-]/','_',trim($fileName));  // converting all on alphanumeric chars to _
$fileName = preg_replace('/\.*$/','',$fileName); // removing dot . after file extension

所以foo&.pdf. 的输入将被转换为foo.pdf

【讨论】:

  • 我想在不需要重命名文件的情况下解决这个问题。谢谢马克斯:)
【解决方案2】:

脚本似乎对我有用。

确保您正在检查的文件位于运行脚本的目录中。

使用 getcwd() 查看您的脚本在哪里运行。

例如如果您的脚本在 my/scripts/script.php 但如果它被 my/other/scripts/index.php 中的另一个脚本包含并调用,那么您的脚本实际上将在 my/other/scripts 目录中运行,而不是在 my/scripts 目录中,如您所料

【讨论】:

    【解决方案3】:

    如果它是一个文件,不应该像文件系统所期望的那样转义吗?它不应该是类似于 \& 的东西,或者可能是基于 unicode 的转义序列(现在让我转义了 ;-) 吗?

    【讨论】:

      【解决方案4】:

      我假设您将参数作为 GET 请求传递,例如 script.php?file=this & that.mp3

      首先确保您检查输入的内容非常好,这样用户就无法删除任意文件。第二:在创建链接时使用urlencode 对文件名进行编码。 & 的编码字符是 %26

      你的脚本会被这样调用:script.php?file=this%20%26%20that.mp3%20 是一个空格)

      否则,您将有另一个 GET 变量,即 that.mp3,未被分配。 & 用于分隔 GET 请求中的单个参数

      编辑
      我这边的一个问题:你如何删除你的文件?使用php的unlink函数?或在您的系统上使用exec 并调用rm? (这通常是非常不安全的)。如果您使用第二种方式,您可以使用escapeshellarg。如果你不转义你的 shell 输入,你的 shell 会将你的命令解释为两个命令(afaik,不要相信我的话)

      【讨论】:

      • 不,不通过 GET 请求传递它。尝试这样做,创建一个文件并在其中放入任何内容(任何 txt 或其他内容)并将其重命名为“this&that.whatever”,然后尝试查看 file_exists 是否有效 ps。这是在基于 linux 的系统上
      • 刚刚测试过。为我工作。 `unlink('this&that.test'); (也在linux系统上)
      【解决方案5】:

      &符号来自哪里 - 用户输入还是真的在您的脚本中?那里的编码可能有混淆。

      另外,当你对目录执行 glob() 时,你会得到什么结果?带有&符号的文件在那里吗?如果您复制并粘贴 glob() 输出并在其上运行 file_exists() 会发生什么?

      【讨论】:

        猜你喜欢
        • 2011-01-20
        • 1970-01-01
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 2013-05-14
        • 2019-06-04
        相关资源
        最近更新 更多