Jump to content
Larry Ullman's Book Forums
hbphoto

Chapter 11, Page 316 - Adding Products

Recommended Posts

Hello:

 

The script for uploading products works perfectly. I have two questions:

 

One, what do I modify in the script to allow for multiple file uploads? Uploading one file at a time is time consuming. I would like to select multiple files.

 

Two, how do I change the script to rename the tmp_name of the file back to the original name of the file? I'm a product photographer and the files are named according to SKU number. The random string new_name file will be difficult for the client to use.

 

On a side note, I select to follow the topics and I do not receive email notifications when replies are posted.

 

Thank you.

Share this post


Link to post
Share on other sites

Hey buddy, it would be wise getting a copy of Larry's other book PHP and MySQL for Dynamic Web Sites Fourth Edition, this actually has a lot of answers to these questions you are asking here. The book you are working through here did assume you has knowledge from the book i am mentioning now.

Share this post


Link to post
Share on other sites

Hi,

 

I bought the PHP and MySQL for Dynamic Web Sites Fourth Edition as you suggested. The content of this book is pretty much the same as the one I have titled PHP 6 and MySQL 5. Neither of these books, from what I can see, mention multiple file uploads.

 

If it happens to be in the book, can you point me to the section?

Share this post


Link to post
Share on other sites

I'm not sure uploading multiple files is covered in the book but you can do this by adding additional input fields to your form e.g.

<input name="myfiles[]" type="file" />
<input name="myfiles[]" type="file" />

You will be able to get information about the files via the $_FILES global array including the original filename. Check out the php manual re $_FILES and multiple file uploads.

  • Upvote 2

Share this post


Link to post
Share on other sites

To be clear, "PHP and MySQL for Dynamic Web Sites" 4th edition is the next edition of the same book after the "PHP 6 and MySQL 5 for Dynamic Web Sites" book, which is the third edition in the same series. Sorry you ended up accidentally buying both.

Share this post


Link to post
Share on other sites

I'm not sure uploading multiple files is covered in the book but you can do this by adding additional input fields to your form e.g.

<input name="myfiles[]" type="file" />
<input name="myfiles[]" type="file" />

You will be able to get information about the files via the $_FILES global array including the original filename. Check out the php manual re $_FILES and multiple file uploads.

 

With the code written as above, can I put the file from the first input into a field in the table called ORIGINAL and the file from the secon input into a field in the table called THUMB?

Share this post


Link to post
Share on other sites

Yes.

 

Or instead of having to refer to the myfiles[] aray you could name each input:

 

<input name="original" type="file">
<input name="thumb" type="file">

 

and then refer to each file by the name.

Share this post


Link to post
Share on other sites

Ok, great, that's exactly what I have.

 

I guess where I'm stumped is after the form is submitted, how do I process both images through validation and moving to and from the temporary directory?

Share this post


Link to post
Share on other sites

The same way you validate one uploaded file (as I believe demonstrated in the book); you'd just do it once for each upload. Arguably, though, it'd be better to have the user upload one image and have the system create the thumbnail automatically.

  • Upvote 1

Share this post


Link to post
Share on other sites

hbphoto, you simply have to iterate over the $_FILES array and then do the normal processing within the loop.

 

Generating the thumbnail server side is definitely easier for the user.

 

We built an application for a professional photographer early this year and what we found was that photographers want complete control over how the thumbnail image looks. Judging from hbphoto's username I'm guessing he/she might be in the same position.

 

For the application we delivered, one original image was uploaded, several predefined sized images were generated, then it took her to a page where she could create the thumbnail using a javascript draggable crop tool with live feedback on the page showing what the thumbnail would look like; which maybe also be an option for you hbphoto?

Share this post


Link to post
Share on other sites

Yes, I'm a product photographer. I want my clients to sign into the website and view their photos so they can decide which ones they want. I want them brought to a page with thumbnails and then they can click on a thumbnail and a larger photo appears.

 

As for the size of the thumbnails, I have a size which works very well.

 

My one concern regarding automatically generating the thumbnails is that the page may take a long time to load. If there is an efficient way of doing this, I'm all ears.

Share this post


Link to post
Share on other sites

I was able to finally solve uploading both images to the directory.

 

I'm trying to insert the information to the table and I'm receiving the following error message:

 

An error occurred in script 'add_image.php' on line 195: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given

 

My connection to the database works because I have a select statement in my form to create a drop down list of my clients.

 

I also made sure that the number of '?' marks equal the number of columns in my table. Also, I made sure that I have the same number of bind parameters for each variable.

 

I'm not sure what else I can do to troubleshoot this.

 

