Form, upload both text fields (to DB) and one image field (to a directory)

I found some code and it simply results in a white screen. I’ve looked over the code and can’t find anything obvious. Maybe someone here can find the problem? The first page (photo_gallery.php) loads and appears to work fine, the result page (imageUpload.php) is just a blank white page. There’s only 3 files, the third is to delete an image. It’s a very simple script that I want to use as a basis to work from.
Here is the code:
photo_gallery.php

<?php
require('connection.php');
  session_start();
?>
<!DOCTYPE html>
<html>
<head>
  <title>Image Gallery</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.css" media="screen">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js"></script>
<style type="text/css">
.gallery
  {
  display: inline-block;
  margin-top: 20px;
  }
.close-icon{
  border-radius: 50%;
  position: absolute;
  right: 5px;
  top: -10px;
  padding: 5px 8px;
  }
.form-image-upload{
  background: #e8e8e8 none repeat scroll 0 0;
  padding: 15px;
  }
</style>
</head>
<body>
<div class="container">
    <h3>Image Gallery</h3>
    <form action="imageUpload.php" class="form-image-upload" method="POST" enctype="multipart/form-data">
        <?php if(!empty($_SESSION['error'])){ ?>
            <div class="alert alert-danger">
                <strong>Whoops!</strong> There were some problems with your input.<br><br>
                <ul>
                    <li><?php echo $_SESSION['error']; ?></li>
                </ul>
            </div>
        <?php unset($_SESSION['error']); } ?>
        <?php if(!empty($_SESSION['success'])){ ?>
        <div class="alert alert-success alert-block">
            <button type="button" class="close" data-dismiss="alert">×</button>
            <strong><?php echo $_SESSION['success']; ?></strong>
        </div>
        <?php unset($_SESSION['success']); } ?>
        <div class="row">
            <div class="col-md-5">
                <strong>Title:</strong>
                <input type="text" name="title" class="form-control" placeholder="Title">
            </div>
            <div class="col-md-5">
                <strong>Image:</strong>
                <input type="file" name="image" class="form-control">
            </div>
            <div class="col-md-2">
                <br/>
                <button type="submit" class="btn btn-success">Upload</button>
            </div>
        </div>
    </form> 
    <div class="row">
    		<div class='list-group gallery'>
            <?php
            
            $sql = "SELECT * FROM image_gallery";
            $images = $mysqli->query($sql);
            while($image = $images->fetch_assoc()){
            ?>
                <div class='col-sm-4 col-xs-6 col-md-3 col-lg-3'>
                    <a class="thumbnail fancybox" rel="ligthbox" href="images/<?php echo $image['image'] ?>">
                        <img class="img-responsive" alt="" src="images/<?php echo $image['image'] ?>" />
                        <div class='text-center'>
                            <small class='text-muted'><?php echo $image['title'] ?></small>
                        </div> <!-- text-center / end -->
                    </a>
                    <form action="imageDelete.php" method="POST">
                    <input type="hidden" name="id" value="<?php echo $image['id'] ?>">
                    <button type="submit" class="close-icon btn btn-danger"><i class="glyphicon glyphicon-remove"></i></button>
                    </form>
                </div> <!-- col-6 / end -->
            <?php } ?>
        </div> <!-- list-group / end -->
    </div> <!-- row / end -->
</div> <!-- container / end -->
</body>
<script type="text/javascript">
    $(document).ready(function(){
        $(".fancybox").fancybox({
            openEffect: "none",
            closeEffect: "none"
        });
    });
</script>
</html>

imageUpload.php

