0

having trouble getting a script of mine to run correctly, I have 2 undefined index errors and an invalid argument supplied error that for the life of me I can't figure out why I'm getting. the 2 undefined index errors come from these lines.

if(!is_null($_GET['order']) && $_GET['order'] != 'courseTitle')

and

if (!is_null($_GET['page']))

and my invalid argument error is this

Warning: Invalid argument supplied for foreach() in

generated from this

<?php foreach ($books as $book) : ?>

my full code between the two classes is this.. any ideas of what I've done wrong? tearing my hair out over this.

index.php 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Catalog</title>
    </head>
    <body bgcolor="white">
        <?php
            /////////////////////////////////////////////////
            //connect to db
            /////////////////////////////////////////////////
            $dsn = 'mysql:host=localhost;dbname=book_catalog';
            $username = "php";
            $password = "php";
            $db = new PDO($dsn, $username, $password);

            //get data
            if(!is_null($_GET['order']) && $_GET['order'] != 'courseTitle')
            {
                $thesort = $_GET['order'];
                $query = "Select * FROM book
                INNER JOIN course
                ON book.course = course.courseID
                ORDER BY ".$_GET['order'];
            }
            else
            {
                $thesort = "courseTitle";
                $query = "Select * FROM book
                INNER JOIN course
                ON book.course = course.courseID
                ORDER BY $thesort";
            }

            //if page is null go to first page otherwise query for correct page
            if (!is_null($_GET['page']))
            {
                $query = $query." LIMIT ".($_GET['page']*8-8).", 8";
            }
            else
            {
                $query = $query." LIMIT 0, 8";
            }

            //query result
            $books = $db->query($query);

            //get number of overall rows
            $query2 = $db->query("SELECT * FROM book");
            $count = $db->query("SELECT Count(*) As 'totalRecords' FROM book");
            $count = $count->fetch();
            $count = $count['totalRecords'];
        ?>

        <table border =" 1">
            <tr>
                <th bgcolor="#6495ed"><a href="?order=course">Course #</th>
                <th bgcolor="#6495ed"><a href="?order=courseTitle">Course Title</th>
                <th bgcolor="#6495ed"><a href="?order=bookTitle">Book Title</th>
                <th bgcolor="#6495ed"></th>
                <th bgcolor="#6495ed"><a href="?order=price">Price</th>
            </tr>
            <?php foreach ($books as $book) : ?>
            <tr>
                <td><a href="rsc/catalog.pdf"><?php echo $book['course']; ?></a></td>
                <td><?php echo $book['courseTitle']; ?></td>
                <td><?php echo $book['bookTitle']; ?></td>
                <td><?php
                $bookcourse = $book['course'];
                $isbn = $book['isbn13'];
                $booklink = "<a href=\"course.php?course=$bookcourse&isbn=$isbn\">";
                echo $booklink ;?><img src='images/<?php echo $book['isbn13'].'.jpg'; ?>'></a></td>
                <td><?php echo $book['price']; ?></td>
            </tr>
            <?php endforeach; ?>
            </tr>
        </table>
         <?php
         //paging function... not sure if it works correctly?
            for ($j=1; $j <= ceil($count/8); $j++)
            { ?>

            <a href=<?php echo "?page=".$j."&order=".$thesort; ?>><?php echo $j; ?></a>
            <?php
            }?>
    </body>
</html>


**course.php**

<?php

    //get data from index.php
    $course = $_GET['course'];
    $isbn = $_GET['isbn'];    

        //connect to db
        $dsn = 'mysql:host=localhost;dbname=book_catalog';
        $username = "php";
        $password = "php";
        $db = new PDO($dsn, $username, $password);

        //get data
        $query = "Select * FROM book, course, author, publisher
    WHERE book.isbn13 = $isbn AND book.course = '$course' AND book.course = course.courseID AND book.bookID = author.bookID AND book.publisher = publisher.publisherID
            ORDER BY book.bookID";

        //query results        
        $books = $db->query($query);

        //error troubleshooting
          if (!$books) {
            echo "Could not successfully run query ($query) from DB: " . mysql_error();
            exit;
          }


        //count the number of rows in the result
        $results = $books->fetchAll();
        $rowCount = count($book);

        //get data from results
        foreach($results as $book){
            $bookID = $book['bookID'];
            $bookTitle = $book['bookTitle'];
            $isbn = $book['isbn13'];
            $price = $book['price']; 
            $desc = $book['description'];
            $publisher = $book['publisher'];
            $courseTitle = $book['courseTitle'];
            $courseID = $book['courseID'];
            $credits = $book['credit'];
            $edition = $book['edition'];
            $publishDate = $book['publishDate'];
            $length = $book['length'];
            $firstName = $book['firstName'];
            $lastName = $book['lastName'];

        }

        if($numrows > 1)
            {
                foreach ($books as $book)
                {
                    $authorArray[] = $book['firstName'] + ' ' + $book['lastName'];
                }
            }