Can someone lend me a hand? Thank you in advance. Here is the INSERT code.

$q = 'INSERT INTO photo (client_id, photo_name, description, image_original, image_thumb) VALUES (?, ?, ?, ?, ?,)';
	$stmt = mysqli_prepare($dbc, $q);
Line 195:	mysqli_stmt_bind_param($stmt, 'issss', $c, $pn, $d, $oi, $ti);
	mysqli_stmt_execute($stmt);

Share this post


Link to post
Share on other sites
My one concern regarding automatically generating the thumbnails is that the page may take a long time to load. If there is an efficient way of doing this, I'm all ears.

You generate the thumbnail image once at the point of uploading the original file. So, when a public facing page, like your gallery page, is requested by a user, the page simply makes the call to an image: the thumbnail has already been generated.

 

I was able to finally solve uploading both images to the directory.

 

Please share solutions, it's really helpful to all users and makes the thread more beneficial and a resource in the future.

 

For your prepared statement remove the comma after the final ? parameter marker.

Share this post


Link to post
Share on other sites

Hi,

 

I created two input fields in my form named image and image1. The code I used to process the upload looks like this. The code here uploads the first image. I then copied and pasted this same exact code underneath and changed everything that referenced "image" to "image1". And that's about it.

if (is_uploaded_file ($_FILES['image']['tmp_name']) && ($_FILES['image']['error'] == UPLOAD_ERR_OK)) {

	$file = $_FILES['image'];

	$size = ROUND($file['size']/1024);

	// Validate the file size:
	if ($size > 99999999999) {
		$errors['image'] = 'The uploaded file was too large.';
	} 

	// Validate the file type:
	$allowed_mime = array ('image/gif', 'image/pjpeg', 'image/jpeg', 'image/JPG', 'image/X-PNG', 'image/PNG', 'image/png', 'image/x-png');
	$allowed_extensions = array ('.jpg', '.gif', '.png', 'jpeg');
	$image_info = getimagesize($file['tmp_name']);
	$ext = substr($file['name'], -4);
	if ( (!in_array($file['type'], $allowed_mime)) 
	||   (!in_array($image_info['mime'], $allowed_mime) ) 
	||   (!in_array($ext, $allowed_extensions) ) 
	) {
		$errors['image'] = 'The uploaded file was not of the proper type.';
	} 

	// Move the file over, if no problems:
	if (!array_key_exists('image', $errors)) {

		// Create a new name for the file:
		$oi = $file['name'];

		// Move the file to its proper folder but add _tmp, just in case:
		$dest =  "../photography/uploads/$oi";

		if (move_uploaded_file($file['tmp_name'], $dest)) {

			// Store the data in the session for later use:
			$_SESSION['image']['oi'] = $oi;
			$_SESSION['image']['file_name'] = $file['name'];

			// Print a message:
			echo '<h4>The file has been uploaded!</h4>';

		} else {
			trigger_error('The file could not be moved.');
			unlink ($file['tmp_name']);				
		}

	} // End of array_key_exists() IF.

} elseif (!isset($_SESSION['image'])) { // No current or previous uploaded file.
	switch ($_FILES['image']['error']) {
		case 1:
		case 2:
			$errors['image'] = 'The uploaded file was too large.';
			break;
		case 3:
			$errors['image'] = 'The file was only partially uploaded.';
			break;
		case 6:
		case 7:
		case 8:
			$errors['image'] = 'The file could not be uploaded due to a system error.';
			break;
		case 4:
		default: 
			$errors['image'] = 'No file was uploaded.';
			break;
	} // End of SWITCH.

} // End of $_FILES IF-ELSEIF-ELSE.

 

 

Share this post


Link to post
Share on other sites

HTML 5 allows this kind of multiple upload input

<p>Upload an image:</b> <input type="file" name="image" multiple/></p>