<?php
session_start();
require('connection.php');
if(isset($_POST) && !empty($_FILES['image']['name']) && !empty($_POST['title']))
{
	$name = $_FILES['image']['name'];
	list($txt, $ext) = explode(".", $name);
	$image_name = time().".".$ext;
	$tmp = $_FILES['image']['tmp_name'];
	if(move_uploaded_file($tmp, 'images/'.$image_name))
	{
		$sql = "INSERT INTO image_gallery (title, image) VALUES ('".$_POST['title']."', '".$image_name."')";
		$mysqli->query($sql);
		$_SESSION['success'] = 'Image Uploaded successfully.';
		header("Location: photo_gallery.php");
	}
	else
	{
		$_SESSION['error'] = 'image uploading failed';
		header("Location: photo_gallery.php");
	}
}
else
{
	$_SESSION['error'] = 'Please Select Image or Write title';
	header("Location: photo_gallery.php");
}
?>

imageDelete.php

<?php
session_start();
require('connection.php');
if(isset($_POST) && !empty($_POST['id']))
{
		$sql = "DELETE FROM image_gallery WHERE id = ".$_POST['id'];
		$mysqli->query($sql);
		$_SESSION['success'] = 'Image Deleted successfully.';
		header("Location: photo_gallery.php");
}
else
{
	$_SESSION['error'] = 'Please Select Image or Write title';
	header("Location: photo_gallery.php");
}
?>

I got part of the problem fixed. I made this change -

