First attempt at uploading image and storing to db

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bissatch@yahoo.co.uk

    First attempt at uploading image and storing to db

    Hi,

    I am trying to upload an image, create a new file based on that image
    and then store the base64 encoded image data in a database.

    I dont really know where my code is going wrong so I will just display
    it below:

    The following code contains the script to process the uploaded file,
    the form to upload the file and then a few links to view the file from
    a php script called simpleimageview er.php:

    <?php

    //this file includes the function, 'dbconn()', that allows you to
    //connect to the database
    include('functi ons.php');

    ?>
    <html>
    <body>
    <?php

    //
    if (isset($_GET['action'])) {
    if (isset($_GET['action']) == "add") {
    $tmpfilesize = $_FILES['imgfile']['size'];
    $tmpfilename = $_FILES['imgfile']['tmp_name'];
    $tmpfiletype = $_FILES['imgfile']['type'];
    if ($tmpfilesize > 0) {
    if (substr($tmpfil etype, 0, 6) == 'image/') {
    //create image from uploaded image
    switch ($tmpfiletype)
    {
    case "image/jpeg":
    case "image/pjpeg":
    $img = imagecreatefrom jpeg($tmpfilena me);
    break;
    case "image/gif":
    $img = imagecreatefrom gif($tmpfilenam e);
    break;
    case "image/png":
    $img = imagecreatefrom png($tmpfilenam e);
    break;
    }
    //create new file
    $newfile = tempnam("/tmp", "img_");
    //create jpeg and save as newfile
    imagejpeg($img, $newfile, 80);
    //open new file
    $nf = fopen($newfile, "r");
    //get contents of opened file and store in var
    $filecontents = fread($nf, filesize($newfi le));
    //destroy file
    fclose($nf);
    unlink($newfile );

    if ($filecontents) {
    $insert = "INSERT INTO imglib (imgid, imgdata, imgtype) VALUES
    (null, '" . base64_encode($ filecontents) . "', '" . $imgtype . "')";
    $result = mysql_query($in sert, $db);
    if ($result) {
    echo "<p>Result! </p>";
    }else{
    echo "<p>No, no, no ... it didnt work</p>";
    }
    }
    } else {
    echo "<p>Please upload an image - wrong file type (" .
    $tmpfiletype . ")</p>";
    }
    }else{
    echo "<p>File not uploaded</p>";
    }
    }
    }

    ?>
    <form enctype="multip art/form-data" name="" method="post"
    action="simple. php?action=add" >
    <input type="hidden" name="MAX_FILE_ SIZE" value="5000000" ><!-- approx.
    5MB -->
    <input name="imgfile" type="file"><br />
    <input name="submit" type="submit" value="Submit">
    </form>
    <?php

    $select = "SELECT * FROM imglib";
    $result = mysql_query($se lect, $db);
    if (mysql_num_rows ($result) > 0) {
    echo "<ul>\n";
    while ($row = mysql_fetch_arr ay($result)) {
    $imgid = $row['imgid'];
    echo " <li><a href=\"simpleim ageviewer.php?i mgid=" . $imgid .
    "\">Image " . $imgid . "</a></li>\n";
    }
    echo "</ul>";
    }

    ?></body>
    </html>



    Sorry about the mass of code but I thought I should just provide it
    all. I also at some point need to resize the uploaded image so I seemed
    the best idea to create a temporary file that I could play around with
    before writing.

    The problem is that when I go to view the image using the following
    script (simpleimagevie wer.php):


    include('functi ons.php');

    //IMAGE OUTPUT

    $select = "SELECT imgdata, imgtype FROM imglib WHERE imgid = " .
    $_GET['imgid'];
    $result = mysql_query($se lect, $db);
    while ($row = mysql_fetch_arr ay($result)) {
    $imgdata = $row['imgdata'];
    $imgtype = $row['imgtype'];
    }

    //header
    header("Content-type: " . $imagetype);
    echo base64_decode($ imgdata);
    flush();


    It doesnt display all the image. See
    http://www.martynbissett.co.uk/test/...er.php?imgid=5 to
    see what I mean. When I highlight the image it does show a lot of white
    area that appears to have been a problem when creating the initial
    image from the uploaded one.

    Can anyone tell from my code what might be the problem, cheers

    Burnsy

  • bissatch@yahoo.co.uk

    #2
    Re: First attempt at uploading image and storing to db

    Me again,

    Think I know what the problem was. The image I was using was about
    1200x1500px, when I resized the image (as I will do in my script
    anyway) it should be ok.

    Is there a maximum data size that datatype, 'text' can store in a
    database or is there something else in the above script that is
    limiting this? Cheers

    Burnsy

    Comment

    • Andy Hassall

      #3
      Re: First attempt at uploading image and storing to db

      On 16 Aug 2005 17:05:01 -0700, bissatch@yahoo. co.uk wrote:
      [color=blue]
      >Think I know what the problem was. The image I was using was about
      >1200x1500px, when I resized the image (as I will do in my script
      >anyway) it should be ok.
      >
      >Is there a maximum data size that datatype, 'text' can store in a
      >database or is there something else in the above script that is
      >limiting this? Cheers[/color]

      Yes, 2^16 bytes = 64Kb, which won't get you very far for big images.


      --
      Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
      <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

      Comment

      • Andy Hassall

        #4
        Re: First attempt at uploading image and storing to db

        On 16 Aug 2005 16:56:33 -0700, bissatch@yahoo. co.uk wrote:
        [color=blue]
        >I am trying to upload an image, create a new file based on that image
        >and then store the base64 encoded image data in a database.[/color]

        A couple of suggestions for improvements:

        MySQL can store binary data directly using the *BLOB types, which would avoid
        the 33% size increase plus processing that you are incurring by base64 encoding
        it.

        You're writing the JPEG to a temporary file then reading back out again before
        feeding into the database; another approach could be to use the output
        buffering functions (ob_start() etc.) and then use imagejpeg without a filename
        argument. You can then read the data out of the output buffer and into the
        database without the intermediate temporary file.

        --
        Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
        <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

        Comment

        • bissatch@yahoo.co.uk

          #5
          Re: First attempt at uploading image and storing to db

          > MySQL can store binary data directly using the *BLOB types, which would avoid[color=blue]
          > the 33% size increase plus processing that you are incurring by base64 encoding
          > it.[/color]

          I was aware that my above method gave a 33% increase but I was just
          wanting to accomplish uploading, storing and outputing at this stage.

          Anyway, going on your advice above I have tried the following code when
          the image is uploaded:

          $tmpfiletype = $_FILES['imgfile']['type'];
          switch ($tmpfiletype)
          {
          case "image/jpeg":
          case "image/pjpeg":
          $img = imagecreatefrom jpeg($tmpfilena me);
          break;
          case "image/gif":
          $img = imagecreatefrom gif($tmpfilenam e);
          break;
          case "image/png":
          $img = imagecreatefrom png($tmpfilenam e);
          break;
          }

          //write to db
          $insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
          '" . $img . "', '" . $imgtype . "')";
          $result = mysql_query($in sert, $db);
          if ($result) {
          echo "<p>Result! </p>";
          }else{
          echo "<p>No, no, no ... it didnt work</p>";
          }


          Unfortetely, I am getting the 'No, no, no ... it didnt work' output
          that indicates that it wasnt able to write the image to the database. I
          am guessing that I need to do something with $img before I can use it
          in the INSERT query. What do I need to do with $img to let me INSERT it
          if this is the case?

          Note: I have created a table called imgblob with a imgdata with type
          'blob' instead of 'text' for use here

          Cheers

          Burnsy

          Comment

          • Andy Hassall

            #6
            Re: First attempt at uploading image and storing to db

            On 17 Aug 2005 16:12:06 -0700, bissatch@yahoo. co.uk wrote:
            [color=blue][color=green]
            >> MySQL can store binary data directly using the *BLOB types, which would avoid
            >> the 33% size increase plus processing that you are incurring by base64 encoding
            >> it.[/color]
            >
            >I was aware that my above method gave a 33% increase but I was just
            >wanting to accomplish uploading, storing and outputing at this stage.[/color]

            OK, fair enough.
            [color=blue]
            >Anyway, going on your advice above I have tried the following code when
            >the image is uploaded:
            >
            >$tmpfiletype = $_FILES['imgfile']['type'];
            >switch ($tmpfiletype)
            >{
            >case "image/jpeg":
            >case "image/pjpeg":
            > $img = imagecreatefrom jpeg($tmpfilena me);
            > break;
            >case "image/gif":
            > $img = imagecreatefrom gif($tmpfilenam e);
            > break;
            >case "image/png":
            > $img = imagecreatefrom png($tmpfilenam e);
            > break;
            >}
            >[/color]

            So $img is a resource handle here.
            [color=blue]
            >//write to db
            >$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
            >'" . $img . "', '" . $imgtype . "')";[/color]

            You don't want to write the string representation of a resource handle into
            the database - it won't mean much. Also you want some escaping here - more so
            since it'll be binary data now.
            [color=blue]
            >$result = mysql_query($in sert, $db);
            >if ($result) {
            > echo "<p>Result! </p>";
            >}else{
            > echo "<p>No, no, no ... it didnt work</p>";[/color]

            The dreaded "doesn't work" message :-( Make it more helpful with
            mysql_error().
            [color=blue]
            >Unfortetely, I am getting the 'No, no, no ... it didnt work' output
            >that indicates that it wasnt able to write the image to the database. I
            >am guessing that I need to do something with $img before I can use it
            >in the INSERT query. What do I need to do with $img to let me INSERT it
            >if this is the case?
            >
            >Note: I have created a table called imgblob with a imgdata with type
            >'blob' instead of 'text' for use here[/color]

            Similar to the bit where you did imagejpeg to a temporary file, but instead
            wrap it in buffering. This is just typed without testing:

            ob_start();
            imagejpeg($img, '', 80);
            $imgdata = ob_get_contents ();
            ob_end_clean();

            $insert = sprintf(
            "INSERT INTO imgblob (imgid, imgdata, imgtype)
            VALUES (null, '%s', '%s'),
            mysql_real_esca pe_string($imgd ata),
            mysql_real_esca pe_string($imgt ype),
            );

            Then go ahead and run the query.

            You might also want a bigger datatype like MEDIUMBLOB or LONGBLOB.

            --
            Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
            <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

            Comment

            • bissatch@yahoo.co.uk

              #7
              Re: First attempt at uploading image and storing to db

              I tried your line for INSERT but I think you may have left out a set of
              quotes ("), and added an extra comma (,) so I tried the following:

              $insert = sprintf(
              "INSERT INTO imgblob (imgid, imgdata, imgtype)
              VALUES (null, '%s', '%s')",
              mysql_real_esca pe_string($imgd ata),
              mysql_real_esca pe_string($imgt ype)
              );

              Unfortuntely that gave me the following error:

              - Unknown column 'imgid' in 'field list'

              Without really knowing too much about your code I cant really determine
              what it is supposed to be doing here.

              Anyway, I have went back to trying my old INSERT with the Output Buffer
              code you provided but still didnt work:

              //prepare image for database
              ob_start();
              imagejpeg($img, '', 80);
              $imgdata = ob_get_contents ();
              ob_end_clean();

              //write to db
              $insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
              '" . $imgdata . "', '" . $imgtype . "')";
              $result = mysql_query($in sert, $db);
              if ($result) {
              echo "<p>Result! </p>";
              }else{
              echo "<p>No, no, no ... it didnt work</p>";
              echo "<p>" . mysql_error() . "</p>";
              }


              Gave me the following 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
              '*)-0-(0%()(ÿÛ' at line 1

              Any ideas?

              Burnsy

              Comment

              • Andy Hassall

                #8
                Re: First attempt at uploading image and storing to db

                On 18 Aug 2005 02:49:21 -0700, bissatch@yahoo. co.uk wrote:
                [color=blue]
                >I tried your line for INSERT but I think you may have left out a set of
                >quotes ("), and added an extra comma (,) so I tried the following:
                >
                >$insert = sprintf(
                > "INSERT INTO imgblob (imgid, imgdata, imgtype)
                > VALUES (null, '%s', '%s')",
                > mysql_real_esca pe_string($imgd ata),
                > mysql_real_esca pe_string($imgt ype)
                >);[/color]

                Ah, yes, I did warn you I hadn't tried it :-)
                [color=blue]
                >Unfortuntely that gave me the following error:
                >
                >- Unknown column 'imgid' in 'field list'[/color]

                Well, what's the definition of your table? I just copied your insert statement
                and fixed it up to escape properly.

                Looking back at your original post you have:

                $select = "SELECT imgdata, imgtype FROM imglib WHERE imgid = ...

                But then "imglib" changes to "imgblob" in the next post.
                [color=blue]
                >Without really knowing too much about your code I cant really determine
                >what it is supposed to be doing here.[/color]

                It's putting the properly escaped values in the statement - and that's all.
                Not doing much more than your previous insert statement, but yours won't work
                as we can see in a moment...
                [color=blue]
                >Anyway, I have went back to trying my old INSERT with the Output Buffer
                >code you provided but still didnt work:
                >
                >//write to db
                >$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
                >'" . $imgdata . "', '" . $imgtype . "')";
                >$result = mysql_query($in sert, $db);
                >if ($result) {
                > echo "<p>Result! </p>";
                >}else{
                > echo "<p>No, no, no ... it didnt work</p>";
                > echo "<p>" . mysql_error() . "</p>";
                >}
                >
                >Gave me the following 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
                >'*)-0-(0%()(ÿÛ' at line 1
                >
                >Any ideas?[/color]

                You MUST use mysql_escape_st ring or mysql_real_esca pe_string on the data
                before you put it in the INSERT statement. Since it's binary data, odds are it
                contains a quote or a NUL character, in which case it breaks out of the quotes
                around it and produces syntax errors from the binary data that it's trying to
                parse as SQL.
                [color=blue]
                >$insert = sprintf(
                > "INSERT INTO imgblob (imgid, imgdata, imgtype)
                > VALUES (null, '%s', '%s')",
                > mysql_real_esca pe_string($imgd ata),
                > mysql_real_esca pe_string($imgt ype)
                >);[/color]

                This is what I was getting at with the modified $insert statement here. You
                could just as well write it as:

                $insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,'" .
                mysql_escape_st ring($imgdata) . "', '" .
                mysql_escape_st ring($imgtype) . "')";

                At which point it'll probably start complaining about imgid again, since it
                seems there's some issue with the table structure not matching what you've
                posted?

                --
                Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
                <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

                Comment

                • bissatch@yahoo.co.uk

                  #9
                  Re: First attempt at uploading image and storing to db

                  My mistake, sorry. For some reason I had accidentally name the imgid
                  field on imgblob as imglib. All is well now.

                  Just one more question. The intended database where this concept will
                  work is PostgreSQL as this is what I work with when Im at work. At home
                  I practise on MySQL. I know the alternatives for stuff like mysql_query
                  and the connection stuff. What is the PG alternative to
                  mysql_real_esca pe_string()? Is it required? Can I simply use
                  mysql_real_esca pe_string() with PG?

                  Cheers

                  Burnsy

                  Comment

                  • Tim Van Wassenhove

                    #10
                    Re: First attempt at uploading image and storing to db

                    On 2005-08-19, bissatch@yahoo. co.uk <bissatch@yahoo .co.uk> wrote:[color=blue]
                    > My mistake, sorry. For some reason I had accidentally name the imgid
                    > field on imgblob as imglib. All is well now.
                    >
                    > Just one more question. The intended database where this concept will
                    > work is PostgreSQL as this is what I work with when Im at work. At home
                    > I practise on MySQL. I know the alternatives for stuff like mysql_query
                    > and the connection stuff. What is the PG alternative to
                    > mysql_real_esca pe_string()? Is it required? Can I simply use
                    > mysql_real_esca pe_string() with PG?[/color]

                    Have you even bothered to have a look at the manual?
                    http://www.php.net/pgsql (pgsql_escape_s tring)

                    Btw, why would you loose time with that if you can use prepared
                    statements/parameter binding?

                    --
                    Met vriendelijke groeten,
                    Tim Van Wassenhove <http://timvw.madoka.be >

                    Comment

                    • bissatch@yahoo.co.uk

                      #11
                      Re: First attempt at uploading image and storing to db

                      > Have you even bothered to have a look at the manual?

                      Its a bit difficult when you dont know the command. How am I supposed
                      to check what pgsql_escape_st ring does when I dont even know that is
                      what I am looking for.

                      I did, however, check for pg_real_escape_ string. Sometimes the PG
                      equivelant is easy to find (mysql_fetch_ar ray -> pg_fetch_array and so
                      on)
                      [color=blue]
                      > Btw, why would you loose time with that if you can use prepared
                      > statements/parameter binding?[/color]

                      Hmm, dont know that one. Explain please.

                      Comment

                      • Tim Van Wassenhove

                        #12
                        Re: First attempt at uploading image and storing to db

                        On 2005-08-19, bissatch@yahoo. co.uk <bissatch@yahoo .co.uk> wrote:[color=blue][color=green]
                        >> Have you even bothered to have a look at the manual?[/color]
                        >
                        > Its a bit difficult when you dont know the command. How am I supposed
                        > to check what pgsql_escape_st ring does when I dont even know that is
                        > what I am looking for.[/color]

                        Well, it's pretty easy to type http://www.php.net/whatever_im_searching

                        In your case, i would probably type http://www.php.net/pgsql and look at
                        the available functions.
                        [color=blue]
                        > I did, however, check for pg_real_escape_ string. Sometimes the PG
                        > equivelant is easy to find (mysql_fetch_ar ray -> pg_fetch_array and so
                        > on)[/color]

                        I went to http://www.php.net/pgsql_real_escape_string and i saw that it
                        doesn't exist. But in the suggested list i see pg_escape_strin g.

                        [color=blue][color=green]
                        >> Btw, why would you loose time with that if you can use prepared
                        >> statements/parameter binding?[/color]
                        >
                        > Hmm, dont know that one. Explain please.[/color]

                        You can start reading at http://www.php.net/pg_query_params.
                        For more in depth info you might want to perform a websearch on
                        "prepared statements" / "parameter binding"

                        --
                        Met vriendelijke groeten,
                        Tim Van Wassenhove <http://timvw.madoka.be >

                        Comment

                        Working...