-1

The problem: "Fatal error: Uncaught Error: Call to a member function bindParam() on string in C:\Users\Robert\Webdev_old\UniServerZ\www\PDO_DB\PDO_DB\admin.php:58 Stack trace: #0 {main} thrown in C:\Users\Robert\Webdev_old\UniServerZ\www\PDO_DB\PDO_DB\admin.php on line 58"

It appears when I try to fill in the form and send it to the database. I want all the text stored in a mysql db named "db_test" with a table named "image_gallery" with the structure:

id picName shopName displayStartDate displayEndDate uploadDate uploadPath picFile

Here is the entire code.

    <?php 
    //require_once("inc/pdo.inc.php");
    //print_r(PDO::getAvailableDrivers());
    // error_reporting(E_ALL);
    // ini_set('display_errors', 1);
    error_reporting(E_ERROR);

    if(isset($_POST["submit"]))
    {
      $dsn = 'mysql:host=localhost; dbname=db_test;';
      $user = 'root';
      $pass = 'r00t';

    // Connection in a try/catch block
    try {
          $DBH = new PDO($dsn, $user, $pass);
          $DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        } 
        catch(PDOException $e) {
          echo "Bummer! Somethin' went apeshit!";
          file_put_contents('PDOErrors.txt', $e->getTraceAsString(), FILE_APPEND);
        };


      // // initialize empty  variables partly to avoid indexing issues
      // $DBH = "";
      // $picName = "";
      // $shopName = "";
      // $displayStartDate = "";
      // $displayEndDate = "";
      // $date = "";
      // $uploadPath = "";
      // $picFile = "";
      // $delay = "";   

    try {

       // prepare sql and bind parameters
       $STH = new stdClass();
       $STH = $DBH->prepare->query = ("INSERT INTO image_gallery ( picName, shopName, displayStartDate, displayEndDate, uploadDate, uploadPath, picFile, delay )
 VALUES (:picName,:shopName,:displayStartDate,:displayEndDate,:uploadDate,:uploadPath,:picFile,:delay)"
                                                );

       $STH->bindParam(':picName',          $picName);
       $STH->bindParam(':shopName',         $shopName);
       $STH->bindParam(':displayStartDate', $displayStartDate);
       $STH->bindParam(':displayEndDate',   $displayEndDate);
       $STH->bindParam(':uploadDate',       $uploadDate);
       $STH->bindParam(':uploadPath',       $uploadPath);
       $STH->bindParam(':picFile',          $picFile);
       $STH->bindParam(':delay',            $delay);

       $picName          = $_POST['picName'];
       $shopName         = $_POST['shopName'];
       $displayStartDate = $_POST['displayStartDate'];
       $displayEndDate   = $_POST['displayEndDate'];
       $uploadDate       = $_POST['uploadDate'];
       $uploadPath       = $_POST['uploadPath'];
       $picFile          = $_POST['picFile'];
       $delay            = $_POST['delay'];

        // run query
        $STH->execute();

    } catch (Exception $e) {
            echo "I'm sorry, I'm afraid I can't do that).";
    }
    if (!$mysqli->execute()) {
        print_r($mysqli->error_list);
    }
?>

The HTML form:

  <form action="_admin.php" METHOD="POST">
  <div class="row">
    <div class="columns small-6 large-6">
      <div class="medium-6 small-12 cell  ">
        <label>Bildnamn med kort beskrivning
          <input type="text" name="picName" placeholder="Wella Conditioner 500ml">
        </label>
      </div>
        <br>
       <div class="medium-6 small-12 cell ">
        <label>Butik där bild ska visas

      <fieldset class="medium-6 small-12 cell">
          <input name="shopName" type="checkbox"><label for="checkbox1">Alla</label>
          <input name="shopName" type="checkbox"><label for="checkbox2">Malmö</label>
          <input name="shopName" type="checkbox"><label for="checkbox3">3</label>
          <input name="shopName" type="checkbox"><label for="checkbox1">4</label>
          <input name="shopName" type="checkbox"><label for="checkbox2">5</label>
          <input name="shopName" type="checkbox"><label for="checkbox3">6</label>
        </fieldset>     
      </label>
      </div>
        <br>

       <div class="medium-6 small-12 cell ">
        <label>Startdatum för bildens visning
          <input type="text" name="displayStartDate">
        </label>
      </div>
      <br>

      <div class="medium-6 small-12 cell ">
        <label>Slutdatum för bildens visning
          <input type="text" name="displayEndDate">
        </label>
      </div>
      <br>


      <div class="medium-6 small-12 cell ">
        <label>Antal sekunder bilden ska visas
          <input type="number" name="delay">
        </label>
      </div>
      <br>


      <input type="hidden" name="uploadPath">
      <input type="hidden" name="uploadDate">
      <input type="submit" name="submit" value="Ladda upp &#x27a4;" class="sub-style">

    </div>
  </div>
</form>

I coded a lot of PHP back in the late 90's, but ever since it's been on and off so I am a bit rusty. Hugely appreciate any and all help. Thank you all in advance!

rob75
  • 1
  • 1
  • 6

1 Answers1

0
  • Read the php.net documentation for EACH function that you're using. In this case, the main problem lies in the line $STH = $DBH->prepare->query = ("...");, as @YourCommonSense already showed you.
  • So, either use just PDO::query, or PDO::prepare followed by PDOStatement::execute. Don't mix them.
  • Another problem: $STH = new stdClass();. It has no use.
  • Also, you can not define the variables passed to PDOStatement::bindParam after the method call.
  • Further: $mysqli->execute() and $mysqli->error_list are related to a mysqli connection. You should decide to use either PDO, or mysqli, but not both.
  • Read the materials recommended by @YourCommonSense and other materials on the subject, like PDO Tutorial for MySQL Developers.
  • You don't need try-catch blocks for the base db operations. Let the PHP engine throw the errors/exceptions, and handle them correspondingly, as explained here and here, at least.
  • Don't use PDO::setAttribute. Pass the driver-specific connection options as array, when creating the PDO instance.

The code bellow shows you how all fits together.

Good luck.

<?php

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'db_test');
define('USERNAME', 'root');
define('PASSWORD', 'r00t');
define('CHARSET', 'utf8');

