只能通过引用传递变量

// 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'
);

有什么办法吗? 两天后还是卡住了。

359318 次浏览

explode的结果赋值给一个变量,并将该变量传递给end:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

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

explode('.', $file_name)的结果不能转换为引用。这是PHP语言中的一个限制,可能是出于简单的原因。

将爆炸()中的数组保存到一个变量中,然后在这个变量上调用end():

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

btw:我使用这段代码来获得文件扩展名:

$ext = substr( strrchr($file_name, '.'), 1);

其中strrchr在最后一个.之后提取字符串,而substr切断.

试试这个:

$parts = explode('.', $file_name);
$file_extension = end($parts);

原因是end的参数是通过引用传递的,因为end通过将其内部指针前进到最后一个元素来修改数组。如果没有传入变量,则没有引用可以指向的对象。

更多信息请参见PHP手册中的end

就像你不能立即索引数组一样,你也不能对它调用end。首先将它赋值给一个变量,然后调用end。

$basenameAndExtension = explode('.', $file_name);
$ext = end($basenameAndExtension);
其他人都已经给出了你得到错误的原因,但这里是做你想做的事情的最佳方式: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION); < / p >

Php 7兼容的正确用法:

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


echo $fileExtension;
// jpg
PHP官方手册: 结束()< / p >

参数

array

数组。这个数组是通过引用传递的,因为它是由函数修改的。这意味着您必须传递给它一个实际变量,而不是返回数组的函数,因为只有实际变量可以通过引用传递。

PHP抱怨是因为end()期望引用它想要更改的东西(只能是变量)。然而,你可以直接将explode()的结果传递给end(),而不需要先将它保存到一个变量中。当explode()返回你的值时,它只存在于内存中,没有变量指向它。不能创建对不存在的东西(或内存中未知的东西)的引用。

或者换句话说:PHP不知道你给他的值是直接的值还是指向值的指针(指针也是一个变量(整数),它存储了内存的偏移量,也就是实际值所在的位置)。PHP希望这里总是有一个指针(引用)。

但是因为这在PHP 7中仍然只是一个通知(甚至没有被弃用),你可以保存忽略通知并使用忽略操作符,而不是完全取消激活通知的错误报告:

$file_extension = @end(explode('.', $file_name));

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

首先,您必须像这样将值存储在变量中

$value = explode("/", $string);

然后你可以使用end函数从这样的数组中获取最后一个索引

echo end($value);

我希望这对你有用。

由于它在超过10年的时间里升起了一个标志,但工作得很好,并返回预期的值,所以一点臭嘴运营商是你所有人都在寻找的最好的坏习惯:

$file_extension = @end(explode('.', $file_name));
但是警告,不要在循环中使用,因为会影响性能。 最新版本的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$$$
$$$$$$$$$$""""           ""$$$$$$$$$$$"
"$$$$$"                      ""$$$$""
$$$"                         $$$$"

答案在别处给出了,

$tmp = explode('.', $fileName);
$file_extension = end($tmp);

是正确有效的。它能完成你想要做的事情。

为什么?

end()函数并不完全像你想象的那样。这与PHP array数据结构的工作方式有关。你通常不会看到它,但PHP中的数组包含一个指向当前元素,的指针,用于迭代(如foreach)。

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

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

简单地在你正在寻找的变量创建数组中设置explode()的输出。创建的数组有一个当前元素指针。现在,世界又恢复了正常。

那么括号呢?

这不是一个bug。再说一次,这是语言要求。

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

这是另一个正确有效的解。这也许是一个更好的解决方案,因为它占用更少的空间。优秀的审查人员或维护者在看到额外的括号时应该明白您要做什么。

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

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

我将只使用@前缀

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

有很多原因。一个非常大的错误是你试图抑制一个特定的错误条件(一个你已经创建的错误),但是错误抑制前缀抑制了所有错误。

在这种情况下,您可能会侥幸逃脱。然而,养成坏的编程习惯就是作弊,而且很可能导致你在未来作弊次数更多、更大。你将为糟糕的代码负责。但我不是密码警察,这是你的密码。它是有效的,因为它解决了问题。

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

做什么@ryeguy建议。不要使用字符串操作来解决平台已经为您解决的定义良好的问题。使用pathinfo()

这有一个额外的好处,它实际上是您想要的,即查找文件名的扩展名。有一个微妙的区别。

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

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