只应通过引用传递变量

Fra*_*oko 220 php

// Other variables
$MAX_FILENAME_LENGTH = 260;
$file_name = $_FILES[$upload_name]['name'];
//echo "testing-".$file_name."<br>";
//$file_name = strtolower($file_name);
$file_extension = end(explode('.', $file_name)); //ERROR ON THIS LINE
$uploadErrors = array(
    0=>'There is no error, the file uploaded with success',
    1=>'The uploaded file exceeds the upload max filesize allowed.',
    2=>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
    3=>'The uploaded file was only partially uploaded',
    4=>'No file was uploaded',
    6=>'Missing a temporary folder'
);
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?2天后仍然卡住了.

Osw*_*ald 460

将结果分配explode给变量并将该变量传递给end:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);
Run Code Online (Sandbox Code Playgroud)

问题是,这end需要引用,因为它修改了数组的内部表示(即它使当前元素指针指向最后一个元素).

结果explode('.', $file_name)不能变成参考.这是PHP语言中的限制,可能出于简单原因而存在.

  • 非常感谢.解决了我的问题. (12认同)
  • 关闭`error_reporting`是安全的.盲目忽视错误是不安全的.关闭`error_reporting`是盲目忽略错误的重要一步.在生产环境中,请关闭`display_errors`,并将错误写入日志文件. (7认同)

Sin*_*dem 51

Php 7兼容正确用法:

$fileName      = 'long.file.name.jpg';
$tmp           = explode('.', $fileName);
$fileExtension = end($tmp);