?>

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>CIS Department Book Catalog</title>
    </head>
    <body bgcolor=white">

        <table border="0">
            <tr>
                <td>
                    <img src='images/<?php echo $isbn.'.jpg'; ?>'>
                </td>
                <td>
         <?php
         echo "For Course: $courseID  $courseTitle ($credits)";
         echo "</br>";    
         echo "Book Title: $bookTitle";
         echo "</br>";    
         echo "Price: $price";
         echo "</br>";    
         echo "Author";
         if ($numResults > 1)
         {
             echo "s:";
             for ($i = 0; $i < $numResults; $i++)
             {
                 if ($i!=0)
                 echo ", $authorArray[i]";
                 else
                     echo $authorArrat[i];
             }
         }
         else
             echo ": $firstName, $lastName";

         echo "</br>";    
         echo "Publisher: $publisher";
         echo "</br>";    
         echo "Edition: $edition ($publishDate)";
         echo "</br>";    
         echo "Length: $length pages";
         echo "</br>";    
         echo "ISBN-13: $isbn";
         ?>
                </td>
            </tr>
            <tr>
                <td colspan="2">
                    <?php echo "Description: $desc"; ?>
                </td>
            </tr>
        </table>

    </body>

</html>
2
  • 1
    What you are doing is terribly insecure. You're already using PDO, so it isn't difficult for you to start using prepared queries. As it stands right now, you are wide open to SQL injection attacks, and you will be hacked if you haven't been already. Commented May 1, 2013 at 3:06
  • why are you using !is_null instead of isset? Commented May 1, 2013 at 3:06

1 Answer 1

1
  1. You should be using isset not is_null to keep it from warning about undefined variables.

  2. $books is never defined It was defined, just incorrectly ... foreach needs it to be an array. You really don't need it anyway, fetch each row into the array with a while loop. (see my example below). You're also redefining $count several times in your query.

And like @Brad said. Use prepared statements and placeholders. Your database will end up hacked with your current code.

EDIT

Answer to your question. query() returns a statement handle. (I've defined it as $sth). fetch() returns a result which you need to pass one of the fetch mode constants (or define it by default earlier with $db->setFetchMode())

To get the books you need to have

$books = array();
$sth = $db->query($query);
while( $row = $sth->fetch(PDO::FETCH_ASSOC) ) {
    $books[] = $row; // appends each row to the array
}

Here's how your code should look to get a count.

// you're not using the $query2 you defined ... just remove it
$sth = $db->query("SELECT Count(*) As 'totalRecords' FROM book");
$result = $sth->fetch(PDO::FETCH_ASSOC);
$count = $result['totalRecords'];

Take a look at: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers Looks like a good guide to give you an in-depth understanding of how to use PDO. Pay special attention to error handling and to prepared statements!

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

4 Comments

Hey thanks for the feedback I changed it to 'isset' in the code. As for your second part, I defined '$books' at this line, '$books = $db->query($query);' In case its hard to find in the code its right before the redefining counts. Am I missing something about the returns? Is it not already in array format?
Edited my answer extensively
Hey Cfreak, sorry to bug you, hopefully this is the last time, but I'm getting an error "Call to undefined method PDO::fetch()" on the PDO's you suggested. I made the changes to the code for count and books. As far as I can tell PDO::FETCH_ASSOC is a constant, and fetch() is defined? Is there something I need to call earlier in my code to implement fetch() correctly?
My bad. should have been $sth->fetch() I just did it wrong. I edited the answer to correct it

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.