HTTP provides for uploading files, with the input type="file". You
need to specify the enctype for the form, use POST, and you may limit
the file
size. You may also include any other data you wish on the form, even
other files. This example is from the PHP documentation.
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="upload.php" method="POST">
<!-- MAX_FILE_SIZE must precede the file input field -->
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />
<!-- Name of input element determines name in $_FILES array -->
<br> Send this file: <input name="mugshot" type="file" />
<br>
<input type="submit" value="Send File" align="center" />
</form>
In PHP, the $_FILES array, indexed by the name(s) given in the form,
contains array(s) of information about each uploaded file. The upload
may fail for a number of reasons. The browser may prevent an overly
large upload, if it does not, PHP will. PHP puts the file in a
temporary location. You need to:
$file = $_FILES['mugshot'];
if ($file['size'] > 31000 || $file['size'] < 1000)
die ("File too large (or small)\n");
if ($file['error'] != UPLOAD_ERR_OK) die ("File upload failed");
if (!move_uploaded_file($file['tmp_name'],"upload/{$file['name']}"))
die ('Possible attack! File: ' . $file['name']."\n") ;
In the example, I have trusted the client to pick an appropriate
name, you may wish to generate your own name. There is a problem of
permission for apache to create a file. Either
chmod g+w upload
if (!is_uploaded_file($file['tmp_name'])
die ('Possible attack! File: ' . $file['name']."\n") ;
pg_query("begin"); // start transaction block, essential for LO
$oid = pg_lo_import($file['tmp_name']);
if ($oid==FALSE) die ("Import failed!");
$imagetype=$file['type'];
$res = pg_query_params("update students set mug=$1, type=$2 where linux=$3",
array($oid, $imagetype, $linux));
if (pg_affected_rows($res) < 1)
pg_lo_unlink($oid); // get rid of large object we can't store oid of
pg_query("commit");
Now, to retrieve the large object, let's suppose it is an image
file, we will need to write a script that will return the whole file,
with the content-type specified, this means sending a header, followed
by all of the large object. Fortunately, there are PHP functions to do
this easily. Possible problem: It was up to the original client to send
us the correct type.
<?php
$linux=$_GET['linux'];
$linux = pg_escape_string($linux); // double any quote that comes in before db use
$database = pg_connect('dbname=timetable host=localhost user=mickey password=MoUsE') or die('Connect failed');
pg_query($database, "begin");
$res = pg_query($database, "select mug, type from students where linux='$linux'");
$row = pg_fetch_row($res);
if (!$row) die("We can'f find you, $linux");
$image_oid = $row[0];
if (!$image_oid) die ("We don't have your picture yet, $linux");
$type=$row[1];
header("Content-type: $type");
$handle = pg_lo_open($database, $image_oid, "r");
pg_lo_read_all($handle);
pg_query($database, "commit");
?>
The type bytea is a binary version of text, an unlimited size of bytes. However, to insert such a binary value, many bytes that are not printing characters must be escaped. Likewise, when retreiving bytea fields, all the bytes are returned as escaped values. NOTE: You cannot pass the already-escaped string as a parameter, since that would cause further escaping!
Going in:
$allbytes = file_get_contents($file['tmp_name']);Getting out:
$allbytes = pg_escape_bytea($allbytes);
$res = pg_query_params("update students set mugb='$allbytes', typeb=$1 where linux=$2",
array($imagetype, $linux));
$res = pg_query($database, "select typeb, mugb from students where linux='$linux'");See this in action, (use second form)
$row = pg_fetch_row($res);
if (!$row) die("We can'f find you, $linux");
$image = $row[1];
if (!$image) die ("We don't have your picture yet, $linux");
$type=$row[0];
header("Content-type: $type");
print pg_unescape_bytea($image);