Transcript Part 1

http://www.flickr.com/photos/torkildr/3462607995/

FILE UPLOAD

Overview of file upload

• File upload is where a file is copied from the client to the server – Useful for uploading • Images • PDFs • • Videos Audio • Pretty much anything that can't be copied-and-pasted into a TEXTAREA

Process of file upload

Browser Server Storage location Fill form with input type=file Encode & upload Access file Store file some place safe, such as on the file sys or in a db

Setting up the form correctly

Choose file:

Receiving the file on the server side

if ($_SERVER['REQUEST_METHOD'] == "POST") { $errorinfo = $_FILES["myfile"]["error"]; $filename = $_FILES["myfile"]["name"]; $tmpfile = $_FILES["myfile"]["tmp_name"]; $filesize = $_FILES["myfile"]["size"]; $filetype = $_FILES["myfile"]["type"]; if ($filetype == "image/jpeg" && $filesize < 1048576) move_uploaded_file($tmpfile, "mydirectory/" . $filename); else echo "Only jpegs under 1MB are invited to this party."; } ?>

Checking that the file is legit

• Be sure to validate the inputs – Otherwise, people could be uploading stuff that you really don't want on your server • Such as .exe, .dll or .so files containing viruses • Or enormous files that waste your server space and maybe your bandwidth – Or they could be uploading bad data that will break your web app when you use data later • doesn't look too good

Storing a file in the database

• • A file is an array of bytes, so storing it in the database is very similar to storing a string But you need to declare the column as a blob – http://dev.mysql.com/doc/refman/5.0/en/blob.html

– mediumblob is usually good (around 16MB)

Lengthy example Part 1 – Storing files away

Choose file:

ini_set('display_errors', 'On'); $mysql_handle = mysql_connect('oniddb.cws.oregonstate.edu', 'scaffidc-db', 'HqLLlDeEifohqWhF') or die("Error connecting to database server"); mysql_select_db('scaffidc-db', $mysql_handle) or die("Error selecting database: $dbname"); if ($_SERVER['REQUEST_METHOD'] == "POST") { $errorinfo = $_FILES["myfile"]["error"]; $filename = $_FILES["myfile"]["name"]; $tmpfile = $_FILES["myfile"]["tmp_name"]; $filesize = $_FILES["myfile"]["size"]; $filetype = $_FILES["myfile"]["type"]; mysql_query('drop table myuploads'); mysql_query('create table myuploads(fid integer not null auto_increment, filename varchar(256), filedata mediumblob, primary key(fid))'); } if ($filetype == "image/jpeg" && $filesize < 1048576) { $filedata = file_get_contents($tmpfile); mysql_query("insert into myuploads(filename, filedata) values (" ."'".mysql_real_escape_string($filename)."'" .",'".mysql_real_escape_string($filedata)."')"); } else { echo "Only jpegs under 1MB are invited to this party."; }

Lengthy example Part 2 – Listing the files

$rs = mysql_query("select fid, filename from myuploads"); $nrows=mysql_numrows($rs); echo "Files

"; for ($i = 0; $i < $nrows; $i++) { echo ""; echo ""; echo ""; } echo '
"; echo htmlspecialchars(mysql_result($rs,$i,"filename"))."
'; echo mysql_error(); mysql_close($mysql_handle); ?>

Lengthy example Part 3 – Showing file contents

ini_set('display_errors', 'On'); $mysql_handle = mysql_connect('oniddb.cws.oregonstate.edu', 'scaffidc-db', 'HqLLlDeEifohqWhF') or die("Error connecting to database server"); mysql_select_db('scaffidc-db', $mysql_handle) or die("Error selecting database: $dbname"); $fid = array_key_exists("id", $_REQUEST) ? $_REQUEST["id"] : 0; if ($fid <= 0) echo ""; else if (!preg_match('/^[0-9]+$/', $fid)) echo "Invalid fid"; else { $rs = mysql_query("select filedata from myuploads where fid = ".$fid); header('Content-type: image/jpeg'); if (mysql_numrows($rs) == 1) echo mysql_result($rs,0,"filedata"); } mysql_close($mysql_handle); ?>

Let's dig into what is really happening

• File upload differs from a typical http POST in the way that data sent to data are encoded – Differences in the "content type" – Differences in how the content is represented • And also when the server sends data back – Differences in the content type

Example of a simple GET request

GET /list.php?category=apple HTTP/1.1 Host: www.myfancypantswebsite.com

User-Agent: Safari/4.0

Example of a simple POST operation

POST /login.php HTTP/1.1 Host: www.myfancypantswebsite.com

User-Agent: Safari/4.0 Content-Length: 26 Content-Type: application/x-www-form-urlencoded usernm=cs&password=mypass

Example of a simple POST file upload

POST /filehandler.php HTTP/1.0

Host: www.myfancypantswebsite.com

User-Agent: Safari/4.0 Content-Type: multipart/form-data; boundary=BbC15x --BbC15x Content-Disposition: form-data; name="someregularparameter" OSU --BbC15x Content-Disposition: form-data; name="files" Content-Type: multipart/mixed; boundary=CcD15y --CcD15y Content-Disposition: file; filename="somefile.jpeg" Content-Type: image/jpeg dGhlIHRlbnVyZSBzeXN0ZW0gaXMgcmVhbGx5IGphY2tlZA== --CcD15y Content-Disposition: file; filename="anotherfile.gif" Content-Type: image/gif Content-Transfer-Encoding: base64 dGVhY2hpbmcgaXMgdW5kZXJyYXRlZA== --CcD15y- --BbC15x--

Content type (MIME type) tells how to interpret data

• • • As some sort of text – text/plain, text/html, text/javascript, text/css As some sort of image – image/jpeg, image/gif, image/png As some sort of multi-part package – multipart/form-data; boundary=BbC15x For others, see http://www.iana.org/assignments/media-types/index.html

Detailed breakdown of file upload

Browser Web server Your PHP program Storage location Fill form with input type=file Multipart encode; upload Read content type; Decode upload; Store files to temp Pass data to your PHP Store data to some safe place

Detailed breakdown of sending data back

Browser Web server Your PHP program Storage location Click a link GET with parameter Read parameters Pass data to your PHP Pass content type & data Interpret data Show to user Pass content type & data Retrieve requested data

Making file upload look slick

• For a great "How-To" topic, search the web for one of the many slick AJAX file upload libraries – HINT: The file can be sent via AJAX; full page refresh isn't needed!