1

I'm new to PHP, so please have patience.

I'm writing a PHP snippet to retrieve a complex data structure from a MySQL database. (Think "has a" object relationship.) I have a single SQL query that translates the results into a list of PHP objects. Those PHP objects contain PHP objects (sometimes in the form of arrays) defined in other MySQL tables. Thus, the constructor of the first object must do its own SQL query, when constructed, to build the inner object(s). Unfortunately, I'm not used to doing this, so I keep getting this error:

Database error: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

How do I set this up so that when I call get_tickets.php, it doesn't have these SQL query issues?

config.php

<?php
  // These variables define the connection information for your MySQL database
  $dbhost = '####';
  $dbuser = '####';
  $dbpass = '####';
  $dbname = '####';

  $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');

  // Attempt to connect to the database
  try {
    $db = new PDO("mysql:host={$dbhost};dbname={$dbname};charset=utf8",
                     $dbuser, $dbpass, $options);
  } catch (PDOException $ex) {
     die("Failed to connect to the database: " . $ex->getMessage());
  }

  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

  // Disable magic quotes
  if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
  {
      function undo_magic_quotes_gpc(&$array)
      {
          foreach($array as &$value)
          {
              if(is_array($value))
              {
                undo_magic_quotes_gpc($value);
              }
              else
              {
                  $value = stripslashes($value);
              }
          }
      }
      undo_magic_quotes_gpc($_POST);
      undo_magic_quotes_gpc($_GET);
      undo_magic_quotes_gpc($_COOKIE);
  }

  // Tell browser to use UTF-8 encoding
  header('Content-Type: text/html; charset=utf-8');

  // Start the session
  if(!isset($_SESSION)){
      session_start();
  }  
?>

get_tickets.php

<?php
  require_once('config.php');
  require('data_access_objects.php');

  // Check for hash
  if (isset($_POST['hash'])) { 
    // Get user's hash
    $hash = $_POST['hash'];

    // Result array to return
    $results = Array();

    try {
      // Get all ticket entries
      $query = "SELECT *
                  FROM tickets 
                  WHERE user = (
                    SELECT id 
                    FROM users 
                    WHERE hash = :hash)";
      $stmt = $db->prepare($query);
      $stmt->bindValue(':hash', $hash, PDO::PARAM_STR);
      $stmt->execute();

      // Convert cursor entries into class objects
      while($row = $stmt->fetch()) {
        array_push($results, new Ticket($row['id'], $row['status'], $row['room'], 
                     $row['location'], $row['gps_loc'], $row['subject'],
                     $row['picture'], NULL));
      }

      // Display resulting array entries
      echo json_encode(array_values($results));
    } catch (PDOException $ex) {
      // Display generic error on page
      echo 'Database error: ' . $ex->getMessage();
    }
  } else {
    // Failed, return nothing
    echo '';
  }
?>

data_access_objects.php

<?php
  /* Room data access object structure */
  class Room
  {
    var $id;
    var $name;
    var $building;

    function __construct($id, $name, $building)
    {
      $this->id = $id;
      $this->name = $name;
      $this->building = $building;
    }
}

/* Ticket data access object structure */
class Ticket
{
    var $id;
    ...
    var $room;
    ...
    var $messages = Array();

    function __construct($id, $status, $room, $location, $gpsLocation, 
                           $subject, $picture, $messages)
    {
      $this->id = $id;
      ...
      $this->retrieveRoom($room);
      ...
      $this->messages = $messages;
    }

    private function retrieveRoom($room_id)
    {
      require_once('config.php');
      try {
        // Get all ticket entries
        $query = "SELECT *
                    FROM rooms 
                    WHERE id = :room_id)";
        $stmt = $db->prepare($query);
        $stmt->bindValue(':id', $room_id, PDO::PARAM_INT);
        $stmt->execute();

        // Convert cursor entrie into room object
        $row = $stmt->fetch();
        $this->room = new Room($row['id'], $row['name'], $row['building']);
      } catch (PDOException $ex) {
        // Display generic error on page
        echo 'Database error: ' . $ex->getMessage();
      }''
    }
    ...
  }
?>

1 Answer 1

1

Looks like PDO is complaining about invalid parameters, I'd check exactly whats being bound for your method:

private function retrieveRoom($room_id)

For protection qualify that the $room_id is numeric before issuing a query.

I will add though your current method is inefficient. You should be condensing your query and creating your objects off joined records.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your reply. I accept that this is inefficient. Anyways, I'm now getting a new error > Notice: Undefined variable: db in D:\xampp\htdocs\castisy\json_queries\data_access_objects.php on line 118 > Fatal error: Call to a member function prepare() on null in D:\xampp\htdocs\castisy\json_queries\data_access_objects.php on line 118
where is $db defined?
config.php, as seen above

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.