Загрузка файла PHP с использованием суперглобального массива FILES - PullRequest
2 голосов
/ 07 мая 2010

Допустим, я настраиваю функцию загрузки для проекта. Я использую PHP5, и мне было интересно, если бы с помощью суперглобального массива $ _FILES, я мог бы получить доступ к ключу массива "tmp_name", который является временным путем и именем загружаемого файла для отображения предварительного просмотра изображения перед перемещением в папку «uploads» на сервере.

Я имел в виду что-то вроде этого: Используйте jQuery, чтобы определить, когда изменяется входной файл «file» (когда пользователь выбирает файл изображения), затем выполните ajax-вызов для загрузки файла, который переместит его во временную папку, даже прежде чем я использую «move_uploaded_file». Если бы я мог как-то получить доступ к ключу массива «tmp_name», я мог бы, вероятно, поместить его в тег «img» для отображения предварительного просмотра. Позже переместите файл в его окончательное местоположение при нажатии кнопки отправки.

Я не прошу каких-либо примеров кода или чего-либо еще, поскольку я был бы рад сделать это самостоятельно, я просто хочу выяснить, есть ли доступ к этому ключу массива каким-либо образом.

Ответы [ 2 ]

2 голосов
/ 07 мая 2010

Чтобы использовать их в теге изображения, вам нужно будет хранить соответствующие временные файлы где-то внутри корневого веб-каталога, поскольку они часто находятся где-то в файловой системе, вне корневого веб-каталога, и вы не хотите выводить их.этот путь к пользователю, так как он будет бесполезным (тег img не может быть сопоставлен с этим путем) и плохой безопасностью (вы выдаете информацию о вашей файловой системе).

Вы можете сделать это a) копирование каждого файла в определенное место в веб-корне (дорого) или b) изменение конфигурации для размещения всех загруженных файлов во временной папке внутри корневого веб-каталога (большая безопасностьпоследствия).

Помните о безопасности, планируя это ...

Просто будьте осторожны с безопасностью других временных файлов.Убедитесь, что в корне сети хранятся только те, которые относятся к этой части этого приложения.Вам не нужно обнаруживать, что вы предоставили достаточно информации, чтобы кто-то мог рассчитать доступ к другим файлам и что-то вроде взлома данных между пользователями, потому что другие загруженные данные доступны (даже в течение очень короткого времени) в вашей сетиroot.

Это может быть лучший способ:

Возможно, лучшим решением было бы получить временное имя, каким-то образом его запутать, добавить к пути, который будетпередайте его в файл привратника и отправьте вместо этого.

Что-то вроде

/images/path/to/gatekeeper.png?name=[obfuscated file name here]

Затем вы можете использовать /images/path/to/.htaccess, чтобы убедиться, что привратник обрабатывается как файл php, а не как файл png, добавив:

<Files gatekeeper.png>
    ForceType application/x-httpd-php
</Files>

Теперь привратник может не запутывать имя файла, извлекать его из временного пути и отправлять, не раскрывая ничего пользователю, не перемещая фактический файл или не изменяя конфигурацию.

Просто убедитесь, что вы не ожидаете, что файл сохранится, потому что, если они обновятся позже, и файл будет перемещен (почти наверняка будет), это будет просто испорченное изображение.Может быть, проверить существование с привратником и дать им изображение «Файл больше не доступен», если оно не найдено.Вы также можете принудительно отправлять только файлы изображений или другие проблемы с безопасностью на уровне привратника.

Вы можете сделать привратник следующим образом (набранный из памяти, вероятно, не запустится и не будет обрабатывать ошибки,пропущенные значения и т. д., но вы должны использовать это как отправную точку ...):

<?php
// This is all inside gatekeeper.png, which is just a .php file with a .png extension
// It's not very good code, just an example to point you in the right direction.

// Specify this will be a png file for the browser...
header("content-type: image/png");


//Read the file name from the $_GET and un-obfuscate it.
$file = "/path/to/temp/directory/outside/file/root/that/we/hopefully/have/access/to/";
$file .= $_GET["name"];


// Check that the file exists, and send a "not found" image if not.
// http://us.php.net/manual/en/function.file-exists.php
if (!file_exists($file)) {etc...}


// Read the image file, send it to the user, and close it...
// http://us.php.net/manual/en/function.imagepng.php
$im = imagecreatefrompng($file);
imagepng($im);
imagedestroy($im);


die();

?>
2 голосов
/ 07 мая 2010

Да, вы можете.

В PHP, когда пользователь отправляет форму с суперглобальным символом $ _FILES, заполняется полезной информацией о загруженном файле. Внутри вы найдете оригинальное имя каждого загруженного файла, тип содержимого, место временной загрузки на сервер, код ошибки и размер в байтах.

Взято из Исправление суперглобального $ _FILES

Вот пример print_r вывода, взятого с сайта массива $_FILES,

Array
 (
    [download_zip] => Array
     (
        [name] => dummy.txt
        [type] => text/plain
        [tmp_name] => /Applications/MAMP/tmp/php/php5TBPsw
        [error] => 0
        [size] => 1
     )

    [download_screenshot] => Array
     (
        [name] => dummy.txt
        [type] => text/plain
        [tmp_name] => /Applications/MAMP/tmp/php/phpTncd39
        [error] => 0
        [size] => 1
     ) 
)

Вы можете получить доступ к tmp_name, используя синтаксис $files_array['download_zip']['tmp_name'].

Обновление:

$path = $files_array['download_zip']['tmp_name'];
echo "<img src='$path'>"; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...