FILE UPLOAD http://www.flickr.com/photos/torkildr/3462607995/ 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 Fill form with input type=file Server Storage location Encode & upload Access file Store file some place safe, such as on the file sys or in a db Setting up the form correctly <form method="post" action="filetest.php" enctype="multipart/form-data"> Choose file: <input type="file" name="myfile"> <input type="submit" value="OK"> </form> Receiving the file on the server side <?php 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 • <img src="blahblah.exe"> 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 <form method="post" action="filetest.php" enctype="multipart/form-data"> Choose file: <input type="file" name="myfile"> <input type="submit" value="OK"> </form> <?php 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<table>"; for ($i = 0; $i < $nrows; $i++) { echo "<tr>"; echo "<td><a href='fileview.php?id=".htmlspecialchars(mysql_result($rs,$i,"fid"))."'>"; echo htmlspecialchars(mysql_result($rs,$i,"filename"))."</a></td>"; echo "</tr>"; } echo '</table>'; echo mysql_error(); ?> mysql_close($mysql_handle); Lengthy example Part 3 – Showing file contents <?php 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 Fill form with input type=file Web server Your PHP program Storage location 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!