echo $fileExtension;
// jpg
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个..但我不喜欢它同时.谢谢你毁了我的一天:-) (25认同)
  • 我研究了这个怪癖,它似乎是一个**bug?**与**php解析器**其中**双括号**"(())"导致引用转换为普通值.更多关于此[链接](http://phpsadness.com/sad/51). (8认同)
  • 那么为什么添加额外的括号会删除错误? (6认同)
  • 在php7中仍会发出警告.http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.variable-handling.parentheses (4认同)
  • 奇怪的.这有效但怎么样?它会抑制警告,类似于`@`前缀吗? (3认同)
  • 因此,它之所以有效是因为它是您不应该建议的错误,不是吗? (2认同)

rye*_*guy 43

其他人都已经告诉你了解错误的原因,但这是做你想做的最好的方法: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

  • 我同意。当您有适当的 API 时,使用字符串操作来解析文件路径是没有意义的。 (4认同)
  • 这对我来说是最好的答案,字符串操作只会在代码中添加一些混乱 (2认同)

Ste*_*uel 24

其他地方给出的答案,

$tmp = explode('.', $fileName);
$file_extension = end($tmp);
Run Code Online (Sandbox Code Playgroud)

是正确且有效的。它完成了您正在尝试做的事情。

为什么?

end()函数的功能并不完全符合您的想象。这与PHP数据结构的工作原理有关array。您通常看不到它,但 PHP 中的数组包含一个指向当前元素的指针,该指针用于迭代(如 with foreach)。

为了使用end(),您必须有一个实际的数组,该数组已附加(通常是不可见的)当前元素指针。该end()函数物理上修改该指针。

的输出explode()不是实际的数组。它是一个函数输出。因此,您不能运行,end(explode())因为您违反了语言要求。

explode()只需在变量中设置 的输出即可创建您要查找的数组。创建的数组有一个当前元素指针。现在,世界一切又恢复正常了。

那么括号呢?

这不是一个错误。再次强调,这是语言要求。

额外的括号(如end((explode())))不仅仅是分组。它们创建一个内联实例变量,就像将函数输出设置为变量一样。您可以将其视为立即执行的 lambda 函数。

这是另一个正确有效的解决方案。这可能是一个更好的解决方案,因为它占用的空间更少。一个好的审阅者或维护者在看到额外的括号时应该明白你想要做什么。

如果您使用 PHPCS 等 linter 或 SCA 程序,则可能不喜欢额外的括号,具体取决于您使用的 linting 配置文件。这是你的 linter,告诉它你想让它为你做什么。

其他一些答案还列出了诸如展开运算符 或 之类的内容array_key_last(),这也是合理的解决方案。它们可能完全有效,但使用和阅读起来更加复杂。

我将只使用@前缀

这个解决方案是有效的,但不正确。它是有效的,因为它解决了问题。这就是它的优点了。

抑制错误始终是不好的做法。原因有很多。其中一个非常大的问题是您试图抑制一种特定的错误条件(您已经创建的错误条件),但错误抑制前缀会抑制所有错误。

在这种情况下,你可能会逃脱惩罚。然而,养成不良的编程习惯就是作弊,并且很可能会导致你将来作弊的次数越来越多。您将对错误的代码负责。但我不是代码警察,这是你的代码。它是有效的,因为它解决了问题。

好吧,那么最好的答案是什么?

按照@ryeguy 的建议进行操作。不要通过字符串操作来解决平台已经为您解决的明确定义的问题。使用pathinfo()

这样做的另一个好处是它实际上可以完成您想要的操作,即查找文件名的扩展名。有一个细微的差别。

您所做的就是获取最后一个点后面的文本。这与查找文件扩展名不同。考虑文件名.gitignore. PHP 知道如何处理这个问题。你的代码有吗?

再说一遍,我不是代码警察。做最适合你的事情。


Flo*_*ern 16

将数组从explode()保存到变量,然后在此变量上调用end():

$tmp = explode('.', $file_name);
$file_extension = end($tmp);
Run Code Online (Sandbox Code Playgroud)

顺便说一句:我使用此代码来获取文件扩展名:

$ext = substr( strrchr($file_name, '.'), 1);
Run Code Online (Sandbox Code Playgroud)

strrchr最后一个之后提取字符串.substr切断字符串.


Wil*_*den 9

试试这个:

$parts = explode('.', $file_name);
$file_extension = end($parts);
Run Code Online (Sandbox Code Playgroud)

原因是参数end是通过引用传递的,因为end通过将其内部指针前进到最终元素来修改数组.如果您没有传入变量,则没有任何参考指向.

有关end详细信息,请参阅PHP手册.


NVR*_*VRM 7

由于它已升旗超过 10 年,但工作正常并返回预期值,因此一点stfu 运算符是您正在寻找的最糟糕的做法:

$file_extension = @end(explode('.', $file_name));
Run Code Online (Sandbox Code Playgroud)

但警告,由于性能下降,请勿在循环中使用。最新版本的 php 7.3+ 提供了方法array_key_last()array_key_first().

https://www.php.net/manual/en/function.array-key-last.php

                 uuuuuuu
             uu$$$$$$$$$$$uu
          uu$$$$$$$$$$$$$$$$$uu
         u$$$$$$$$$$$$$$$$$$$$$u
        u$$$$$$$$$$$$$$$$$$$$$$$u
       u$$$$$$$$$$$$$$$$$$$$$$$$$u
       u$$$$$$$$$$$$$$$$$$$$$$$$$u
       u$$$$$$"   "$$$"   "$$$$$$u
       "$$$$"      u$u       $$$$"
        $$$u       u$u       u$$$
        $$$u      u$$$u      u$$$
         "$$$$uu$$$   $$$uu$$$$"
          "$$$$$$$"   "$$$$$$$"
            u$$$$$$$u$$$$$$$u
             u$"$"$"$"$"$"$u
  uuu        $$u$ $ $ $ $u$$       uuu
 u$$$$        $$$$$u$u$u$$$       u$$$$
  $$$$$uu      "$$$$$$$$$"     uu$$$$$$
u$$$$$$$$$$$uu    """""    uuuu$$$$$$$$$$
$$$$"""$$$$$$$$$$uuu   uu$$$$$$$$$"""$$$"
 """      ""$$$$$$$$$$$uu ""$"""
           uuuu ""$$$$$$$$$$uuu
  u$$$uuu$$$$$$$$$uu ""$$$$$$$$$$$uuu$$$
  $$$$$$$$$$""""           ""$$$$$$$$$$$"
   "$$$$$"                      ""$$$$""
     $$$"                         $$$$"
Run Code Online (Sandbox Code Playgroud)


wiz*_*ard 6

PHP抱怨因为end()期望引用它想要改变的东西(它只能是一个变量).但是,您可以explode()直接将结果传递给end()它而不将其保存到变量中.在explode()返回值时,它仅存在于内存中,并且没有变量指向它.您不能创建对某些内容(或内存中未知的内容)的引用,这种内容不存在.

或者换句话说:PHP不知道,如果你给他的值是直接值或只是指向值的指针(指针也是一个变量(整数),它存储内存的偏移量,其中实际值所在).所以PHP总是希望这里有一个指针(引用).

但由于这仍然只是PHP 7中的一个通知(甚至不推荐),您可以保存忽略通知并使用ignore-operator而不是完全停用通知的错误报告:

$file_extension = @end(explode('.', $file_name));
Run Code Online (Sandbox Code Playgroud)

  • @OskarCalvo这也是我的理念。但这不是错误-PHP将其视为“通知”。这是这里其他答案的替代“解决方案”,没有人直接提及。更好的方法是将“ explode”的值保存到一个临时变量中,就像其他人在这里写的一样。但是再次:这不是错误,因此可以使用此运算符。PHP通常不好处理错误。因此,我建议使用`set_error_handler`和`set_exception_handler`进行错误处理并作为最干净的解决方案。 (3认同)

Tgr*_*Tgr 5

end(...[explode('.', $file_name)])从 PHP 5.6 开始工作。这在RFC 中有记录,但不在 PHP 文档中。