$result = mysqli_query($link, $sql);
while($row = mysqli_fetch_assoc($result)) {

Now it appears there is a problem with the photo_gallery.php page not displaying the pics that exist in the db, it shows only the red X for the delete function.

I’ll look into it more tomorrow, now it’s time for bed.

You first need to turn on error reporting in PHP as that will help you debug.

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Here’s my scripts to delete an image (I’m using php) ->

<?php

require_once '../private/initialize.php';

use Library\CMS\CMS;

confirm_user_logged_in();
is_session_valid();

$cms = new CMS();
if (isset($_GET['id']) && filter_var($_GET['id'], FILTER_VALIDATE_INT)) {
    /*
     * Delete the image and the record from the database table journal
     */
    $id = filter_var($_GET['id']);
    $image_path = $cms->readImagePath($id);
    $thumb_path = $cms->readThumbPath($id);

    unlink($image_path);
    unlink($thumb_path);
    
    $result = $cms->deleteRecord($id);
    if ($result) {
        header("Location: member_page.php");
        exit();
    } 
}  

second script part of a class

public function deleteRecord(int $id = NULL) {
    $db = DB::getInstance();
    $pdo = $db->getConnection();
    $this->query = "DELETE FROM journal WHERE id=:id";
    $this->stmt = $pdo->prepare($this->query);
    $this->stmt->execute([':id' => $id]);
    return \TRUE;
}

Nothing fancy, but it serves my purpose for my gallery. I just want to show my scripts just to give you an idea. Maybe someone else will come up a more detailed solution.

I’m at a loss of how to get the variables passed without problems. You will see in the processor code some commented out sections as I have been trying different things. But I always get the same result: undefined variable for ALL of the variables being passed.

the error messages:

**Notice** : Undefined variable: title in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**
**Notice** : Undefined variable: para1 in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**
**Notice** : Undefined variable: story in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**
**Notice** : Undefined variable: pubdate in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**
**Notice** : Undefined variable: tags in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**
**Notice** : Undefined variable: fileDescription in **/home/wiegando/public_html/loidamercedes/crud/insert_new_processor.php** on line **66**

For your reference: line 66 is:
$insert_path=“INSERT INTO blogs(title, para1, story, pubdate, tags, picAlt) VALUES(’$title’,’$para1’,’$story’, ‘$pubdate’, ‘$tags’, ‘$fileDescription’)”;


Here is my form:

indent preformatted text by 4 spaces
<?php
switch($_GET['choice'])
{
/* ------------------------------------------------------
----------------- Create a new blog ---------------------
-------------------------------------------------------*/
case 'newBlog':
?>
<form action="insert_new_processor.php?choice=insertBlog" method="post" enctype="multipart/form-data">
<table>
  <tr>
    <th colspan="2" class="textBig w3-padding-32 w3-center">Website Administration - Create a new Blog</th>
  </tr>
  <tr>
    <th class="width25">Title</th>
      <td><input type="text" class="center" name="title" id="title" size="100" placeholder="The title of the blog." /></td>
  </tr>
  <tr>
    <th class="width25">Intro Paragraph</th>
    <td><textarea class="center" name="para1" id="para1" cols="100" rows="5" placeholder="The intro paragraph or two of the story."></textarea></td>
  </tr>
  <script>CKEDITOR.replace( 'para1' );</script>
  <tr>
    <th class="width25">Story</th>
    <td><textarea class="center" name="story" id="story" cols="100" rows="10" placeholder="The rest of the story."></textarea></td>
  </tr>
  <script>CKEDITOR.replace( 'story' );</script>
  <tr>
    <th class="width25">Enter the date of the blog to be displayed.</th>
    <td><input type="text" class="center" name="pubdate" id="pubdate" size="50" placeholder="Use Format: Aug 12, 2019" /></td>
  </tr>
  <tr>
    <th class="width25">Enter some tags. (Some words or 2-word phrases that describe this blog.)</th>
    <td><input type="text" class="center" name="tags" id="tags" size="50" placeholder="fashion clothes jeans t-shirt" /></td>
  </tr>
  <tr>
    <th class="width25">Photo</th>
    <td><input type="file" class="center" name="pic" id="pic" size="50" /></td>
  </tr>
  <tr>
    <th class="width25">Photo Description</th>
    <td><input type="text" class="center" name="picAlt" id="picAlt" size="100" placeholder="Short description of the photo." /></td>
  </tr>
  <tr>
    <th>
    <div class="wide buttonSection pTOr"><button class="center" name="choice" type="submit" value="insertBlog">Submit</button></div>
    </th>
    <td></td>
  </tr>
</table>
</form>
<?php
if(isset($_post['title']) || isset($_post['para1']) ||isset($_post['story']) ||isset($_post['pubdate']) ||isset($_post['tags']) ||isset($_post['pic']) ||isset($_post['picAlt'])) 
{
$title = mysqli_real_escape_string($link, $_POST["title"]);
$para1 = mysqli_real_escape_string($link, $_POST["para1"]);
$story = mysqli_real_escape_string($link, $_POST["story"]);
$pubdate = mysqli_real_escape_string($link, $_POST["pubdate"]);
$tags = mysqli_real_escape_string($link, $_POST["tags"]);
$pic = mysqli_real_escape_string($link, $_POST["pic"]);
$fileDescription = mysqli_real_escape_string($link, $_POST["picAlt"]);
}
break;
?>

And here is the code from the processor page -

<?php
$choice = $_GET["choice"];
?>
<div id="New Blog">
<?php
/* -----------------------------------------------------
----------------- Insert a new blog---------------------
-------------------------------------------------------*/
if ($choice == "insertBlog")
{
  if(isset($_GET['title']) || isset($_GETt['para1']) ||isset($_GET['story']) ||isset($_GET['pubdate']) ||isset($_GET['tags']) ||isset($_GET['pic']) ||isset($_GET['picAlt'])) 
{
//$fileExistsFlag = 0; 
//$fileName = $_FILES['pic']['name'];
  $title = mysqli_real_escape_string($link, $_GET["title"]);
  $para1 = mysqli_real_escape_string($link, $_GET["para1"]);
  $story = mysqli_real_escape_string($link, $_GET["story"]);
  $pubdate = mysqli_real_escape_string($link, $_GET["pubdate"]);
  $tags = mysqli_real_escape_string($link, $_GET["tags"]);
  $pic = mysqli_real_escape_string($link, $_GET["pic"]);
  $fileDescription = mysqli_real_escape_string($link, $_GET["picAlt"]);
}
/*$query = "SELECT * FROM blogs";	
$result = $link->query($query) or die("Error : ".mysqli_error($link));
while($row = mysqli_fetch_array($result)) 
{
      $target = "../images/";		
  $fileTarget = $target.$fileName;	
  $tempFileName = $_FILES["pic"]["tmp_name"];
$result=move_uploaded_file($tempFileName,$fileTarget);									if($result) 
{ 
  echo "Your file <html><b><i>".$fileName."</i></b></html> has been successfully uploaded";		
  $query = "INSERT INTO blogs(title, para1, story, pubdate, tags) VALUES('$title','$para1','$story', '$pubdate', '$tags')";
  if (mysqli_query($link, $query))
  {			
    echo "New record created successfully";
  } 
  else 
  {
    echo "There was an error in section newBlog: " . $query . "<br>" . mysqli_error($link);
  }
}
} */
/*$upload_image=$_FILES[" pic "][ "name" ];*/
/*$folder="../images/";*/
/*move_uploaded_file($_FILES[" pic "][" tmp_name "], "$folder".$_FILES[" pic "][" name "]);*/
$insert_path="INSERT INTO blogs(title, para1, story, pubdate, tags, picAlt) VALUES('$title','$para1','$story', '$pubdate', '$tags', '$fileDescription')";
$var=mysqli_query($link, $insert_path);		
} /* close 'if choice == insertBlog' */	
mysqli_close($link);	
?>
</div> <!-- close 'id=New Blog' -->

You need to start small and get the program logic to work for one or two form fields (the file upload field and one $_POST field), then you can worry about adding the code needed for the rest of the fields.

Here’s a list of things you need to do or not do -

  1. Put the form and the form processing code on the same page. The form processing code goes above the start of the html document. This will simplify all the code and provide a better User eXperience (UX). You can re-populate the form field values when you re-display the form when there are validation errors.
  2. The form processing code needs to detect if a post method form has been submitted before accessing any of the form data. If there is more than one form/processing-code on a page, you would add logic to this to control which form processing code to execute.
  3. Except for un-checked check-boxes/radio-buttons, all other form fields will be set after the form has been submitted, so, using isset() on always-set fields is pointless, and in fact hides mistakes, which is something that’s wrong with the current code (you have the wrong letter-case in the $_post variables, it should be $_POST, a typo in another variable name, and using $_GET where there should be $_POST.)
  4. Don’t use any _escape_string() calls, use prepared queries instead, and use the much simpler PDO extension. A prepared query, while adding only one statement per query, if you use the PDO extension, eliminates the need for the _escape_string statements and it simplifies the sql query syntax, which eliminates a lot of typo mistakes.
  5. Don’t copy variables to other variables without a good reason. One good reason to make a copy of a variable, is if you modify the value in the variable, such as trimming the data. You should trim all the input values so that you can detect if all white-space characters were entered. You can do this using one single php statement by operating on the form data as a set, using php array functions.
  6. You should validate all inputs separately, setting up a unique and helpful error message for each input that is not valid, storing the error messages in an array, using the field name as the array index. This error array is also an error flag. If the array is empty, there are no errors. You would display the contents of this errors array at the appropriate point in the html document.
  7. When the total size of the submitted post method form data exceeds the post_max_size setting, both the $_FILES and $_POST arrays will be empty. You must test for this condition, and set up an error message for the user, before you can reference any of the submitted form data.
  8. Because the uploaded file information will be lost if you don’t save it somewhere, you should test for upload errors, validate the uploaded file information, and process the uploaded file, first, before validating and processing the $_POST data.
  9. The form data will be in $_POST/$_FILES. I don’t know why you wrote out code using $_GET, but since there’s a bunch of isset() statements around them, that code isn’t being executed, nor will it produce any php errors telling you why it isn’t being executed, which is why you are getting the current undefined variable errors. You have too much logic that is not put together so that all the form processing code runs under the same conditions.
  10. Don’t use or die(…) or the other conditional logic you have now for error handling. Use exceptions for database statement errors - connection, query, prepare, and execute, and in most cases let php catch and handle the exception, where it will use its error related settings to control what happens with the actual error information (database statement errors will ‘automatically’ get displayed/logged the same as php errors.) You would then remove any existing error handling logic, simplifying the code.
  11. Why did you put the form processing code inside of a loop that’s looping over all the blogs data? The form processing code belongs above the start of the html document.
  12. Php will destroy all resources when the script ends, so, in most cases, you don’t need to close database connections, close prepared statements, …
  13. When you output dynamic values onto a web page (the form field values), you need to apply htmlentities() to help prevent cross site scripting.

Most of these things will simplify and clean up the code/query, making it easier to see what you are actually trying to accomplish.

1 Like

here’s the latest version, I believe much improved and simplified, and in a file of it’s own now. But I do need to add some code that will prevent it from being submitted empty.

    <?php
  ini_set('display_errors', 1);
  ini_set('display_startup_errors', 1);
  error_reporting(E_ALL);
  
  require_once "../connection.php";
  
  if(isset($_POST['submit'])) 
  {
  	//declare variables
    $alt = mysqli_real_escape_string($link, $_POST["picAlt"]);
    $title = mysqli_real_escape_string($link, $_POST["title"]);
    $para1 = mysqli_real_escape_string($link, $_POST["para1"]);
    $story = mysqli_real_escape_string($link, $_POST["story"]);
    $pubdate = mysqli_real_escape_string($link, $_POST["pubdate"]);
    $tags = mysqli_real_escape_string($link, $_POST["tags"]);
    $pic = $_FILES['pic']['name'];
    $filetmpname = $_FILES['pic']['tmp_name'];
    //folder where images will be uploaded
    $folder = '../images/';
    //function for saving the uploaded images in a specific folder
    move_uploaded_file($filetmpname, $folder.$pic);
    //inserting image details (ie image name) in the database
    $sql = "INSERT INTO blogs (title, para1, story, pic, picAlt, tags, pubdate) VALUES ('$title','$para1','$story','$pic','$alt','$tags','$pubdate')";
    $qry = mysqli_query($link, $sql);
    if( $qry) 
    {
    	header('Location: admin.php'); exit;
    }
    else
    {
    	echo "<br />shit";
    }
	}
    ?>

    <!DOCTYPE html>
    <html>
    <head>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Damion">
    <link rel="stylesheet" href="crud.css">
    <link rel="stylesheet" href="../w3.css">
    <link rel="stylesheet" href="../site.css">
    <script src="ckeditor/ckeditor.js"></script>
    </head>
    <body>
    <form action="" method="post" enctype="multipart/form-data">
    <table>
    <tr>
    <th colspan="2" class="textBig w3-padding-32 w3-center">Website Administration - Create a new Blog</th>
    </tr>
    <tr>
    <th>Choose a Photo: (This is the small circled photo that represents the blog.)</th>
    <td><input type="file" name="pic" /></td>
    </tr>
    <tr>
    <th>Photo Description</th>
    <td><input type="text" class="center" name="picAlt" id="picAlt" size="100" placeholder="A short description of the photo." /></td>
    </tr>
    <tr>
    <th>Title (less than 100 characters)</th>
    <td><input type="text" class="center" name="title" id="title" size="100" placeholder="The title of the blog." /></td>
    </tr>
    <tr>
    <th class="width25">Introduction Paragraph</th>
    <td><textarea class="center" name="para1" id="para1" cols="100" rows="5" placeholder="The intro paragraph or two of the story."></textarea></td>
    </tr>
    <script>
    CKEDITOR.replace( 'para1' );
    </script>	
    <tr>
    <th class="width25">Story</th>
    <td><textarea class="center" name="story" id="story" cols="100" rows="10" placeholder="The rest of the story."></textarea></td>
    </tr>
    <script>
    CKEDITOR.replace( 'story' );
    </script>	
    <tr>
    <th>Date</th>
    <td><input type="date" class="center" name="pubdate" id="pubdate" size="100" placeholder="The date of the blog." /></td>
    </tr>
    <tr>
    <th>Tags</th>
    <td><input type="text" class="center" name="tags" id="tags" size="100" placeholder="Some tags, or keywords, for the blog." /></td>
    </tr>
    <tr>
    <th><span class="center"><div class="wide buttonSection pTOr"><button class="center" name="submit" type="submit" value="submit">Submit</button></div></span></th>
    <td></td>
    </tr>
    </table>
    </form>
    </body>
    </html>

If that’s a question, the method to use has already been posted -

While it looks like you made use of some of the points given, you need to use them all. For example, if the total size of the submitted form data is too large, your current form processing code will be skipped over and the page will just look like it refreshed, without telling the user what was wrong with what they did. If you visited a web page that did that, what would you think?

Thanks for the help, it’s much appreciated. I’m making progress but still have a couple niggling issues -
1: -> Why won’t this maintain the chosen filename when the page is reloaded (due to error(s) in other fields)?
2: -> Why doesn’t textarea mainain the entered text on reloads (same as #1)?
3: I am using this function that is supposed to check the fields and throw up an error before the data is written into the database. Problem is this: the data is written into the db every time the submit button is pressed (bypassing the function). The error messages appear on the screen so the user can fix the problem fields, so that works, but the first time the user pressed the submit button the data with the bad characters was inserted.

<?php
error_reporting(E_ALL);
require_once "../connection.php";

$title = $para1 = $story = $pic = $picAlt = $tags = $pubdate = "";
$titleErr = $picAltErr = $tagsErr = "";

if ($_SERVER["REQUEST_METHOD"] == "POST")
{
    function test_input($data) 
    {
        $data = trim($data);
        $data = stripslashes($data);
        $data = htmlspecialchars($data);
        return $data;
    }	
    if (empty($_POST["title"])) 
    {
        $titleErr = "<br />A title line of the blog is required";
    } 
    else 
    {
        $title = test_input($_POST["title"]);
        // check if name only contains letters and whitespace
        if (!preg_match("/^[a-zA-Z0-9 ]*$/",$title)) 
        {
            $titleErr = "<br />Only letters, numbers, and spaces are allowed.";
        }
    }  
    if (empty($_POST["picAlt"])) 
    {
        $picAltErr = "<br />A description of the photo is required.";
    } 
    else 
    {
        $picAlt = test_input($_POST["picAlt"]);
        // check if name only contains letters and whitespace
        if (!preg_match("/^[a-zA-Z0-9 ]*$/",$picAlt)) 
        {
            $picAltErr = "<br />Only letters, numbers, and spaces are allowed.";
        }
    }
    if (empty($_POST["tags"])) 
    {
        $tagsErr = "<br />At least one tag is required.";
    } 
    else 
    {
        $tags = test_input($_POST["tags"]);
        // check if name only contains letters and whitespace
        if (!preg_match("/^[a-zA-Z0-9 ]*$/",$tags)) 
        {
            $tagsErr = "<br />Only letters, numbers, and spaces are allowed.";
        }
    }
    //folder where images will be uploaded
    $folder = '../images/';
    //Save the uploaded image in the specified folder
    move_uploaded_file($filetmpname, $folder.$pic);
    //insert details into the database
    $sql = "INSERT INTO blogs (title, para1, story, pic, picAlt, tags, pubdate) VALUES ('$title','$para1','$story','$pic','$picAlt','$tags','$pubdate')";
    $qry = mysqli_query($link, $sql);
}
?>
  1. Another issue with the above code is that if a person enters disallowed characters they are not being removed. Isn’t that the purpose of the htmlspecialchars($data) line?

I admit I don’t understand all of your suggestions PHDR, but I will try to implement what I can figure out.

This blog website is to be used by only one person with no other users logging in to it. She will be posting health/fitness blogs, photos, and videos. The blogs will be written in either Spanish (her native language) or English.

And, yes, I could have used a “canned” blog system but then I don’t really learn anything from it.

Sponsor our Newsletter | Privacy Policy | Terms of Service