so I'm wondering, has anyone come up with a fancy fix for dealing with the extreme awkwardness of $_FILES arrays? I'm having way too much trouble figuring out a count/foreach method for this. What I have is comically incomplete because I keep trying new things, but I'm also afraid to break what I already have that works. Any suggestions?

	if(isset($_POST['image'])){
		$count=0 
                foreach (($_FILES['image']['tmp_name']) as $tmp)

        //This is as far as I get before becoming hopelessly confused as to what should be done next. 
        //As you can see, the rest is pretty much from the book.

		if (is_uploaded_file ($_FILES['image']['tmp_name'])) {
		//create temporary file name
		$temp = '../../uploads/'. md5($_FILES['image']['name']);
		//Move the file over.
			if (move_uploaded_file($_FILES['image']['tmp_name'], $temp)){
				//echo '<p class="marked"><em>The file has been uploaded!</em></p>';
				//set the $i variable to the image's name
				$i = $_FILES['image']['name']; 
				} else {//couldn't move the file over
					$errors[] = 'the file could not be moved';
					$temp = $_FILES['image']['tmp_name'];
				}
				
	}else{//no uploaded file
		$errors[] = 'No file was uploaded';
		$temp = NULL;
	}

if (empty($errors)){ //if everything is ok
				
				//add the image to the database
			$q = 'INSERT INTO image (image_name, img_type, coll_id) VALUES
			(?, ?, ?)';
			$stmt = mysqli_prepare($dbc, $q);
			mysqli_stmt_bind_param($stmt, 'ssi', $i, $it, $cid);
			mysqli_stmt_execute($stmt);
			$img_id = mysqli_stmt_insert_id($stmt);
			
			if (mysqli_stmt_affected_rows($stmt)== 1) {
				
				//print a message
				//echo '<p class="marked">the img has been added</p>';
			}else{ echo 'the img could not be added';
			}
			
			//Check the results
			if (mysqli_stmt_affected_rows($stmt)== 1) {
				
				//print a message
				//echo '<p class="marked">the image has been added</p>';
				
				//rename the image
				$id = mysqli_stmt_insert_id($stmt);//Get the image id
				rename($temp, "../../uploads/$id");
				
				//Clear $_POST
				$_POST = array();
			}else{//Error!
				echo '<p>Your submission could not be processed due to a system error.</p>';
			}
			mysqli_stmt_close($stmt);
			

Share this post


Link to post
Share on other sites

This is where I got to since last night (adapted from http://stackoverflow.com/questions/12766035/php-upload-multiple-files):

 

I am getting an error from the insert query("system error"), so I think the multiple upload might actually be working. How do I loop the insert query? Should I include it in the first IF statement, or would this be hackish? Am I getting ahead of myself?

		//Check for an image
		if(isset($_POST['image'])){
			$count=0;
			foreach (($_FILES['image']['tmp_name']) as $file){			
		if (is_uploaded_file ($file)) {
		//create temporary file name
		$temp = '../../uploads/'. md5($_FILES['image']['name']);
		$tmp=$_FILES['image']['tmp_name'][$count];
                $count=$count + 1;
		 $temp=$temp.basename($file);
		//Move the file over.
			if (move_uploaded_file($file, $temp)){
				//echo '<p class="marked"><em>The file has been uploaded!</em></p>';
				//set the $i variable to the image's name
				$i = $_FILES['image']['name'][$count]; 
				} else {//couldn't move the file over
					$errors[] = 'the file could not be moved';
					$temp = $file;
				}
			}
		}
	}else{//no uploaded file
		$errors[] = 'No file was uploaded';
		$temp = NULL;
	}
if (empty($errors)){ //if everything is ok
        
          //add the image to the database
            $q = 'INSERT INTO image (image_name) VALUES
            (?)';
            $stmt = mysqli_prepare($dbc, $q);
            mysqli_stmt_bind_param($stmt, 's', $i);
            mysqli_stmt_execute($stmt);
            $img_id = mysqli_stmt_insert_id($stmt);
            
            if (mysqli_stmt_affected_rows($stmt)== 1) {
                
                //print a message
                //echo '<p class="marked">the img has been added</p>';
            }else{ echo 'the img could not be added';
            }
            
            //Check the results
            if (mysqli_stmt_affected_rows($stmt)== 1) {
                
                //print a message
                //echo '<p class="marked">the image has been added</p>';
                
                //rename the image
                $id = mysqli_stmt_insert_id($stmt);//Get the image id
                rename($temp, "../../uploads/$id");
                
                //Clear $_POST
                $_POST = array();
            }else{//Error!
                echo '<p style="font-weight:bold; color: #C00">Your submission could not be processed due to a system error.</p>';
            }
            mysqli_stmt_close($stmt);

Share this post


Link to post
Share on other sites

You loop a query by invoking the mysqli_stmt_execute($stmt); line within the loop, assuming that the values of the bound variables would be different within each iteration of the loop as well. 

Share this post


Link to post
Share on other sites

I'm afraid that I'm barely beyond "monkey see, monkey do" when it comes to query loops and I can't find an adaptable example (did I miss something in the book? I'm not quite all the way through). Would you mind adding an example, please?

Share this post


Link to post
Share on other sites

Okay, it'd be something like this:

 

 

$q = 'INSERT INTO image (image_name) VALUES (?)';
$stmt = mysqli_prepare($dbc, $q);
mysqli_stmt_bind_param($stmt, 's', $i);
foreach ($whatever_array as $i) {
    mysqli_stmt_execute($stmt);
}
So if you had an array of image names, you'd loop through that array and create a unique $i value within the loop and execute the statement. If you needed to do other stuff (such as handle the file upload, dynamically determine the value of $i, etc.), you'd also do that in the loop.

Share this post


Link to post
Share on other sites

I'm officially stumped. Now I'm getting a blank screen.

 

Here is the state of things. I feel like I'm close, but can't quite put my finger on the problem. I thought it was the code at first (and fooled around with it forever), but then I caught a problem with the form (no [] included, duh), then I started from scratch and something went wrong somewhere.

 

The form:

	<p>Upload images: <input type="file" name="image[]" multiple/></p>

The process:

//Check for an image
		if (is_uploaded_file ($_FILES['image']['tmp_name'])){
			for($i=0; $i<count($_FILES['image']['name']); $i++) {
			  //Get the temp file path
			  $tmp = $_FILES['image']['tmp_name'][$i];
			
			  //Make sure there is a filepath
			  if ($tmp != ""){
				//Setup new file path
				$temp = "../../uploads/" . $_FILES['image']['name'][$i];
				//Move the file over.
					if (move_uploaded_file($tmp, $temp)){
						echo '<p class="marked"><em>The file has been uploaded!</em></p>';
						//set the $i variable to the image's name
						$i = $_FILES['image']['name'][$i]; 
						} else {//couldn't move the file over
							$errors[] = 'the file could not be moved';
							$temp = $_FILES['image']['tmp_name'];
						}
					}
				}
		
	}else{//no uploaded file
		$errors[] = 'No file was uploaded';
		$temp = NULL;
	}

The Insert:

//add the image to the database
			$q = 'INSERT INTO image (image_name) VALUES
			(?)';
			$stmt = mysqli_prepare($dbc, $q);
			mysqli_stmt_bind_param($stmt, 's', $i);
			foreach($_FILES['image']['name'][$i] as $i){
			mysqli_stmt_execute($stmt);
			$img_id = mysqli_stmt_insert_id($stmt);
			
			if (mysqli_stmt_affected_rows($stmt)>0) {
				
				//print a message
				echo '<p class="marked">the img has been added</p>';
			}else{ echo 'the img could not be added';
			
			
			//Check the results
			if (mysqli_stmt_affected_rows($stmt)>0) {
				
				//print a message
				echo '<p class="marked">the image has been added</p>';
				
				//rename the image
				$id = mysqli_stmt_insert_id($stmt);//Get the image id
				rename($temp, "../../uploads/$id");
				
				//Clear $_POST
				$_POST = array();
			}else{//Error!
				echo '<p style="font-weight:bold; color: #C00">Your submission could not be processed due to a system error.</p>';
			}
			mysqli_stmt_close($stmt);
			}

Share this post


Link to post
Share on other sites

Welp, after four days on this, I'm done (for now anyway). Your next book (I have three - just started on the "advanced..." book) really should include a tutorial on this. It seems like it should be reasonably easy to figure out, but with all the loops, counts, and array issues, there are really too many things that could go wrong. It's difficult for a semi-beginner (me) to even identify a problem.

 

Thanks anyway.

Share this post


Link to post
Share on other sites

I was able to finally solve uploading both images to the directory.

 

I'm trying to insert the information to the table and I'm receiving the following error message:

 

An error occurred in script 'add_image.php' on line 195: mysqli_stmt_bind_param() expects parameter 1 to be mysqli_stmt, boolean given
My connection to the database works because I have a select statement in my form to create a drop down list of my clients.

 

I also made sure that the number of '?' marks equal the number of columns in my table. Also, I made sure that I have the same number of bind parameters for each variable.

 

I'm not sure what else I can do to troubleshoot this.

 

Can someone lend me a hand? Thank you in advance. Here is the INSERT code.

$q = 'INSERT INTO photo (client_id, photo_name, description, image_original, image_thumb) VALUES (?, ?, ?, ?, ?,)';
		$stmt = mysqli_prepare($dbc, $q);
Line 195:	mysqli_stmt_bind_param($stmt, 'issss', $c, $pn, $d, $oi, $ti);
		mysqli_stmt_execute($stmt);

Looks like a comma too many in the VALUES after the last  question mark.

Share this post


Link to post
Share on other sites

I have question. When I run the register.php page , I keep receiving this error:

 

An error occurred in script 'C:\XAMPP\htdocs\discounts\html\includes\mysql.inc.php' on line 18:
mysqli_connect(): (HY000/1045): Access denied for user 'username'@'localhost' (using password: YES)

 

Anyone can help please

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...