Злоключение upload space php. Пример реализации загрузки картинок на сервер

Данная возможность позволяет загружать как текстовые, так и бинарные файлы. С помощью PHP-функций аутентификации и работы с файлами вы имеете полный контроль над тем, кому разрешено загружать файлы и что делать с файлом после его загрузки.

PHP способен получать загруженные файлы из любого браузера, совместимого со стандартом RFC-1867.

Также следует заметить, что PHP поддерживает загрузку файлов методом PUT, который используется в клиентах Netscape Composer и W3C Amaya . Для получения более детальной документации обратитесь к разделу поддержка метода PUT .

Пример #1 Форма для загрузки файлов

Страница для загрузки файлов может быть реализована при помощи специальной формы, которая выглядит примерно так:

Отправить этот файл:

В приведенном выше примере __URL__ необходимо заменить ссылкой на PHP-скрипт.

Скрытое поле MAX_FILE_SIZE (значение необходимо указывать в байтах) должно предшествовать полю для выбора файла, и его значение является максимально допустимым размером принимаемого файла в PHP. Рекомендуется всегда использовать эту переменную, так как она предотвращает тревожное ожидание пользователей при передаче огромных файлов, только для того, чтобы узнать, что файл слишком большой и передача фактически не состоялась. Имейте в виду, что обойти это ограничение на стороне браузера достаточно просто, следовательно, вы не должны полагаться на то, что все файлы большего размера будут блокированы при помощи этой возможности. Это по большей части удобная возможность для пользователей клиентской части вашего приложения. Однако настройки PHP (на сервере) касательно максимального размера обойти невозможно.

Замечание :

Также следует убедиться, что форма загрузки имеет атрибут enctype="multipart/form-data" , в противном случае загрузка файлов на сервер не произойдет.

Оригинальное имя файла на компьютере клиента.

$_FILES["userfile"]["type"]

Mime-тип файла, в случае, если браузер предоставил такую информацию. В качестве примера можно привести "image/gif" . Этот mime-тип не проверяется на стороне PHP, так что не полагайтесь на его значение без проверки.

$_FILES["userfile"]["size"]

Размер в байтах принятого файла.

$_FILES["userfile"]["tmp_name"]

Временное имя, с которым принятый файл был сохранен на сервере.

$_FILES["userfile"]["error"]

По окончанию работы скрипта, если загруженный файл не был переименован или перемещен, он будет автоматически удален из временной папки.

Изображения:

foreach ($_FILES [ "pictures" ][ "error" ] as $key => $error ) {
if ($error == UPLOAD_ERR_OK ) {
$tmp_name = $_FILES [ "pictures" ][ "tmp_name" ][ $key ];
// basename() может спасти от атак на файловую систему;
// может понадобиться дополнительная проверка/очистка имени файла
$name = basename ($_FILES [ "pictures" ][ "name" ][ $key ]);
move_uploaded_file ($tmp_name , "data/ $name " );
}
}
?>

Полоса прогресса загрузки файлов может быть реализована с помощью "отслеживания прогресса загрузки файлов с помощью сессий ".

Use Psr \ Http \ Message \ UploadedFileInterface ;
use Zend \ Diactoros \ ServerRequestFactory ;

$request = ServerRequestFactory :: fromGlobals ();

if ($request -> getMethod () !== "POST" ) {
http_response_code (405 );
exit("Use POST method." );
}

$uploaded_files = $request -> getUploadedFiles ();

if (
!isset($uploaded_files [ "files" ][ "x" ][ "y" ][ "z" ]) ||
! $uploaded_files [ "files" ][ "x" ][ "y" ][ "z" ] instanceof UploadedFileInterface
) {
http_response_code (400 );
exit("Invalid request body." );
}

$file = $uploaded_files [ "files" ][ "x" ][ "y" ][ "z" ];

if ($file -> getError () !== UPLOAD_ERR_OK ) {
);
}

$file -> moveTo ("/path/to/new/file" );

?>

10 years ago

I think the way an array of attachments works is kind of cumbersome. Usually the PHP guys are right on the money, but this is just counter-intuitive. It should have been more like:

Array
=> Array
=> facepalm.jpg
=> image/jpeg
=> /tmp/phpn3FmFr
=> 0
=> 15476
)

=> Array
=>
=>
=>
=> 4
=>
)

and not this
Array
=> Array
=> facepalm.jpg
=>
)

=> Array
=> image/jpeg
=>
)

=> Array
=> /tmp/phpn3FmFr
=>
)

