Before I start I'm a bit of a PHP/MYSQL newbie.

I have created a simple blog/news feed using PHP and MYSQL:
http://stephengreig.co.uk/newjack/blog.php

Currently I can insert the news post details into the database table and the news feed will update.

What I want to do is create a form where a user can input the post title and text as well as upload an image (which is the main bit I'm having trouble with). When submitted this form then inserts the data into the database and updates the news feed page.

My database table for the news post is simply: id, postdate, title, newstext.
Do I simply add another field for image with a BLOB type? Or does the image need its own table?

Any help would be greatly appreciated.

    There are a couple approaches you can use to store the image (1) store the image in the database as a blob. (2) store the path to the image in the database and store the image as a file in a designated folder. Storing them in the database scales easier.

    Factors that will influence your decision include: the maximum size of the image --- there is a limit to how big a query you can send to mysql at once and you may not depending on your hosting situation have access to change that number. Its call max_allowed_packet (http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html) which is probably 16MB, so if you're just saving small jpegs its probably not a problem.

    You are correct in your approach: just add another column to the existing table. I can see some benefits of making the images in their own table and add image_id to the existing table: you could continue to read the existing table more or less as you do right now. If you add an image blob to the existing table every select * query will pull back the images, which maybe not what you want to do. Also, having a separate table for the images would make it easier to in the future allow multiple images per post if you wanted.

    If you store the image into the database you'll likely want to store the image dimensions (width, height and size in bytes) as well. If you store the images on the file system you can get the info easily with getimagesize().

    Use addslashes($imageData) for storing the image blob into the mysql table rather than mysql_real_escape_string($imageData) where $imageData is the binary image data. To get the binary data into $imageData you read it from the file system w/ fread().

    Remember to set enctype="multipart/form-data" attribute for form to allow the image to upload --- I forgot that the first couple times.

    Hope that helps you get started.

      Let me show you where I'm at now...

      My form:

      When I click submit it adds to the database (the last entry shown here):

      There does seem to be something in the image field... does this mean the image upload worked?

      If so, how on earth do I display this image in my blog post as intended? The blog updates perfectly (http://stephengreig.co.uk/newjack/blog.php) but how do I include the image that was uploaded in the blog post?

      My PHP code is:

      <?php
      /* user config variables */
      $max_items = 5; /* max number of news items to show */
      
      /* make database connection */
      require_once('config.php');
      $db = mysql_connect (DB_HOST,DB_USER,DB_PASSWORD);
      if(!$db) {
      		die('Failed to connect to server: ' . mysql_error());
      	}
      mysql_select_db (DB_DATABASE,$db);
      
      function displayNews($all = 0) {
          /* bring in two variables
           * $db is our database connection
           * $max_items is the maximum number
           * of news items we want to display */
          global $db, $max_items;
      
      /* query for news items */
      if ($all == 0) {
          /* this query is for up to $max_items */
          $query = "SELECT id,title,newstext," . 
                   "DATE_FORMAT(postdate, '%H:%i, %D %M %Y') as date " . 
                   "FROM news ORDER BY postdate DESC LIMIT $max_items";
      } else {
          /* this query will get all news */
          $query = "SELECT id,title,newstext," . 
                   "DATE_FORMAT(postdate, '%H:%i, %D %M %Y') as date " .
                   "FROM news ORDER BY postdate DESC";
      }
      $result = mysql_query ($query);
      
      
      while ($row = mysql_fetch_assoc ($result)) {
          /* display news in a simple table */
          echo "<div class='newspost'>\n";
      
          /* place table row data in 
           * easier to use variables.
           * Here we also make sure no
           * HTML tags, other than the
           * ones we want are displayed */
          $date = $row['date'];        
          $title = htmlentities ($row['title']);
          $news = nl2br (strip_tags ($row['newstext'], '<a><b><i><u>'));
      
          /* display the data */
          echo "<span class='posttitle'><span class='postedon'>$date</span>$title</span>\n";
          echo "<span class='news'>$news</span>\n";
      
          /* get number of comments */
          $comment_query = "SELECT count(*) FROM news_comments " .
                           "WHERE news_id={$row['id']}";
          $comment_result = mysql_query ($comment_query);
          $comment_row = mysql_fetch_row($comment_result);
      
          /* display number of comments with link */
          echo "<a href=\"{$_SERVER['PHP_SELF']}" .
               "?action=show&amp;id={$row['id']}\">Comments&nbsp;</a>" .
               "($comment_row[0])\n";
      
          /* finish up table*/
          echo "</div>\n";
          echo "<br />\n";
      }
      
      /* if we aren't displaying all news, 
       * then give a link to do so */
      if ($all == 0) {
          echo "<span class='viewall'><a href=\"{$_SERVER['PHP_SELF']}" .
               "?action=all\">View all</a></span>\n";
      }
      }
      
      function displayOneItem($id) {
          global $db;
      
      /* query for item */
      $query = "SELECT * FROM news WHERE id=$id";
      $result = mysql_query ($query);
      
      /* if we get no results back, error out */
      if (mysql_num_rows ($result) == 0) {
          echo "Bad news id\n";
          return;
      }
      $row = mysql_fetch_assoc($result);
      echo "<div class='newspost'>\n";
      
      /* easier to read variables and 
       * striping out tags */
      $title = htmlentities ($row['title']);
      $news = nl2br (strip_tags ($row['newstext'], '<a><b><i><u>'));
      
      /* display the items */
      echo "<span class='posttitle'>$title</span>\n";
      echo "<br />$news\n";
      
      echo "</div>\n";
      echo "<p><a href='blog.php'>Back to news</a></p>";
      
      /* now show the comments */
      displayComments($id);
      
      }
      
      function displayComments($id) {
          /* bring db connection variable into scope */
          global $db;
      
      /* query for comments */
      $query = "SELECT * FROM news_comments WHERE news_id=$id";
      $result = mysql_query ($query);
      echo "Comments:<br />\n";
      
      /* display the all the comments */
      while ($row = mysql_fetch_assoc ($result)) {
          echo "<div class='comments'>\n";
      
          $name = htmlentities ($row['name']);
          echo "<span class='comname'>by: $name</span>\n";
      
          $comment = strip_tags ($row['comment'], '<a><b><i><u>');
          $comment = nl2br ($comment);
          echo "<p>$comment</p>\n";
      
          echo "</div>\n";
      }
      
      /* add a form where users can enter new comments */
      echo "<div id='comform'>";
      echo "<FORM action=\"{$_SERVER['PHP_SELF']}" .
           "?action=addcomment&amp;id=$id\" method=POST>\n";
      echo "Name:<br /> <input id='comname' type=\"text\" " .
           "width=\"30\" name=\"name\"><br />\n";
      echo "<TEXTAREA id='comtxt' cols=\"40\" rows=\"5\" " .
           "name=\"comment\"></TEXTAREA><br />\n";
      echo "<input type=\"submit\" name=\"submit\" " .
           "value=\"Add Comment\">\n";
      echo "</FORM>\n";
      echo "</div>";
      
      }
      
      function addComment($id) {
          global $db;
      
      /* insert the comment */
      $query = "INSERT INTO news_comments " .
               "VALUES('',$id,'{$_POST['name']}'," .
               "'{$_POST['comment']}')";
      mysql_query($query);
      
      echo "<p>";
      echo "<span class='commentposted'>Comment posted. Thanks!</span><br />\n";
      echo "<a href=\"{$_SERVER['PHP_SELF']}" .
           "?action=show&amp;id=$id\"<span class='comback'>Back</span></a>\n";
      echo "</p>";
      }
      
      /* this is where the script decides what do do */
      
      echo "\n";
      switch($_GET['action']) {
      
      case 'show':
          displayOneItem($_GET['id']);
          break;
      case 'all':
          displayNews(1);
          break;
      case 'addcomment':
          addComment($_GET['id']);
          break;
      default:
          displayNews();
      }
      echo "\n";
      ?>

        You have to make a php page to serve the image. In static html you'd write <img src="foo.png" />...now you have to write <img src="image_server.php?id=6" /> where you want the image to appear on the page...obviously your php page can have whatever name and take whatever params you need to pull the image. Then image_server.php (or whatever you called it) will read the blob from the database, send the appropriate content-type header, then print the binary data.

          Many thanks for you help.

          When I try to insert the image tag into my code the page then appears completely blank. I am trying to put the image within my displayNews function in the PHP. I have put red text where I want to insert the image code. Can you help?

          function displayNews($all = 0) {
              global $db, $max_items;
          
          /* query for news items */
          if ($all == 0) {
              /* this query is for up to $max_items */
              $query = "SELECT id,title,newstext," . 
                       "DATE_FORMAT(postdate, '%H:%i, %D %M %Y') as date " . 
                       "FROM news ORDER BY postdate DESC LIMIT $max_items";
          } else {
              /* this query will get all news */
              $query = "SELECT id,title,newstext," . 
                       "DATE_FORMAT(postdate, '%H:%i, %D %M %Y') as date " .
                       "FROM news ORDER BY postdate DESC";
          }
          $result = mysql_query ($query);
          
          
          while ($row = mysql_fetch_assoc ($result)) {
              echo "<div class='newspost'>\n";
          
              $date = $row['date'];        
              $title = htmlentities ($row['title']);
              $news = nl2br (strip_tags ($row['newstext'], '<a><b><i><u>'));
          
              /* display the data */
              echo "<span class='posttitle'><span class='postedon'>$date</span>$title</span>\n";
          	[COLOR="Red"]I WANT THE APPROPRIATE IMAGE TO APPEAR HERE - IT WILL BE DIFFERENT FOR EACH NEWS POST[/COLOR]
              echo "<span class='news'>$news</span>\n";
          
              /* get number of comments */
              $comment_query = "SELECT count(*) FROM news_comments " .
                               "WHERE news_id={$row['id']}";
              $comment_result = mysql_query ($comment_query);
              $comment_row = mysql_fetch_row($comment_result);
          
              /* display number of comments with link */
              echo "<a href=\"{$_SERVER['PHP_SELF']}" .
                   "?action=show&amp;id={$row['id']}\">Comments&nbsp;</a>" .
                   "($comment_row[0])\n";
          
              echo "</div>\n";
              echo "<br />\n";
          }
          
          /* if we aren't displaying all news, 
           * then give a link to do so */
          if ($all == 0) {
              echo "<span class='viewall'><a href=\"{$_SERVER['PHP_SELF']}" .
                   "?action=all\">View all</a></span>\n";
          }
          }

            Did you create a php page dedicated to displaying the images? It will in pseudo code be something like:

            read id from HTTP request ala $id = $_GET['id']
            if you didn't get an id, send 404 response
            find image by id in the database, if not found send 404 response
            send appropriate content-type header for the image
            print the image

            ...so if you request that page like "mypage.php?id=1" you should see the image uploaded with post where the post's id is 1.

            That is the first step to get that working. Then where you have the red code in your last post you'd put the img tag with that php page as the "src" attribute: <img src="mypage.php?id=$id" />

            If the post does not have an image you probably don't want to write the <img /> tag or display a default image...its up to you.

              Thanks for your help again.

              I can't get my head around what you've said here: If the post does not have an image you probably don't want to write the <img /> tag or display a default image...its up to you.

              The PHP code I gave in my last post is a sort of template blog post; every blog post will use that code... so if the <img /> tag is in that function, it is used by blog post... so what would happen if a blog entry has no image?

              Also, I understand that the <img /> tag needs anotherpage.php to pull the correct image from the database (image id should correspond with newspost id), but I'm not exactly sure how to code it.

              Thanks again for your help with this.

                Write a Reply...