Тільки змінні повинні передаватися за посиланням


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

Будь-які ідеї? Через 2 дні все-таки застряг.


2
Краще пояснення причини vijayasankarn.wordpress.com/2017/08/28/…
Анант

Відповіді:


515

Призначте результат explodeзмінної та передайте цю змінну end:

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

Проблема полягає в тому, що endпотрібна посилання, оскільки вона змінює внутрішнє представлення масиву (тобто робить поточний елемент, який вказує на останній елемент).

Результат explode('.', $file_name)не може бути перетворений на посилання. Це обмеження в мові PHP, яке, ймовірно, існує з простоти.


12
Велике спасибі Вирішив мою проблему.
Френк Нвоко

1
@Oswald, ми можемо вимкнути попередження за допомогою error_reporting. Чи безпечно це робити?
Pacerier

9
Це безпечно вимкнути error_reporting. Сліпо ігнорувати помилки не безпечно. Вимкнення error_reporting- це головний крок до сліпого ігнорування помилок. У виробничому середовищі вимкніть display_errorsзамість цього і запишіть помилки у файл журналу.
Освальд

Не працює. Відповідь нижче - подвійні дужки - працює.
ббе

Дякую, врятуй мені багато часу!
симон

52

Правильне використання Php 7:

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

echo $fileExtension;
// jpg

3
Дивно. Це працює, але як? Чи придушує це попередження, подібне до того, що @робить префікс?
Найджел Олдертон

6
То чому додавання додаткової дужки видаляє помилку?
Найджел Олдертон

8
Я дослідив цю химерність і, здається, це помилка? з аналізатором php, де подвійна дужка "(())" призводить до перетворення посилання на звичайне значення. Детальніше за цим посиланням .
Callistino

26
Мені це подобається .., але мені це одночасно не подобається. Дякую за те, що ви зруйнували мій день :-)
billynoah

4
У php7 попередження все одно буде видано. php.net/manual/en / ...
Kosta

49

Всі інші вам уже дали причину помилки, але ось найкращий спосіб зробити те, що ви хочете зробити: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);


1
Я згоден. Немає сенсу використовувати маніпуляції з рядками для розбору шляхів до файлів, коли у вас є відповідні API.
gd1

18

збережіть масив від explode () до змінної, а потім викликайте end () на цій змінній:

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

btw: Я використовую цей код, щоб отримати розширення файлу:

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

де strrchrвитягує рядок після останнього .і substrобрізає.


9

Спробуйте це:

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

Причина в тому, що аргумент для endпередається через посилання, оскількиend модифікує масив, просуваючи його внутрішній покажчик до кінцевого елемента. Якщо ви не передаєте змінну в, немає нічого, на що слід посилатися.

Дивіться endв посібнику PHP для отримання додаткової інформації.


8

PHP скаржиться, тому що end()очікує посилання на щось, що хоче змінити (що може бути лише змінною). Однак ви передаєте результат explode()безпосередньо, end()не зберігаючи його в першу чергу. У момент, колиexplode() повертає ваше значення, воно існує лише в пам’яті і змінної не вказує на нього. Ви не можете створити посилання на щось (або на щось невідоме в пам'яті), що не існує.

Або іншими словами: PHP не знає, якщо значення, яке ви йому надаєте, є прямим значенням або просто вказівником на значення (покажчик - це також змінна (ціле число), яка зберігає зміщення пам'яті, де фактичне значення проживає). Тож PHP очікує, що тут вказівник (посилання) завжди.

Але оскільки це все ще є лише повідомленням (навіть не застарілим) у PHP 7, ви можете безпечно ігнорувати повідомлення та використовувати оператор ігнорування замість того, щоб повністю деактивувати повідомлення про помилки для повідомлень:

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

3
@OskarCalvo Це теж моя філософія. Але це не помилка - PHP трактує це як "повідомлення". І це було альтернативне «рішення» інших відповідей тут, про які ніхто безпосередньо не згадував. Кращим способом було б збереження значення explodeдо тимчасової змінної, як писали тут інші. Але ще раз: це не помилка, тому нормально використовувати цей оператор. PHP, як правило, погано справляється з помилками. Тому я б запропонував використовувати set_error_handlerі set_exception_handlerдля усунення помилок, і як найчистіше рішення.
майстер

4

Так само, як ви не можете відразу індексувати масив, так і на ньому не можна подзвонити. Спершу призначте його змінній, а потім завершіть виклик.

$basenameAndExtension = explode('.', $file_name);
$ext = end($basenameAndExtension);

4

end(...[explode('.', $file_name)])працює з PHP 5.6. Це зафіксовано в RFC, хоча не в самих документах PHP.


2

Оскільки він піднімає прапор понад 10 років, але він працює чудово і повертає очікуване значення, маленький оператор stfu - найкраща погана практика, яку ви шукаєте:

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

0

Офіційне керівництво PHP: end ()

Параметри

array

Масив. Цей масив передається за посиланням, оскільки він модифікується функцією. Це означає, що ви повинні передавати йому реальну змінну, а не функцію, що повертає масив, оскільки лише фактичні змінні можуть передаватися за посиланням.


3
Складіть цитату з офіційного посібника, не переписуйте своїми руками. Крім того, подумайте, щоб зробити свою відповідь кращою за існуючу.
Віктор Полевий

-1

По-перше, вам доведеться зберігати значення в такій змінній

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

Тоді ви можете використовувати функцію закінчення, щоб отримати останній індекс з такого масиву

echo end($value);

Сподіваюся, це спрацює для вас.


-3

$ file_extension = end (вибухнути ('.', $ file_name)); // ПОМИЛКА НА ЦЕЙ ЛІНІЇ

змінити цей рядок як,

$ file_extension = end ( (вибухнути ('.', $ file_name)) ); // немає помилок

Техніка проста, поставте ще одну дужку для вибуху,

(вибухнути ()) , то тільки він може виконувати незалежно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.