=> Array
=> 0
=> 4
)

=> Array
=> 15476
=> 0
)

Anyways, here is a fuller example than the sparce one in the documentation above:

foreach ($_FILES [ "attachment" ][ "error" ] as $key => $error )
{
$tmp_name = $_FILES [ "attachment" ][ "tmp_name" ][ $key ];
if (! $tmp_name ) continue;

$name = basename ($_FILES [ "attachment" ][ "name" ][ $key ]);

If ($error == UPLOAD_ERR_OK )
{
if (move_uploaded_file ($tmp_name , "/tmp/" . $name ))
$uploaded_array .= "Uploaded file "" . $name . "".
\n" ;
else
$errormsg .= "Could not move uploaded file "" . $tmp_name . "" to "" . $name . ""
\n" ;
}
else $errormsg .= "Upload error. [" . $error . "] on file "" . $name . ""
\n" ;
}
?>

3 years ago

The documentation doesn"t have any details about how the HTML array feature formats the $_FILES array.

Example $_FILES array:

For single file -

Array
=> Array
=> sample-file.doc
=> application/msword
=> /tmp/path/phpVGCDAJ
=> 0
=> 0
)

Multi-files with HTML array feature -

Array
=> Array
=> Array
=> sample-file.doc
=> sample-file.doc
)

=> Array
=> application/msword
=> application/msword
)

=> Array
=> /tmp/path/phpVGCDAJ
=> /tmp/path/phpVGCDAJ
)

=> Array
=> 0
=> 0
)

=> Array
=> 0
=> 0
)

The problem occurs when you have a form that uses both single file and HTML array feature. The array isn"t normalized and tends to make coding for it really sloppy. I have included a nice method to normalize the $_FILES array.

Function normalize_files_array ($files = ) {

$normalized_array = ;

Foreach($files as $index => $file ) {

If (! is_array ($file [ "name" ])) {
$normalized_array [ $index ] = $file ;
continue;
}

Foreach($file [ "name" ] as $idx => $name ) {
$normalized_array [ $index ][ $idx ] = [
"name" => $name ,
"type" => $file [ "type" ][ $idx ],
"tmp_name" => $file [ "tmp_name" ][ $idx ],
"error" => $file [ "error" ][ $idx ],
"size" => $file [ "size" ][ $idx ]
];
}

Return $normalized_array ;

?>

The following is the output from the above method.

Array
=> Array
=> Array
=> sample-file.doc
=> application/msword
=> /tmp/path/phpVGCDAJ
=> 0
=> 0
)

=> Array
=> Array
=> sample-file.doc
=> application/msword
=> /tmp/path/phpVGCDAJ
=> 0
=> 0
)

=> Array
=> sample-file.doc
=> application/msword
=> /tmp/path/phpVGCDAJ
=> 0
=> 0
)

10 years ago

Also note that since MAX_FILE_SIZE hidden field is supplied by the browser doing the submitting, it is easily overridden from the clients" side. You should always perform your own examination and error checking of the file after it reaches you, instead of relying on information submitted by the client. This includes checks for file size (always check the length of the actual data versus the reported file size) as well as file type (the MIME type submitted by the browser can be inaccurate at best, and intentionally set to an incorrect value at worst).

3 years ago

For clarity; the reason you would NOT want to replace the example script with
$uploaddir = "./";
is because if you have no coded file constraints a nerd could upload a php script with the same name of one of your scripts in the scripts directory.

Given the right settings and permissions php-cgi is capable of replacing even php files.

Imagine if it replaced the upload post processor file itself. The next "upload" could lead to some easy exploits.

Even when replacements are not possible; uploading an .htaccess file could cause some problems, especially if it is sent after the nerd throws in a devious script to use htaccess to redirect to his upload.

There are probably more ways of exploiting it. Don"t let the nerds get you.

More sensible to use a fresh directory for uploads with some form of unique naming algorithm; maybe even a cron job for sanitizing the directory so older files do not linger for too long.

2 years ago

I have found it useful to re-order the multidimensional $_FILES array into a more intuitive format, as proposed by many other developers already.

Unfortunately, most of the proposed functions are not able to re-order the $_FILES array when it has more than 1 additional dimension.

Therefore, I would like to contribute the function below, which is capable of meeting the aforementioned requirement:

