Add a product with details (name,quantity,multiple images) and retrieve them in another page

后端 未结 1 1276
逝去的感伤
逝去的感伤 2020-12-20 10:54

Suppose I have a product table with attributes id, name, quantity, image, description. and I have another table image with attributes id, productId, imagepath.

and I

1条回答
  •  半阙折子戏
    2020-12-20 11:35

    Yes, this is how you should do it: a "products" table and a "products_images" table. The later should have a foreign key set: "product_id" column should reference the "id" in "products" table. And both tables must have the "id" columns as primary keys.

    I hope you will understand the code:

    • addProduct.php contains the form and adds a product. getProduct.php displays the details of a selected product.
    • A link will appear after successfully adding a product (in addProduct.php), in order to have a way to display its details in getProduct.php.
    • A directory will be automatically created at the path provided in the config.php file. I set the directory path to "uploads". This path will be prepended to an image filename upon upload and saved in the corresponding column "filename" in "products_images".
    • Multiple file uploads.
    • When you submit the form with the provided product details, the user input values will be validated and corresponding error messages will appear over the form.
    • Beside addProduct.php and getProduct.php, there are two auxiliary files: config.php holds some constants regarding upload; connection.php holds the database connection instance and the constants needed for it.
    • The database access operations are performed using PDO/MySQLi and the so called prepared statements.

    Just test the code as it is, first, so that you see what it does. Of course, after you create the tables as I did (see the create table syntaxes below).

    Good luck.

    Create table syntaxes

    CREATE TABLE `products` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(100) DEFAULT NULL,
      `quantity` int(11) DEFAULT NULL,
      `description` varchar(150) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `products_images` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `product_id` int(11) unsigned DEFAULT NULL,
      `filename` varchar(100) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `product_id` (`product_id`),
      CONSTRAINT `products_images_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    config.php

    PDO solution

    You already have it...

    MySQLi solution (object-oriented style)

    connection.php

    report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    
    /*
     * Create a new db connection.
     * 
     * @see http://php.net/manual/en/mysqli.construct.php
     */
    $connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);
    

    addProduct.php

     $uploadedFileError) {
                    if ($uploadedFileError === UPLOAD_ERR_NO_FILE) {
                        $errors[] = 'You did not provide any files.';
                    } elseif ($uploadedFileError === UPLOAD_ERR_OK) {
                        $uploadedFileName = basename($_FILES['file']['name'][$uploadedFileKey]);
    
                        if ($_FILES['file']['size'][$uploadedFileKey] <= UPLOAD_MAX_FILE_SIZE) {
                            $uploadedFileType = $_FILES['file']['type'][$uploadedFileKey];
                            $uploadedFileTempName = $_FILES['file']['tmp_name'][$uploadedFileKey];
    
                            $uploadedFilePath = rtrim(UPLOAD_DIR, '/') . '/' . $uploadedFileName;
    
                            if (in_array($uploadedFileType, $allowedMimeTypes)) {
                                if (!move_uploaded_file($uploadedFileTempName, $uploadedFilePath)) {
                                    $errors[] = 'The file "' . $uploadedFileName . '" could not be uploaded.';
                                } else {
                                    $filenamesToSave[] = $uploadedFilePath;
                                }
                            } else {
                                $errors[] = 'The extension of the file "' . $uploadedFileName . '" is not valid. Allowed extensions: JPG, JPEG, PNG, or GIF.';
                            }
                        } else {
                            $errors[] = 'The size of the file "' . $uploadedFileName . '" must be of max. ' . (UPLOAD_MAX_FILE_SIZE / 1024) . ' KB';
                        }
                    }
                }
            }
        }
    
        /*
         * Save product and images.
         */
        if (!isset($errors)) {
            /*
             * The SQL statement to be prepared. Notice the so-called markers, 
             * e.g. the "?" signs. They will be replaced later with the 
             * corresponding values when using mysqli_stmt::bind_param.
             * 
             * @link http://php.net/manual/en/mysqli.prepare.php
             */
            $sql = 'INSERT INTO products (
                        name,
                        quantity,
                        description
                    ) VALUES (
                        ?, ?, ?
                    )';
    
            /*
             * Prepare the SQL statement for execution - ONLY ONCE.
             * 
             * @link http://php.net/manual/en/mysqli.prepare.php
             */
            $statement = $connection->prepare($sql);
    
            /*
             * Bind variables for the parameter markers (?) in the 
             * SQL statement that was passed to prepare(). The first 
             * argument of bind_param() is a string that contains one 
             * or more characters which specify the types for the 
             * corresponding bind variables.
             * 
             * @link http://php.net/manual/en/mysqli-stmt.bind-param.php
             */
            $statement->bind_param('sis', $productName, $productQuantity, $productDescription);
    
            /*
             * Execute the prepared SQL statement.
             * When executed any parameter markers which exist will 
             * automatically be replaced with the appropriate data.
             * 
             * @link http://php.net/manual/en/mysqli-stmt.execute.php
             */
            $statement->execute();
    
            // Read the id of the inserted product.
            $lastInsertId = $connection->insert_id;
    
            /*
             * Close the prepared statement. It also deallocates the statement handle.
             * If the statement has pending or unread results, it cancels them 
             * so that the next query can be executed.
             * 
             * @link http://php.net/manual/en/mysqli-stmt.close.php
             */
            $statement->close();
    
            /*
             * Save a record for each uploaded file.
             */
            foreach ($filenamesToSave as $filename) {
                $sql = 'INSERT INTO products_images (
                            product_id,
                            filename
                        ) VALUES (
                            ?, ?
                        )';
    
                $statement = $connection->prepare($sql);
    
                $statement->bind_param('is', $lastInsertId, $filename);
    
                $statement->execute();
    
                $statement->close();
            }
    
            /*
             * Close the previously opened database connection.
             * 
             * @link http://php.net/manual/en/mysqli.close.php
             */
            $connection->close();
    
            $productSaved = TRUE;
    
            /*
             * Reset the posted values, so that the default ones are now showed in the form.
             * See the "value" attribute of each html input.
             */
            $productName = $productQuantity = $productDescription = NULL;
        }
    }
    ?>
    
    
        
            
            
            
            
    
            Save product details
    
            
            
    
        
        
    
            

    Add a product

    ', $errors); } elseif ($productSaved) { echo 'The product details were successfully saved.'; } ?>
    Click me to see the saved product details in getProduct.php (product id: )

    getProduct.php

    prepare($sql);
    
        $statement->bind_param('i', $productId);
    
        $statement->execute();
    
        /*
         * Get the result set from the prepared statement.
         * 
         * NOTA BENE:
         * Available only with mysqlnd ("MySQL Native Driver")! If this 
         * is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in 
         * PHP config file (php.ini) and restart web server (I assume Apache) and 
         * mysql service. Or use the following functions instead:
         * mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
         * 
         * @link http://php.net/manual/en/mysqli-stmt.get-result.php
         * @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
         */
        $result = $statement->get_result();
    
        /*
         * Fetch data (all at once) and save it into an array.
         * 
         * @link http://php.net/manual/en/mysqli-result.fetch-all.php
         */
        $products = $result->fetch_all(MYSQLI_ASSOC);
    
        /*
         * Free the memory associated with the result. You should 
         * always free your result when it is not needed anymore.
         * 
         * @link http://php.net/manual/en/mysqli-result.free.php
         */
        $result->close();
    
        $statement->close();
    
        if (!$products) {
            $errors[] = 'No product found.';
        } else {
            $product = $products[0];
    
            $productName = $product['name'];
            $productQuantity = $product['quantity'];
            $productDescription = $product['description'];
    
            /*
             * Get the images list for the provided product.
             */
            $sql = 'SELECT * 
                    FROM products_images 
                    WHERE product_id = ?';
    
            $statement = $connection->prepare($sql);
    
            $statement->bind_param('i', $productId);
    
            $statement->execute();
    
            $result = $statement->get_result();
    
            $images = $result->fetch_all(MYSQLI_ASSOC);
    
            $result->close();
    
            $statement->close();
    
            $connection->close();
        }
    }
    ?>
    
    
        
            
            
            
            
    
            Product details
    
            
            
        
        
    
            

    Product details

    ', $errors); exit(); } ?>
    Name
    Quantity
    Description
    Images

    0 讨论(0)
提交回复
热议问题