-1

I have created a file upload that stores files in a mysql database and it works as it should for all file types except PDF.

MySQL database structure:

CREATE TABLE IF NOT EXISTS `pdfupload` 
(
  `id` int(12) NOT NULL,
  `name` varchar(100) NOT NULL,
  `type` varchar(100) NOT NULL,
  `size` int(12) NOT NULL,
  `content` longblob NOT NULL
)

And here is my code for the file upload

<!DOCTYPE html>
<body>

<form method="post" enctype="multipart/form-data">
<table width="350" border="0" cellpadding="1" cellspacing="1" class="box">
<tr> 
<td width="246">
<input type="hidden" name="MAX_FILE_SIZE" value="20000000">
<input name="userfile" type="file" id="userfile"> 
</td>
<td width="80"><input name="upload" type="submit" class="box" id="upload"    

    value=" Upload "></td>
</tr>
</table>
</form>

<?php
include 'connect-db.php';
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
    $fileName = $_FILES['userfile']['name'];
    $tmpName  = $_FILES['userfile']['tmp_name'];
    $fileSize = $_FILES['userfile']['size'];
    $fileType = $_FILES['userfile']['type'];

    $fp      = fopen($tmpName, 'r');
    $content = fread($fp, filesize($tmpName));
    $content = addslashes($content);
    fclose($fp);

    if(!get_magic_quotes_gpc())
    {
        $fileName = addslashes($fileName);
    }

    $query = "INSERT INTO pdfupload 
                     (name, size, type, content ) 
              VALUES ('$fileName', '$fileSize', '$fileType', '$content')";

    mysql_query($query) or die('Error, query failed'); 

    echo "<br>File $fileName uploaded<br>";
} 
?>

</body>
</html>

Can anyone spot any issues or inform me if this will simply not work with PDF documents?
Many thanks in advance.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
calac94
  • 1
  • 5
  • 1
    How can you read pdf file via fread($fp, filesize($tmpName)); ? think your self its correct? – Ajeet Kumar Oct 02 '15 at 11:01
  • Sorry, I don't understand what you are trying to say here. Please expand – calac94 Oct 02 '15 at 11:07
  • 1
    **Note**: Drop using `mysql_` functions, as it's deprecated, and migrate to `mysqli_` ones, or `PDO` objects. – al'ein Oct 02 '15 at 11:07
  • I would suggest not storing files like this in the database. If `addslashes()` is necessary to allow the file to be stored then it is **no longer a pdf file** and when you come to try and read it back from the database and view it as a PDF, **it just wont work** And before anyone suggests that `stripslashes()` will acurately undo what `addslashes` has done. I bet it wont with a file as complex as a PDF! – RiggsFolly Oct 02 '15 at 11:11
  • Try changing `mysql_query($query) or die('Error, query failed');` so that it actually outputs the real error like `mysql_query($query) or die(mysql_error());` That may well be all you need to diagnose your problem – RiggsFolly Oct 02 '15 at 11:24
  • @RiggsFolly - the error message is not even outputted when the file doesnt upload – calac94 Oct 02 '15 at 11:29
  • Why are you trying to read the contents of a PDF file and then store the contents in a database? Why not just upload the file itself then store the name of the file in the database? Then you can just use the name stored in the database as a link to open the actual pdf file. Just a thought. Seems like you are over-complicating things. – Kuya Oct 02 '15 at 11:31
  • I also seem to remember that if you are on windows as I now see you are, its better to use the binary flag when reading files like this so when you actually get a file uploaded change this line to include the binary flag `$fp = fopen($tmpName, 'rb');` – RiggsFolly Oct 02 '15 at 11:51
  • Well if you got it working somehow. It would be useful to others if you posted your actual solution. It would help others that have similiar problems. _That is afterall the basic ethos of SO_ To record answer to questions, so that others may learn from them, without having to ask the same question again and again. – RiggsFolly Oct 02 '15 at 15:23
  • I plan on uploading the working version later im not on my computer right now – calac94 Oct 02 '15 at 15:26

3 Answers3

0

use mysql_real_escape_string

mysql_real_escape_string(fread($instr,filesize($fileName)));

instead of

addslashes($content);

addslashes adds slashes to characters that are commonly disturbing. mysql_real_escape_string escapes whatever MySQL needs to be escaped. This may be more or less characters than what addslashes takes care of.

Also, mysql_real_escape_string will not necessarily add slashes to escape. While I think it works if you do it that way, recent versions of MySQL escape quotes by putting two of them together instead of by putting a slash before it.

I believe you should always use your data provider's escape function instead of addslashes, because addslashes may either do too much or not enough work for the purpose you use it. On the other hand, mysql_real_escape_string knows what to do to prepare a string for embedding it in a query. Even if the specs change about how to escape stuff and suddenly it's not backslashes that you should use anymore, your code will still work because mysql_real_escape_string will be aware