function get_fixed_files () {
$function = function($files , $fixed_files = array(), $path = array()) use (& $function ) {
foreach ($files as $key => $value ) {
$temp = $path ;
$temp = $key ;

If (is_array ($value )) {
$fixed_files = $function ($value , $fixed_files , $temp );
} else {
$next = array_splice ($temp , 1 , 1 );
$temp = array_merge ($temp , $next );

$new = & $fixed_files ;

Foreach ($temp as $key ) {
$new = & $new [ $key ];
}

$new = $value ;
}
}

Return $fixed_files ;
};

Return $function ($_FILES );
}
?>

Side note: the unnamed function within the function is used to avoid confusion regarding the arguments necessary for the recursion within the function, for example when viewing the function in an IDE.

Sorry... I can"t deal with all the SPAM so until I can find a better solution for the forums, I"m locking them down. For now please use awesome services like stackoverflow.com for community support. Thanks.

This forum is a community forum meant for users of the plugin to collaborate and help solve issues with implementation, etc. Unfortunately, as the creator of the plugin, I do not have much time to attend to every request here as this is only a side project and I must work a full-time job to provide for my family. This is how I keep the Flash version free and the HTML5 version low cost.

    I tried using the str_replace function in various places in the uploadify.php script, but not luck, it either continued uploading but did not change the spaces. Or it did not upload at all, although it looked like it did...

    How/where would this be implemented?

    Generally like this

    $str = " This is a test ";
    $count = 1;
    while($count)
    $str = str_replace(" ","", $str, $count);
    echo $str;
    ?>

    But maybe preg_replace is the better choice to clean everything bad from the filename

    $fname="Filen"ame 1\/23;"."""."la\l[a]*(/.jpg";
    $replace="_";
    $pattern="/[^a-zA-Z0-9\.]/";
    $fname=preg_replace($pattern,$replace,$fname);
    $fname=str_replace($replace,"",$fname);
    echo "
    ".$fname;

    This is my final php, which cleans the filename from spaces and other problematic chars,
    randomizes the filename afterwards and send it back to the backend:

    if (!empty($_FILES)) {
    $replace="_";
    $newfile= $_FILES["Filedata"]["name"] ;
    $ext = substr($newfile,-4); //comment out to not ramdomize the filename
    $pre = mb_split($ext,$newfile); //comment out to not ramdomize the filename
    $randoms = base_convert(mt_rand(0x1679616, 0x39AA3FF), 10, 36); //comment out to not ramdomize the filename
    $newfile = $pre.$randoms.$ext; //comment out to not ramdomize the filename
    $pattern="/[^a-zA-Z0-9\.]/";
    $newfile = preg_replace($pattern,$replace,$newfile);
    $tempFile = $_FILES["Filedata"]["tmp_name"];
    $targetPath = $_SERVER["DOCUMENT_ROOT"] . $_REQUEST["folder"] . "/";
    $targetFile = str_replace("//","/",$targetPath) . $newfile;
    move_uploaded_file($tempFile,$targetFile);
    chmod($targetFile,0777);
    echo $newfile; // Required to trigger onComplete function on Mac OSX (same for linux and windows as it seems)
    //and to send back the new filename to the "response" variable in uploadify
    }
    else { // Required to trigger onComplete function on Mac OSX
    echo "ERROR!";
    }
    ?>

    This is great, but I have noticed that now the Checking script doesn"t work quite right. check.php is looking to see if there are files with a different name, but the file we are uploading is going to have its name changed, how do account for that in the check script, another str_replace?

    How do we write that?

    Actually I don"t use the check script. In my case I have to upload hundreds of images and therefore I need to give the user the possibility to upload files, without worrying about the file name as he could want to upload a file named logo.gif for different datasets maybe ten times.
    That"s why I added a random part to the filename. The $randoms very likely never gives the same result twice.
    I think you can"t alter the check.php to follow the same rules, as the $randoms will be different even for the same finename, though

    I would be possible if you comment out the ramdomising part and only use the "cleaning" part.
    Then the output is predictible.
    I haven"t tested that, but it should be something like this:

    $fileArray = array();
    $replace="_";
    $pattern="/[^a-zA-Z0-9\.]/";
    foreach ($_POST as $key => $value) {
    if ($key != "folder") {
    $value= preg_replace($pattern,$replace,$value);
    if (file_exists($_SERVER["DOCUMENT_ROOT"] . $_POST["folder"] . "/" . $value)) {
    $fileArray[$key] = $value;
    }
    }
    }
    echo json_encode($fileArray);

    This is just a quick guess, try if it works.
    And comment out the lines in upload.php which are indicated.

У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!

Загрузка файлов на сервер

