Using cookies to store auto incremented ID


#1

I’m currently learning php I have designed a form where a user can enter product details which are validated and sent to a database, I need to store the product ID (auto incremented) to a cookie, then retrieve the cookie and display to the user on an update page. I am aware cookies are not good for storing form data but this is for educational purposes. I have provided a copy of the form and validation code, this then calls a file called storefile2 to send details to the database and display on an update page to user. I am stuck on this problem and would appreciate any help. I have added the code for the form and the update page. Thanks

<!DOCTYPE html> 
	<?php				
				$conn = @mysqli_connect("localhost","root","","doorlever"); 
 
				// Check connection  
				if (mysqli_connect_errno() !=0)  //or use if(!$conn)
				{     
					echo "<p>Failed to connect to MySQL, Error: " . mysqli_connect_error()."</p>";    
				}   
				else     
				{     
					//echo "<p>Connected to MySQL</p>"; 
					$pid = mysqli_insert_id($conn);
				} 
	?>	
	<?php
				setcookie('prodID', $pid, time()+ (86400 * 365));
				if(isset($_COOKIE['prodID']))  
				{  
					//echo $_COOKIE['prodID']  . "<br />";  
				}  
				else  
				{       
					echo "Sorry... product ID not found" . "<br />";  
				} 		
	?>
	
	<html lang="en">  
	<head>   
		<meta charset="UTF-8">  
		<title>Assessment 4</title> 
		<link rel="stylesheet" type="text/css" href="css/lever.css"> 
	</head>
	
	<style>    
		.error { color: #FF0000; }   
		.container {width:700px;margin:0 auto;}
		.center {text-align:center;}
		
	</style> 
	<body>  
	
	<?php	     
		$errMessageName ="required field"; 
		$errMessageFinish="required field";
		$errMessageUsage = "required field";
		$errMessageCost="required field";
		$errMessageImage="required field";
		$prodName="";
		$prodFinish="";
		$prodUsage="";
		$prodCost="";
		$prodID= "";
		$invalidData = false; 

		if ($_SERVER["REQUEST_METHOD"] == "POST") {
				
			if(isset($_POST["reset"])){    
					header("Refresh:0");   
					exit();    
			} 
			
			//validate fields	
			$prodName = checkinput($_POST["Name"]);
			$prodFinish = checkinput($_POST["Finish"]);
			$prodUsage = checkinput($_POST["Usage"]);
			$prodCost = checkinput($_POST["Cost"]);
			
			$fileupload = $_FILES['userfile']['name'];
			$filetype = $_FILES['userfile']['type']; 
			$filesize = $_FILES['userfile']['size'];
			$tempname = $_FILES['userfile']['tmp_name'];
			
			$filelocation = "images/$fileupload"; 
			
				if($prodName == "") { 
					$errMessageName = "Product name must not be blank";
					$invalidData = true;
				}     
				elseif ($prodFinish == "") { 
					$errMessageFinish = "Product finish must not be blank";  
					$invalidData = true;
				}     
				elseif ($prodUsage == ""){    
					$errMessageUsage = "Product Usage must not be blank";
					$invalidData = true;
				}     
				elseif (!filter_var($prodCost, FILTER_VALIDATE_FLOAT)) { 
					$errMessageCost = "Please enter a number only in decimal format eg: 1.00"; 
					$invalidData = true;
				} 													
				//make sure a file has been entered   
				elseif($fileupload == "") { 
					$errMessageImage = "Please enter an image";
					$invalidData = true;	
				} 
				//check file type
				elseif (($_FILES['userfile']['type'] != "image/jpg") && ($_FILES['userfile']['type'] != "image/png")  
				&& ($_FILES['userfile']['type'] != "image/jpeg"))
				{   
					$errMessageImage = "Only JPG & PNG files are allowed.";
					$invalidData = true;			
				} 																
				elseif (!move_uploaded_file($tempname,$filelocation)) {   
						switch ($_FILES['userfile']['error'])    
						{     
							case UPLOAD_ERR_INI_SIZE:    
								echo "<p>Error: File exceeds the maximum size limit set by the server</p>" ;   
							break;   
				
							 case UPLOAD_ERR_FORM_SIZE:  
								echo "<p>Error: File exceeds the maximum size limit set by the browser</p>" ;    
							break;       
							
							case UPLOAD_ERR_NO_FILE:    
								echo "<p>Error: No file uploaded</p>" ;   
							break; 
							
							default:    
								echo "<p>File could not be uploaded </p>" ; 
						}	
					}
					else
					{				
			
					$conn = mysqli_connect("localhost:3306","root",""); 
					// Check connection  
					if (mysqli_connect_errno())   
					{   
						echo "<p>Failed to connect to MySQL: " . mysqli_connect_error() . "</p>";   
					}  
   			
			}				
				
				if ($invalidData == false) {   
				include('storefile2.php');
				//Show thank you page    
				//header('Location: update.php');									
				exit();
			    }		
			}
				
			
			function checkInput($inputData) {    
				$inputData = trim($inputData);    
				$inputData = stripslashes($inputData);    
				$inputData = htmlspecialchars($inputData);  
				return $inputData;   
				}
		
		?>
			  
			<div class="container">
			<h1>Acme Hardware</h1>
			<h2>Door Levers - Product Entry Form</h2>
			<h3>Enter the Door Lever Product Details into the form and and click the Submit button</h3>
			
			<p>NOTE: * denotes required entry</p></br>  
			
			<form id="Form1" name="Form" method="post" enctype='multipart/form-data' action=<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>>   
			 
				<label for="Name">Product Name: </label><input type="text" name="Name" id="Name" size="20" value="<?php echo
				$prodName;?>"><span class="error">* <?php echo $errMessageName;?></span><br /><br /> 
				 
				<label for="Finish">Product Finish: </label> <input type="text" name="Finish" id="Finish" size="20" value="<?php echo   
				$prodFinish;?>"><span class="error">* <?php echo $errMessageFinish;?></span><br /><br />
				 
				<label for="Usage">Product Usage: </label><input type="text" name="Usage" id="Usage" size="20" value="<?php echo
				$prodUsage;?>"><span class="error">* <?php echo $errMessageUsage;?></span><br /><br />
				 
				<label for="Cost">Product Cost: </label><input type="text" name="Cost" id="Cost" size="20" value="<?php echo
				$prodCost;?>"><span class="error">* <?php echo $errMessageCost;?></span><br /><br />
				 
				<a href="ProductCost.php">Update product cost</a> <br/><br/>
				<a href="deleteProduct.php">Delete product</a> <br/><br/>
					
				<input type='hidden' name='MAX_FILE_SIZE' value='4000000'/>   
				<label for="userfile">Product image: </label><input type='file' id='userfile' name='userfile'><span class="error">* <?php echo $errMessageImage;?></span></br>
				 
				 <input type="submit" name="submit" value="Submit"/>  
				 <input type ="reset" name="reset" value ="Reset" title="Reset Form"/>  
				 
			</form>   
			</div>
 </body> 
 </html> 
<!--Page Name: storefile2.php
Date: 2/11/18
Author: 
Purpose:  uses the fields posted from the productEntryForm and stores it in the levers table 
the ccokies are stored to and retrieved from the browser settings (eg. Chrome://settings/cookies) as this information can be lost from page to the next (stateless protocol)-->
			
<?php 
 						
		//Open the database and make sure the levers table is present 
		$fileupload = $_FILES['userfile']['name'];
		$filetype = $_FILES['userfile']['type']; 
		$filesize = $_FILES['userfile']['size'];
		$tempname = $_FILES['userfile']['tmp_name']; 
		$filelocation = "images/$fileupload"; 
		//$prodID = "";
		
		include ('update_db.php'); 
		
		 $dbQuery= "INSERT INTO levers(id, prodName, prodFinish, prodUsage, prodCost, imageurl)
						VALUES('$prodID', '$prodName', '$prodFinish', '$prodUsage', '$prodCost', '$filelocation')"; 
		 
		 if (mysqli_query($conn, $dbQuery))    
		 {     
			echo "<!DOCTYPE html>";     
			echo "<html lang='en'>";     
				echo "<head>";      
					echo "<meta charset='UTF-8'>";      
					echo "<title>File Upload</title>"; 
				echo "</head>";  
				echo "<body>"; 
					echo"<h1>Update Page</h1>";
					echo"<p>Thank you. database has been updated</p>";
					$pid = mysqli_insert_id($conn);
					echo"<p>The product ID for this product is <b>".$pid."</b>.<p>";
					echo"<p>File Image: </p>";
					echo"<p><img src='$filelocation' height='300' width='200'></p>";     
					echo"<a href='productEntryForm.php'>Back to Product Entry Form</a>"; 
				echo "</body>";   
			echo "</html>"; 
		}   
		else  
		{   
			echo "<p>Couldn't add the file to the database " . mysqli_error($conn) .  "</p>" ; 
		}
	
?>

#2

Sorry for how this sounds, but this code is filled with bad practices resulting in a wall of unnecessarily complicated code that’s making it harder to get the code to do what you want and for anyone to help with it (cannot see the forest for trees problem.) One of the points of programming is to produce working code as efficiently and effectively as possible.

A list of things you should or should not do -

  1. Create only ONE database connection. Also, you should not use the root user in your application code. Create a specific user with just the necessary permissions that your application needs.
  2. Use exceptions to handle database statement (connection, query, prepare, and execute) errors and in most cases let php catch the exception where it will use its error_reporting, display_errors, and log_errors settings to control what happens with the actual error information. When learning, developing, and debugging code/queries, you would display all errors. When on a live/public server, you would log all errors. You would then remove any error handling logic you have in your code for the database statements. Someone will post an example of how to enable exceptions for whichever database extension you end up using, if you get to this point.
  3. Put the form processing code above the start of the html document (this will allow your setcookie() statement to work as you cannot output anything to the browser prior to sending a cookie.)
  4. Use an array to hold validation error messages. This array is also an error flag. If the array is empty, there are no errors. If the array is not empty, there are errors.
  5. Use an array to hold a trimmed copy of the submitted form data. You can trim all the data at once using a single php statement. Someone will post an example if you get to this point.
  6. Don’t use the checkinput() function you found on the web or were shown in a classroom. In addition to it being improperly named (it’s not checking anything) the only proper thing it is doing is trimming the data. The other things it is doing are either not necessary (there’s no need to use striplslashes) or are incorrect (htmlspecialchars is an output function. You use it when you output values onto a web page. You do not use it on input data as it modifies the value, so any validation will be affected and will result in altered data being stored in the database.
  7. All the inputs should be validated at once, separately. Your use of the elseif() logic means that the validation stops on the first error, so you must submit the form repeatedly to see all the validation errors.
  8. Don’t create variables and copy data from one variable to another for no reason. This is just cluttering up your code, making more typing work for you, and making more things you must keep track of in your code. You even have cases where you copying data to variables, then using the original variables.
  9. When uploading files, you must check for upload errors before you can use any of the uploaded file information. If the total size of the submitted form data exceeds the post_max_size setting, both the $_FILES and $_POST arrays will be empty. After you detect that a post method form was submitted, you must test for this condition, since there will be no $_FILES or $_POST data and the rest of your code will produce a bunch of validation errors that don’t have anything to do with the actual problem. Next, before you start validating the actual uploaded file information (size, mime type, …), you must check the [‘error’] element in the $_FILES data. There’s only valid uploaded data if there is no upload error.
  10. You should not rely on the uploaded file [‘type’] value. It can be set to anything by a hacker and different browsers send different values for the same type of file. You should use one of the php functions to get the mime type of the uploaded file.
  11. You should NOT put external/unknown values directly into an sql query statement. Use a prepared query, with place-holders in the sql statement for each data value, then supply the actual data when you execute the query. Unfortunately, the php mysqli extension’s prepared query programming interface is overly complicated and inconsistent. You should forget about the mysqli extension, and switch to the much simpler php PDO extension.
  12. The browser sends a cookie to the server when it makes the http(s) request. So, a cookie value is not available in the php code until the next http(s) request after it is set. It’s not clear from the posted code/your description, if you expect the cookie value to be immediately available after you set it or if you are navigating to another page or refreshing the current page before you are trying to use the cookie value. The code using the cookie value would first test if it is set, then use it to retrieve the product information.
  13. Your database table should NOT be named levers. A lever is a specific type/category of an item/product. The table should hold all items/products, with a type/category column, and should be named products or similar.

#3
  1. To test if a value is one of several possible values (the mime type), create an array of the permitted values and use in_array() to perform the test. This will save you from having to write out a bunch of conditional logic.

  2. Don’t use the @ error suppressor, ever.

  3. I see that a moderator edited your post so it displays the actual code. Outputting a html document inside a html document results in invalid html. Until you can produce code that works with a valid html document, you should forget about using php include/require statements to paste together code.