Ajeet Kumar
  • 805
  • 1
  • 7
  • 26
  • And where are `$instr` and what is `"latest.img"` in the OP's question. An answer should be related to the question and not just a copy/paste of some code you found somewhere! Also some description of why `mysql_real_escape_string()` is better than `addslashes()` would also be useful to make a complete answer – RiggsFolly Oct 02 '15 at 11:15
  • 1
    Any tutorial that uses an `@` in front of a `@mysql_*` function call should be treated with the **total disrespect that it deserves** – RiggsFolly Oct 02 '15 at 11:21
  • I've tried using the mysql_real_escape string as suggested and then changed it to : $content = mysql_real_escape_string(fread($content,filesize(""))); and now have the error message " fread() expects parameter 1 to be resource, string given" – calac94 Oct 02 '15 at 11:25
  • Make it `mysql_real_escape_string(fread($fp,filesize($fileName)));` he is not really paying attention – RiggsFolly Oct 02 '15 at 11:30
  • Still no luck, same as before, no error message outputted but the file isnt uploading, however upon trying to upload a file that would usually work, the following message is outputted: Warning: filesize(): stat failed for IMG_1162.JPG in C:\xampp\htdocs\Intranet\upload.php on line 27 Warning: fread(): Length parameter must be greater than 0 in C:\xampp\htdocs\Intranet\upload.php on line 27 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 and the file is also not uploaded – calac94 Oct 02 '15 at 11:34
  • You are not checking the `$_FILES['userfile']['error']` so it is quite possible that PHP has rejected the file upload as too large. Check the `error` code, see [possible error codes and meanings](http://php.net/manual/en/features.file-upload.errors.php) Also check `upload_max_filesize` in your `php.ini` – RiggsFolly Oct 02 '15 at 11:41
  • the upload_max_filesize is 2Mb and the files I have tried uploading are all under 1Mb - so that cant be the issue, good suggestion though – calac94 Oct 02 '15 at 11:49
  • @calac94 where you got error in mysql or php side if its not on php side then print your query and run on mysql , you could got the error.... – Ajeet Kumar Oct 02 '15 at 12:00
  • Well as its saying that `filesize($fileName)` is zero, I would suggest that the temp file is either not uploaded or has somehow been removed. Or you have got the filename wrong. – RiggsFolly Oct 02 '15 at 12:00
  • @RiggsFolly in the database the content coulmn is empty - it is filling all other fields including size – calac94 Oct 02 '15 at 12:02
  • Check there error_reporting is on or not ... may be php giving warning on there...... use **error_reporting(1);** to show errors – Ajeet Kumar Oct 02 '15 at 12:05
  • error reporting You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '00') /ModDate (D:20150826130427+02'00') >> endobj 2 0 obj << /Type /Catalog /Pag' at line 1 – calac94 Oct 02 '15 at 12:10
  • @calac94 have you added in **mysql_real_escape_string** your code? if not than add it .. mysql_real_escape_string can add shlashes there which are break your query.. – Ajeet Kumar Oct 02 '15 at 12:38
0

You could try using the MySQL LOAD_FILE() syntax to load the PDF file into the tables content column.

<?php
error_reporting(E_ALL); 
ini_set('display_errors', 1);

include 'connect-db.php';
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
    $message = '';
    switch ($_FILES['userfile']['error']) {
        case UPLOAD_ERR_INI_SIZE:
            $message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
            break;
        case UPLOAD_ERR_FORM_SIZE:
            $message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
            break;
        case UPLOAD_ERR_PARTIAL:
            $message = "The uploaded file was only partially uploaded";
            break;
        case UPLOAD_ERR_NO_FILE:
            $message = "No file was uploaded";
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $message = "Missing a temporary folder";
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $message = "Failed to write file to disk";
            break;
        case UPLOAD_ERR_EXTENSION:
            $message = "File upload stopped by extension";
            break;

        default:
            $message = "Unknown upload error";
        }
    } 
    if ( $message != '' ) {
        echo $message;
        exit;
    }

    $fileName = $_FILES['userfile']['name'];
    $tmpName  = $_FILES['userfile']['tmp_name'];
    $fileSize = $_FILES['userfile']['size'];
    $fileType = $_FILES['userfile']['type'];

    $query = "INSERT INTO pdfupload 
                     (name, size, type, content ) 
              VALUES ( '$fileName', 
                       '$fileSize', 
                       '$fileType',
                       LOAD_FILE($tmpName) 
                 )";

    $res = mysql_query($query);
    if ( ! $res ) {
        echo 'Query failed with error : ' . mysql_error();
        exit;
    }
}

See The documentation for LOAD_FILE It can be a bit particular about rights etc, but on windows you should not have that issue, probably.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
  • This method does not work either, although there are no errors which must be getting better... the mysql_error is not outputting again. – calac94 Oct 02 '15 at 12:54
  • Try adding the 2 Error reporting lines to the top of the script. See if that gives you any more clues – RiggsFolly Oct 02 '15 at 12:56
  • Nothing at all showing up on error reporting when trying to upload pdf files, with any other file the following error is on screen: - Query failed with error : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':\xampp\tmp\php2783.tmp) )' at line 6 – calac94 Oct 02 '15 at 12:58
  • Ok next possibility. Add the upload error processing code, see if that tells us anything – RiggsFolly Oct 02 '15 at 13:02
  • Actually that error message seems to be saying that somehow you have choped the `drive letter` from the front of the filename???? I dont know how your code actually looks anymore as I dont know what suggestions you have kept and which you have discarded – RiggsFolly Oct 02 '15 at 13:04
  • currently i am using the php code you recently provided and the original html form – calac94 Oct 02 '15 at 13:07
  • I edited the original code i had to the extent where there was too many issues and a new way of doing it was the best option from there – calac94 Oct 02 '15 at 13:13
  • Any idea on why the driver letter is missing? Try adding `echo $_FILES['userfile']['tmp_name'];` so you can see what it is being created as by PHP – RiggsFolly Oct 02 '15 at 13:22
  • no idea at all, cant see anything unusual in the code. – calac94 Oct 02 '15 at 14:04
  • it doesnt show anything at all except : C:\xampp\tmp\php574F.tmpQuery failed with error : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':\xampp\tmp\php574F.tmp) )' at line 6 – calac94 Oct 02 '15 at 14:10
  • So what server version are you using? Just in case we are talking about MYSQL1.0 here – RiggsFolly Oct 02 '15 at 15:07
0

You might need library for that e.g http://www.pdfparser.org/. Have a look at this question might help you.

Read pdf files with php

Community
  • 1
  • 1
Abbasi
  • 617
  • 7
  • 14