Краткий эксурс в upload

Что такое Upload files, или почему не работает
copy ("c:\images\sample.jpg", "http://mysite.ru/uploads/sample.jpg ")

Даже если у Вас в распоряжении всего один компьютер, на котором совмещен и сервер и рабочая станция, не стоит забывать о том, что php использует технологию клиент/сервер. Файл, который мы хотим загрузить, как правило, находится на машине клиента, т.е. пользователя, обыкновенного посетителя сайта. Место назначения - сервер. Для того чтобы совершить процесс передачи файла, нам понадобиться следующая форма:

Send this file:

При этом в поле action должен быть указан URL Вашего php-скрипта, который в дальнейшем будет заниматься обработкой загружаемых файлов. Скрытое поле MAX_FILE_SIZE должно предшествовать полю выбора файла, и содержать максимально допустимый размер файла в байтах. Его назначение - проверка размера файла еще до момента отправки файла на сервер. Это должно избавить пользователя от длительной и безрезультатной загрузки файла на сервер и образования лишнего трафика, но не стоит особо полагаться на это ограничение, так как его легко обойти.

Что происходит, когда пользователь выбрал файл на своем диске, и нажал на кнопку "Send file"? Браузер отсылает файл на сервер, где php-интерпретатор помещает его в свою временную директорию, присваивая ему случайное имя и выполняет скрипт, указанный в поле action.

Как должен выглядеть upload.php?

$uploaddir = "/var/www/uploads/"; if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $uploaddir. $_FILES["userfile"]["name"])) { print "File is valid, and was successfully uploaded."; } else { print "There some errors!"; }

При написании скрипта, возникает естественный вопрос: как получить информацию о загруженном файле и достучаться до самого файла. Если Вы используете PHP версии 4.1.0 и старше, лучше всего будет обратиться к глобальному массиву $_FILES. Для каждого загруженного файла он содержит хеш-массив, со следующими данными:

  • $_FILES["userfile"]["name"] - оригинальное имя файла, такое, каким его видел пользователь, выбирая файл;
  • $_FILES["userfile"]["type"] - mime/type файла, к примеру, может быть image/gif; это поле полезно сохранить, если Вы хотите предоставлять интерфейс для скачивания загруженных файлов;
  • $_FILES["userfile"]["size"] - размер загруженного файла;
  • $_FILES["userfile"]["tmp_name"] - полный путь к временному файлу на диске;
  • $_FILES["userfile"]["error"] - Начиная с версии 4.2.0, содержит код ошибки, который равен 0, если операция прошла успешно.

Для PHP версии ниже 4.1.0 этот массив называется $HTTP_POST_FILES. Не стоит забывать, что в отличие от $_FILES этот массив не является суперглобальным и при обращении к нему, к примеру, из функции, необходимо явно указывать global $HTTP_POST_FILES;

Если в настройках Вашего сервера register_globals=on, будут созданы дополнительные переменные вида $userfile_name, $userfile_type, $userfile_size… Учитывая, что, начиная с версии 4.2.0, в настройках по умолчанию register_globals=off использования этих переменных не рекомендовано, даже если они определены. Лучший способ получения информации о загружаемых файлах - использовать массив $_FILES.

Для работы с загруженными файлами лучше всего использовать встроенные функции is_uploaded_file() и move_uploaded_file() , которые проверяют, был ли загружен файл, и помещают его в указанную папку соответственно. Более детальную информацию Вы можете найти на страницах руководства. Не стоит изобретать велосипед и работать самому с временными файлами, копировать их, удалять. Это уже сделано до Вас и для Вас.

Настройка сервера

Я все сделал правильно, но у меня что-то не работает. Может, у меня неправильно сконфигурирован сервер?

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

В файле php.ini:

  • Если Вы хотите узнать, где расположен Ваш php.ini, выполните
  • file_uploads - возможность запретить или разрешить загрузку файлов в целом. По умолчанию On.
  • upload_max_filesize - максимальный размер файла, который может быть загружен. Если Вам необходимо работать с большими файлами, измените эту настройку. По умолчанию 2М. Не забудьте изменить post_max_size.
  • post_max_size - общее ограничение сверху на размер данных, передаваемых в POST запросе. Если Вам необходимо работать с большими файлами, или передавать несколько файлов одновременно, измените эту настройку. Значение по умолчанию 8М.
  • upload_tmp_dir - временная директория на сервере, в которую будут помещаться все загружаемые файлы. Проверьте, какие на нее выставлены права(если на данном этапе у Вас возникли сложности, смотрите пояснения в конце статьи). Такая директория должна существовать и у пользователя, под которым выполняется Apache, также должны быть права на запись в эту директорию. Если Вы работаете с включенным ограничением open_basedir - то временный каталог должен находиться внутри. Вам не нужно заботиться о ее чистке или об уникальности имен, PHP решает эту проблему за Вас.