// Error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1); // SET IT TO 0 ON A LIVE SERVER!

/*
 * Create a PDO instance as db connection to db.
 * 
 * @link http://php.net/manual/en/class.pdo.php
 * @link http://php.net/manual/en/pdo.constants.php
 * @link http://php.net/manual/en/pdo.error-handling.php
 * @link http://php.net/manual/en/pdo.connections.php
 */
$connection = new PDO(
        sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s', HOST, PORT, DATABASE, CHARSET)
        , USERNAME
        , PASSWORD
        , [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => FALSE,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
);

if (isset($_POST['submit'])) {
    $picName = $_POST['picName'];
    $shopName = $_POST['shopName'];
    $displayStartDate = $_POST['displayStartDate'];
    $displayEndDate = $_POST['displayEndDate'];
    $uploadDate = $_POST['uploadDate'];
    $uploadPath = $_POST['uploadPath'];
    $picFile = $_POST['picFile'];
    $delay = $_POST['delay'];

    /*
     * The SQL statement to be prepared. Notice the so-called named markers.
     * They will be replaced later with the corresponding values from the
     * bindings array when using PDOStatement::bindValue.
     * 
     * When using named markers, the bindings array will be an associative
     * array, with the key names corresponding to the named markers from
     * the sql statement.
     * 
     * You can also use question mark markers. In this case, the bindings 
     * array will be an indexed array, with keys beginning from 1 (not 0).
     * Each array key corresponds to the position of the marker in the sql 
     * statement.
     * 
     * @link http://php.net/manual/en/mysqli.prepare.php
     */
    $sql = 'INSERT INTO image_gallery (
                picName,
                shopName,
                displayStartDate,
                displayEndDate,
                uploadDate,
                uploadPath,
                picFile,
                delay
            ) VALUES (
                :picName,
                :shopName,
                :displayStartDate,
                :displayEndDate,
                :uploadDate,
                :uploadPath,
                :picFile,
                :delay
            )';

    /*
     * The bindings array, mapping the named markers from the sql
     * statement to the corresponding values. It will be directly 
     * passed as argument to the PDOStatement::execute method.
     * 
     * @link http://php.net/manual/en/pdostatement.execute.php
     */
    $bindings = [
        ':picName' => $picName,
        ':shopName' => $shopName,
        ':displayStartDate' => $displayStartDate,
        ':displayEndDate' => $displayEndDate,
        ':uploadDate' => $uploadDate,
        ':uploadPath' => $uploadPath,
        ':picFile' => $picFile,
        ':delay' => $delay,
    ];

    /*
     * Prepare the sql statement for execution and return a statement object.
     * 
     * @link http://php.net/manual/en/pdo.prepare.php
     */
    $statement = $connection->prepare($sql);

    /*
     * Execute the prepared statement. Because the bindings array
     * is directly passed as argument, there is no need to use any
     * binding method for each sql statement's marker (like
     * PDOStatement::bindParam or PDOStatement::bindValue).
     * 
     * @link http://php.net/manual/en/pdostatement.execute.php
     */
    $executed = $statement->execute($bindings);

    /*
     * Close the prepared statement.
     * 
     * @link http://php.net/manual/en/pdo.connections.php Example #3 Closing a connection.
     */
    $statement = NULL;
}
  • Thank you so much for taking the time to write so extensively and professionally. I really appreciate it @aendeerei! :) However the data from the form is not saved when i input data. I'm sure there's a small mistake and easily fixed. If your curious how my form looks look at my original question. Thank you again! :D – rob75 Nov 23 '17 at 08:28
  • Sorry for chasing you again but JFYI: [The key thing to understand about persistent connections is that you should NOT use them in most web applications](https://stackoverflow.com/questions/3332074/what-are-the-disadvantages-of-using-persistent-connection-in-pdo) – Your Common Sense Nov 23 '17 at 11:40
  • @YourCommonSense No, please do it. And no need for "sorry". I learned to appreciate your advices. I will read the answer today and reedit correspondingly. Thank you! –  Nov 23 '17 at 11:53
  • @rob75 You are welcome. Put the code, form and db insert code (without all that long comments), in a new question. Then you'll find out, where the problems reside. I'll come back to reedit my answer here, after I find out, if that persistent connection attribute is indeed needed. –  Nov 23 '17 at 12:12
  • @ aendeerei: I posted a new question here https://stackoverflow.com/questions/47456731/how-to-upload-image-into-database-in-a-long-range-of-mysql-queries-with-pdo-and – rob75 Nov 23 '17 at 13:31
  • @YourCommonSense Thanks for the link regarding persistent connections. Interesting thing. –  Nov 23 '17 at 23:22