Jump to content
Larry Ullman's Book Forums

Recommended Posts

Good day all,

 

I am new to Php, and trying to edit script 17.1.   I'm running into problems with inserting into database.  After running the script the error message I get is:

 

 

The file has been uploaded!


Warning: mysqli_stmt_bind_param() [function.mysqli-stmt-bind-param]: Number of elements in type definition string doesn't match number of bind variables in C:\xampp\htdocs\dwsite\add_print.php on line 122


Your submission could not be processed due to a system error.

 

 

Line 22 is in blue below

 

My script is below:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title>Add a Print</title>
</head>
<body>
<?php # Script 17.1 - add_print.php
// This page allows the administrator to add a print (product).

require_once ('mysqli_connect.php');

if (isset($_POST['submitted'])) { // Handle the form.
    
    // Validate the incoming data...
    $errors = array();

    // Check for a print name:
    if (!empty($_POST['print_name'])) {
        $pn = trim($_POST['print_name']);
    } else {
        $errors[] = 'Please enter the print\'s name!';
    }
    
    // Check for an image:
    if (is_uploaded_file ($_FILES['image']['tmp_name'])) {
    
        // Create a temporary file name:
        $temp = 'uploads/' . md5($_FILES['image']['name']);
        //$temp = '../../uploads/' . md5($_FILES['image']['name']);
    
        // Move the file over:
        if (move_uploaded_file($_FILES['image']['tmp_name'], $temp)) {
    
            echo '<p>The file has been uploaded!</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;
    }
    
    // Check for a size (not required):
    $s = (!empty($_POST['size'])) ? trim($_POST['size']) : NULL;
    
    // Check for a price:
    if (is_numeric($_POST['price'])) {
        $p = (float) $_POST['price'];
    } else {
        $errors[] = 'Please enter the print\'s price!';
    }
    
    // Check for a description (not required):
    $d = (!empty($_POST['description'])) ? trim($_POST['description']) : NULL;
    
    // Validate the artist...
    if (isset($_POST['property']) && ($_POST['property'] == 'new') ) {
        // If it's a new artist, add the artist to the database...
        
        // Validate the street and accom type names (neither required):
        $fn = (!empty($_POST['accom_type'])) ? trim($_POST['accom_type']) : NULL;
        $mn = (!empty($_POST['street_name'])) ? trim($_POST['street_name']) : NULL;

        // Check for a suburb_name...
        if (!empty($_POST['suburb_name'])) {
            
            $ln = trim($_POST['suburb_name']);
            
            // Add the property to the database:
            $q = 'INSERT INTO properties (accom_type, street_name, suburb_name) VALUES (?, ?, ?)';
            $stmt = mysqli_prepare($dbc, $q);
            if($stmt == false) {
        die("<pre>".mysqli_error($dbc).PHP_EOL.$query."</pre>");
    }  
            mysqli_stmt_bind_param($stmt, 'sss', $fn, $mn, $ln);
            mysqli_stmt_execute($stmt);
            
            // Check the results....
            if (mysqli_stmt_affected_rows($stmt) == 1) {
                echo '<p>The property has been added.</p>';
                $a = mysqli_stmt_insert_id($stmt); // Get the artist ID.
            } else { // Error!
                $errors[] = 'The new property could not be added to the database!';
            }
            
            // Close this prepared statement:
            mysqli_stmt_close($stmt);
            
        } else { // No last name value.
            $errors[] = 'Please enter the property\'s name!';
        }
        
    } elseif ( isset($_POST['property']) && ($_POST['property'] == 'existing') && ($_POST['existing'] > 0) ) { // Existing artist.
        $a = (int) $_POST['existing'];
    } else { // No artist selected.
        $errors[] = 'Please enter or select the print\'s property!';
    }
    
    if (empty($errors)) { // If everything's OK.
    
        // Add the print to the database:
        $q = 'INSERT INTO prints (prop_id, print_name, price, size, description, image_name) VALUES (?, ?, ?, ?, ?, ?)';
        //$stmt = mysqli_prepare($dbc, $q);
        $stmt = mysqli_prepare($dbc, $q);
            if($stmt == false) {
        die("<pre>".mysqli_error($dbc).PHP_EOL.$query."</pre>");
    }  
        mysqli_stmt_bind_param($stmt, 'idddddss', $a, $pn, $p, $s, $d, $i);
        mysqli_stmt_execute($stmt);
        
        // Check the results...
        if (mysqli_stmt_affected_rows($stmt) == 1) {
        
            // Print a message:
            echo '<p>The print has been added.</p>';
            
            // Rename the image:
            $id = mysqli_stmt_insert_id($stmt); // Get the print ID.
            //rename ($temp, "../../uploads/$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);
        
    } // End of $errors IF.
    
    // Delete the uploaded file if it still exists:
    if ( isset($temp) && file_exists ($temp) && is_file($temp) ) {
        unlink ($temp);
    }
    
} // End of the submission IF.

// Check for any errors and print them:
if ( !empty($errors) && is_array($errors) ) {
    echo '<h1>Error!</h1>
    <p style="font-weight: bold; color: #C00">The following error(s) occurred:<br />';
    foreach ($errors as $msg) {
        echo " - $msg<br />\n";
    }
    echo 'Please reselect the print image and try again.</p>';
}

// Display the form...
?>
<h1>Add a Property</h1>
<form enctype="multipart/form-data" action="add_print.php" method="post">

    <input type="hidden" name="MAX_FILE_SIZE" value="524288" />
    
    <fieldset><legend>Fill out the form to add a print to the catalog:</legend>
    
    <p><b>Property Name:</b> <input type="text" name="print_name" size="30" maxlength="60" value="<?php if (isset($_POST['print_name'])) echo htmlspecialchars($_POST['print_name']); ?>" /></p>
    
    <p><b>Image:</b> <input type="file" name="image" /></p>
    
    <div><b>Property:</b>
    <p><input type="radio" name="property" value="existing" <?php if (isset($_POST['property']) && ($_POST['property'] == 'existing') ) echo ' checked="checked"'; ?> /> Existing =>
    <select name="existing"><option>Select One</option>
    <?php // Retrieve all the artists and add to the pull-down menu.
    $q = "SELECT prop_id, CONCAT_WS(' ', accom_type, street_name, suburb_name) FROM properties ORDER BY suburb_name, accom_type ASC";        
    //$r = mysqli_query ($dbc, $q);
    $r = mysqli_query($dbc, $q);
            if($r == false) {
        die("<pre>".mysqli_error($dbc).PHP_EOL.$query."</pre>");
        }
    if (mysqli_num_rows($r) > 0) {
        while ($row = mysqli_fetch_array ($r, MYSQLI_NUM)) {
            echo "<option value=\"$row[0]\"";
            // Check for stickyness:
            if (isset($_POST['existing']) && ($_POST['existing'] == $row[0]) ) echo ' selected="selected"';
            echo ">$row[1]</option>\n";
        }
    } else {
        echo '<option>Please add a new property.</option>';
    }
    mysqli_close($dbc); // Close the database connection.
    ?>
    </select></p>
    
    <p><input type="radio" name="property" value="new" <?php if (isset($_POST['property']) && ($_POST['property'] == 'new') ) echo ' checked="checked"'; ?> /> New =>
    Accomodation Type: <input type="text" name="accom_type" size="10" maxlength="20" value="<?php if (isset($_POST['accom_type'])) echo $_POST['accom_type']; ?>" />
    Street Name: <input type="text" name="street_name" size="10" maxlength="20" value="<?php if (isset($_POST['street_name'])) echo $_POST['street_name']; ?>" />
    Suburb Name: <input type="text" name="suburb_name" size="10" maxlength="40" value="<?php if (isset($_POST['suburb_name'])) echo $_POST['suburb_name']; ?>" /></p>
    </div>
    
    <p><b>Price:</b> <input type="text" name="price" size="10" maxlength="10" value="<?php if (isset($_POST['price'])) echo $_POST['price']; ?>" /> <small>Do not include the dollar sign or commas.</small></p>
    
    <p><b>Size:</b> <input type="text" name="size" size="30" maxlength="60" value="<?php if (isset($_POST['size'])) echo htmlspecialchars($_POST['size']); ?>" /> (optional)</p>
    
    <p><b>Description:</b> <textarea name="description" cols="40" rows="5"><?php if (isset($_POST['description'])) echo $_POST['description']; ?></textarea> (optional)</p>
    
    </fieldset>
        
    <div align="center"><input type="submit" name="submit" value="Submit" /></div>
    <input type="hidden" name="submitted" value="TRUE" />

</form>

</body>
</html>

<body>
</body>
</html>
 

 

Link to comment
Share on other sites

php is very helpful in that it provides error messages that indicate what the error is and where to look.

 

Number of elements in type definition string doesn't match number of bind variables in C:\xampp\htdocs\dwsite\add_print.php on line 122

 

Please look again at this statement and I'm sure you'll spot what the mistake is. The clue is in the NUMBER of bind parameters.

 mysqli_stmt_bind_param($stmt, 'idddddss', $a, $pn, $p, $s, $d, $i);

For future reference, you don't need to post the whole script, just the relevant statements. Also please use code tags when posting code, it makes it easier to read.

  • Upvote 1
Link to comment
Share on other sites

I'm having a similar issue, but I'm pretty sure that it has something to do with the textarea input.

 

When I attempt to insert the description into the prints table it results in a system error, but when I leave it out everything submits.

 

I have tried to isolate the problem by creating a separate description table and adding an error message if it doesn't submit. Anyway, I cannot figure out what is wrong after hours of trying.

 

Here is the isolated code:

 

//check for a description
    $d = (!empty($_POST['desc'])) ? trim($_POST['desc']): NULL;

 

//add the decription to the database
            $q = 'INSERT INTO description (desc) VALUES
            (?)';
            $stmt = mysqli_prepare($dbc, $q);
            mysqli_stmt_bind_param($stmt, 's', $d);
            mysqli_stmt_execute($stmt);
            
            if (mysqli_stmt_affected_rows($stmt)== 1) {
                
                //print a message
                echo '<p>the description has been added</p>';
            }else{echo 'the description could not be added';
            }
          

<p><b>Description</b> <textarea name="desc" cols="40" rows="5">
<?php if(isset($_POST['desc'])) echo $_POST['desc']; ?></textarea> (optional)</p>

 

The mysql table has two fields desc_id (int, 11), and desc (varchar, 255, default NULL)

 

I would actually prefer that the description field be a text instead of varchar, so if I can get this to work, do I need to change the data type from 's' to 'b' or change the bind_param to long_data?

 

Any help would be much appreciated.

Link to comment
Share on other sites

Is the desc_id field in your table auto-incrementing? If not, you will have to explicitly specify it for your INSERT statement or an error will occur. Right after your $stmt = mysqli_prepare($dbc, $q); statement, try putting all of your code within the following if statement:

if ($stmt)

For some reason, if the prepared statement isn't a valid query, an error will be returned, which you can then troubleshoot.

Link to comment
Share on other sites

I agree with HartleySan. The code looks okay. Check the sql statement on its own.

 

As written, the first time you run the above script, your error message will be displayed ("the description could not be added") so you might want to wrap it in an if statement that checks the form has been submitted.

Link to comment
Share on other sites

Thank you.

 

After I checked the sql and the auto-increment (neither was a problem), I thought I would try something new by switching everything that says "desc" to "description" (including the table fields). Now it works, but I'm not entirely sure why. Can anyone give me some insight here? I really want to understand this.

Link to comment
Share on other sites

Here is the original code:

//check for a description
    $d = (!empty($_POST['desc'])) ? trim($_POST['desc']): NULL;

 

//add the decription to the database
            $q = 'INSERT INTO description (desc) VALUES
            (?)';
            $stmt = mysqli_prepare($dbc, $q);
            mysqli_stmt_bind_param($stmt, 's', $d);
            mysqli_stmt_execute($stmt);
            
            if (mysqli_stmt_affected_rows($stmt)== 1) {
                
                //print a message
                echo '<p>the description has been added</p>';
            }else{echo 'the description could not be added';
            }
          

<p><b>Description</b> <textarea name="desc" cols="40" rows="5">
<?php if(isset($_POST['desc'])) echo $_POST['desc']; ?></textarea> (optional)</p>

 

The mysql table has two fields desc_id (int, 11), and desc (varchar, 255, default NULL)

 

 

Here is the new code:

//check for a description
    $d = (!empty($_POST['description'])) ? trim($_POST['description']): NULL;

 

//add the decription to the database
            $q = 'INSERT INTO description (description) VALUES
            (?)';
            $stmt = mysqli_prepare($dbc, $q);
            mysqli_stmt_bind_param($stmt, 's', $d);
            mysqli_stmt_execute($stmt);
            
            if (mysqli_stmt_affected_rows($stmt)== 1) {
                
                //print a message
                echo '<p>the description has been added</p>';
            }else{echo 'the description could not be added';
            }
          

<p><b>Description</b> <textarea name="description" cols="40" rows="5">
<?php if(isset($_POST['description'])) echo $_POST['description']; ?></textarea> (optional)</p>

 

The mysql table is named "description" and the field that I changed was "desc" and is now "description"

Link to comment
Share on other sites

Ah, duh! It didn't hit me the first time I read your post about changing "desc" to "description", but I get it now.

 

"DESC" (case-insensitive) is a keyword in MySQL that's used to order results in descending order (http://php.about.com/od/learnmysql/p/SQL_order_by.htm). As such, if you have a column named "desc" (which you can do), you have to wrap the column name in backticks (`), also sometimes referred to as grave accent marks, to tell the MySQL query interpreter that "desc" should be a column name, and not the keyword DESC.

 

Please note that a backtick is not the same character as a single quote.

Link to comment
Share on other sites

 Share

×
×
  • Create New...