В файле httpd.conf :

  • Прежде всего, убедитесь, что Вы используете веб-сервер Apache 1.3 (последняя версия на момент написания статьи - 1.3.27). Если Вы используете Apache 2.0, Вам следует прочитать следующий отрывок из документации:

    Do not use Apache 2.0 and PHP in a production environment neither on Unix nor on Windows.

  • Если Вы получили сообщение "POST Method Not Allowed", это означает, что надо искать что-то похожее на следующие директивы, и использовать ключевое слово Allow: Order allow,deny Allow from all
  • Проблемы с загрузкой бинарных файлов - классический вопрос "почему бьются файлы при upload". Вот способ решения, предложенный Димой Бородином (http://php.spb.ru): В директории, где лежит скрипт, делаем файл .htaccess , в котором пишем: CharsetDisable On В файл httpd.conf дописать строки: CharsetRecodeMultipartForms Off

Небольшие пояснения, к этому рецепту: вышеописанная проблема, когда загруженные на сервер архивы не распаковываются и картинки не отображаются, может возникать из-за того, что используется веб-сервер Russian Apache. Директива CharsetDisable отключает модуль charset-processing module, т.е. никакой перекодировки при скачивании файлов, находящихся в данной папке, происходить не будет. Директива CharsetRecodeMultipartForms выключает перекодировку данных, переданных методом POST с заголовком Content-Type: multipart/form-data. Т.е. двоичные данные, переданные с такой настройкой, будут оставлены в первоначальном виде, а все остальное наполнение сайта будет перекодировано согласно текущим настройкам сервера.

Но при этом могут возникнуть осложнения: будьте готовы к тому, что в некоторых случаях текстовые части запросов вам придется перекодировать самостоятельно. Вот что по этому поводу говорится в документации:

Используйте директиву CharsetRecodeMultipartForms, которая появилась в PL23, но при этом вам все-равно придется перекодировать вручную текстовые части запросов. Для этого можно использовать Russian Apache API, доступное в других модулях или Russian Apache Perl API, доступное из mod_perl.

Один из примеров определения кодировки вы можете найти тут: http://tony2001.phpclub.net/detect_charset/detect.phps

Самая свежая документация по Russian Apache находится на его официальном сайте: http://apache.lexa.ru/.

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

Также возможна настройка параметров Apach с помощью.htaccess:

Php_value upload_max_filesize 50M php_value post_max_size 50M

Дополнительные возможности

Загрузка нескольких файлов одновременно

Пример формы загрузки нескольких файлов:

Send these files:


И не забудьте увеличить post_max_size , если предполагается много файлов

Автоматическая загрузка файлов на сервер

Не стоит забывать, что файлы на диске пользователя - конфиденциальная информация, к которой ни JavaScript, ни уж тем более PHP не имеют ни малейшего отношения. До тех пор, пока пользователь сам не выбрал файл при помощи ни о какой работе с ним не может идти и речи. И не забывайте, что у данного поля ввода атрибут value защищен от записи.

Хранение файлов в базе данных mySQL

Если Вы собрались хранить загружаемы файлы в базе данных, Вам необходимо помнить следующие моменты:

  • Необходимо использовать поле типа BLOB
  • Перед тем, как класть в базу, не забыть применить к строке mysql_escape_string()
  • При отображении файла необходимо указывать заголовок content/type

Помните, что скрипт отображающий ваш HTML никак не связан со скриптом, который должен выводить изображение. Это должны быть два различные приложения.

Хранение картинок в базе не является хорошем стилем. Гораздо удобней хранить в базе лишь пути к файлам изображений.

Получение свойств изображения.

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

Загрузка файлов, имеющих русско-язычное название

При загрузке на сервер файлов, необходимо проверять их оригинальные имена на предмет наличия "нестандартных" символов (к примеру русских букв). В случае их присутствия необходимо произвести замену. Оригинальное имя файла можно найти в переменной $_FILES["userfile"]["name"]. Как перекодировать русскоязычную строку в транслит можно можно найти в примерах PHP .

Отображения статуса загрузки (Progress bar)

Необходимо учитывать, что до полной загрузки файла, PHP не может оперировать ни размером файла, ни процентом его загрузки. Только когда файл уже находится на сервере PHP, то он получает возможность обращаться к информации. Если вам все-таки крайне необходимо реализовать такую возможность, воспользуйтесь Java-аплетом.

Права на файлы

Проблемы с правами на сервере (upload_tmp_dir)

В Unix-подобных операционных системах каждой папке, файлу, ссылке выставлены соответствие права доступа. Они могут выглядеть как rwx-rw-r- или же как число 754.

Доступность файла или каталога зависят от идентификатора пользователя и идентификатора группы, в которую он входит. Режим в целом описывается в терминах трех последовательностей, по три буквы в каждой:

Владелец Группа Прочие (u) (g) (o) rwx rwx rwx

Здесь владелец, члены группы и все прочие пользователи обладают правами чтения файла, записи в него и его выполнения. Права - любая осмысленная комбинация следующих букв:

r Право на чтение. (4)
w Право на запись. (2)
x Право на выполнение (поиск в каталоге). (1)

  • Установить владельцем каталога пользователя, с чьими привелегиями выполняется apache. Это можно узнать из файла httpd.conf или просмотрев список процессов на сервере. Права на каталог должны быть 700 (rwx------).
  • Независимо от того, кто является владельцем каталога, установить права 777 (rwxrwxrwx).

    Пример реализации загрузки картинок на сервер.

    $max_image_width = 380; $max_image_height = 600; $max_image_size = 64 * 1024; $valid_types = array("gif","jpg", "png", "jpeg"); if (isset($_FILES["userfile"])) { if (is_uploaded_file($_FILES["userfile"]["tmp_name"])) { $filename = $_FILES["userfile"]["tmp_name"]; $ext = substr($_FILES["userfile"]["name"], 1 + strrpos($_FILES["userfile"]["name"], ".")); if (filesize($filename) > $max_image_size) { echo "Error: File size > 64K."; } elseif (!in_array($ext, $valid_types)) { echo "Error: Invalid file type."; } else { $size = GetImageSize($filename); if (($size) && ($size < $max_image_width) && ($size < $max_image_height)) { if (@move_uploaded_file($filename, "/www/htdocs/upload/")) { echo "File successful uploaded."; } else { echo "Error: moving fie failed."; } } else { echo "Error: invalid image properties."; } } } else { echo "Error: empty file."; } } else { echo "
    Send this file:
    "; }

    Оригинал статьи находится на сайте PHP Club


    Как скачать файл с сервера?
  • Multipart-формы

    • Веб-итерфейсы почтовых сервисов, которые позволяют добавалять к письму приложение (attach), а для этого нужно сначала загрузить файл на сервер, и только после этого его можно добавлять к письму;
    • Интерактивные фотогалереи и фотоальбомы, которые не могут существовать без механизма загрузки файлов на сервер;
    • Порталы бесплатного програмного обеспечения, которые используют для обмена файлами различных программ, и.т.д.

    Загрузка файла на сервер осуществляется с помощью multipart -формы, в которой есть поле загрузки файла. В качестве параметра enctype указывается значение multipart/form-data :



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

    Multipart-формы обычно используют метод передачи POST. Как видно из предыдущего примера, данная форма имеет два поля:

    • Поле выбора файла для закачки ;
    • Поле указания имени файла, которое он должен будет иметь на сервере .

    Обработка multipart-форм

    Прежде, чем приступить к написанию скрипта обработки multipart-формы, нужно отредактировать файл конфигурации php.ini , чтобы разрешить загрузку файлов на сервер.

    Конфигурационный файл PHP php.ini имеет три параметра, связанные с загрузкой файлов на сервер:

    • file_uploads=On - разрешает загрузку файлов на сервер по протоколу HTTP;
    • upload_tmp_dir=/tmp - устанавливает каталог для временного хранения загруженных файлов;
    • upload_max_filesize=2M - устанавливает максимальный объем загружаемых файлов.

    Если ваш веб-сервер работает под управлением операционной системы Linux, то нужно перезапустить сервис:

    service httpd restart

    Как же PHP обрабатывает multipart-формы? Получив файл, он сохраняет его во временном каталоге upload_tmp_dir , имя файла выбирается случайным образом. Затем он создает четыре переменных суперглобального массива $_FILES . Этот массив содержит информацию о загруженном файле.

    Переменные, определенные для загруженных файлов, зависят от версии PHP и текущей конфигурации. Суперглобальный массив $_FILES доступен начиная с PHP 4.1.0. В случае, если конфигурационная директива register_globals установлена значением on , дополнительно будут объявлены переменные с соответствующими именами. Начиная с версии 4.2.0 значением по умолчанию для опции register_globals является off .

    Содержимое массива $_FILES для нашего примера приведено ниже. Обратите внимание, что здесь предполагается использование имени uploadfile для поля выбора файла, в соответствии с приведенной выше multipart-форме. Разумеется, имя поля может быть любым.

    • $_FILES["uploadfile"]["name"] - имя файла до его отправки на сервер, например, pict.gif;
    • $_FILES["uploadfile"]["size"] - размер принятого файла в байтах;
    • $_FILES["uploadfile"]["type"] - MIME-тип принятого файла (если браузер смог его определить), например: image/gif, image/png, image/jpeg, text/html;
    • (так мы назвали поле загрузки файла) - содержит имя файла во временном каталоге, например: /tmp/phpV3b3qY;
    • $_FILES["uploadfile"]["error"] - Код ошибки, которая может возникнуть при загрузке файла. Ключ ["error"] был добавлен в PHP 4.2.0. С соответствующими кодами ошибок вы можете ознакомиться

    После завершения работы скрипта, временный файл будет удален. Это означает, что мы должны его скопировать в другое место до завершения работы скрипта. То есть алгоритм работы сценария загрузки файла на сервер такой:

    Если кнопка "Submit" нажата, то файл уже будет загружен на сервер и его имя будут в переменной $_FILES["uploadfile"]["name"] . В этом случае скрипт должен сразу скопировать файл с именем $_FILES["uploadfile"]["tmp_name"] в какой-нибудь каталог (необходимы права на запись в этот каталог).

    Копирование файла производится функцией copy() :

    Используйте только функцию копирования copy() , а не перемещения, поскольку:

    • Временный файл будет удален автоматически;
    • Если временный каталог находится на другом носителе, будет выведено сообщение об ошибке.

    Предположим, нам нужно загрузить файл в каталог uploads , который находится в корневом каталоге веб-сервера (в каталоге DocumentRoot ).

    // На всякий случай создадим каталог. Если он уже создан,
    // сообщение об ошибки мы не увидим, поскольку воспользуемся оператором @:

    @mkdir("uploads", 0777);

    // Копируем файл из /tmp в uploads
    // Имя файла будет таким же, как и до отправки на сервер:

    Copy($_FILES["uploadfile"]["tmp_name"],"uploads/".basename($_FILES["uploadfile"]["name"]));

    В Linux все намного сложнее - нам нужно учитывать права доступа к каталогу uploads . Скорее всего в таком случае, функция mkdir() не сработает, так как у нас нет прав на запись в каталог DocumentRoot (обычно это /var/www/html или /home/httpd/html). Зарегистрируйтесь в системе как пользователь root , создайте каталог uploads и измените его владельца и права доступа следующим образом:

    // Создаем каталог uploads

    // Устанавливаем имя владельца apache и его группу - тоже apache:

    Chown apache:apache uploads

    // Разрешение записи всем (777) + установка закрепляющего бита (1):

    Chmod 1777 uploads

    Размер файла можно ограничить, при желании можно отредактировать файл .htaccess и ограничить доступ к каталогу uploads - указать или конкретных пользователей, которым можно обращаться к каталогу, или IP-адреса.

    Вот теперь можно загружать файлы на сервер.

    Пишем PHP скрипт загрузки файлов на сервер


    // Каталог, в который мы будем принимать файл:
    $ uploaddir = "./files/" ;
    $ uploadfile = $ uploaddir . basename ($ _FILES [ "uploadfile" ][ "name" ]);

    // Копируем файл из каталога для временного хранения файлов:
    if (copy ($ _FILES [ "uploadfile" ][ "tmp_name" ], $ uploadfile ))
    {
    echo "

    Файл успешно загружен на сервер

    " ;
    }
    else { echo "

    Ошибка! Не удалось загрузить файл на сервер!

    "
    ; exit ; }

    // Выводим информацию о загруженном файле:
    echo "

    Информация о загруженном на сервер файле:

    "
    ;
    echo "

    Оригинальное имя загруженного файла: " .$ _FILES [ "uploadfile" ][ "name" ]. "

    " ;
    echo "

    Mime-тип загруженного файла: " .$ _FILES [ "uploadfile" ][ "type" ]. "

    " ;
    echo "

    Размер загруженного файла в байтах: " .$ _FILES [ "uploadfile" ][ "size" ]. "

    " ;
    echo "

    Временное имя файла: " .$ _FILES [ "uploadfile" ][ "tmp_name" ]. "

    " ;

    ?>

    Загрузку нескольких файлов можно реализовать используя, например, различные значения name для тега input .

    Также предусмотрена возможность автоматического получения организованной в массив информации о нескольких одновременно загружаемых файлах. Для реализации такой возможности используйте тот же синтаксис отправки массива из HTML-формы, что и для множественных полей select и checkbox :


    Send these files:






    В случае, если такая форма была отправлена, массивы $_FILES["userfile"] , $_FILES["userfile"]["name"] , и $_FILES["userfile"]["size"] будут инициализированы (точно так же, как и $HTTP_POST_FILES для PHP 4.1.0 и более ранних версий). Если конфигурационная директива register_globals установлена значением on , также будут инициализированы сопутствующие глобальные переменные. Каждая из таких переменных будет представлять собой численно индексированный массив соответствующих значений для принятых файлов.

    Предположим, что были загружены файлы /home/test/some.html и /home/test/file.bin . В таком случае переменная $_FILES["userfile"]["name"] будет иметь значение some.html , а переменная $_FILES["userfile"]["name"] - значение file.bin . Аналогично, переменная $_FILES["userfile"]["size"] будет содержать размер файла some.html и так далее.

    Переменные $_FILES["userfile"]["name"] , $_FILES["userfile"]["tmp_name"] , $_FILES["userfile"]["size"] и $_FILES["userfile"]["type"] также будут инициализированы.

    Заключение:

    Как видите, организовать загрузку файлов на сервер не так сложно. Сложнее обеспечить необходимый уровень безопасности, так как загрузка файлов на сервер может использоваться злоумышленниками для атаки на сервер. О том, как обеспечить необходимый уровень безопасности, работая с Uploads , смотрите .



    <<< Назад Содержание Вперед >>>
    Есть еще вопросы или что-то непонятно - добро пожаловать на наш

    To allow users to upload data on to your website, you need to know the original format of the data and the desired format in which it will be available for downloading. You will have to finalize the usability and limits of viewing or downloading. As a webmaster, allocating space gives you an upload webspace to save files online of various sizes and formats. The online storing feature is a powerful tool for online file sharing, or if you want to store important files that are huge in size and portable, instead of using PHP code, you can set up your own custom upload space on your website.

    Intro

    These days many websites offer a function allowing the user to upload files to the site. This is particularly useful for sharing files over the internet or for storing backup copies of files.

    Is a website that provides FTP uploads. However, you can get a similar service without paying using a PHP code to set up your own custom upload space on your website.

    Solution

    This PHP code is available on the website File Thingie . The benefit of this program is that it allows you to upload multiple files at the same time, protect them with a password, rename, move or delete the files and edit your text in HTML.

    Implementation

    After downloading the file and unzipping it, there are some modifications that you should make to it.
    • Rename the PHP file ft2.php as index.php
    • Insert the new username and password after this line in the code: # Settings - Change as appropriate. See online documentation for explanations. #,
      • Define the new username and password as indicated below:
      • define("USERNAME", "my_username");
      • define("PASSWORD", "my_password");
    • Change the DIR declaration from define("DIR", "."); to define("DIR", "files");
    • You can also alter the storage capacity by changing define("MAXSIZE", 2000000); to define("MAXSIZE", 9999999);
    • Step 5: Finally, you can define the formats that can be uploaded where you see this code: define("FILETYPEBLACKLIST", "php phtml php3 php4 php5");
      • To add more file types you could replace it with this: define("FILETYPEBLACKLIST", "php phtml php3 php4 php5 mp3 doc xls");

    What to change on your website

    Once you have finished making changes, you should now create a directory to store the files on your website. Note that you should also create a subfolder that will contain the PHP file. You should, therefore, put the index.php file in this sub folder. All you have to do now is to go to http://yoursite.com/storage and insert your username and password to be able to access this space.

    Important notes

    Anyone can access the files you upload using File Thingie so do not use it for private material. The password is only for uploading.

    It is therefore not suitable for backing up certain data, but a useful file sharing tool..

    • Note: If the automatic indexing is disabled on your web server, by going http://yoursite.com/storage/files users will not see the file list.
    • You therefore have to create a page (eg index.html) with links to each file, or add a PHP file that lists the available documents.