Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

My PDO statement has an error

I'm trying to select data where the user got the same grades and took the same subjects as a past student from mysql table in phpmyadmin. I'm not sure if my query is right. I have a html form where user enters their data which gets posted into the predicter.php file. Once i get the data i'm trying to query the database and find a student who took the same subjects and got the same grades and echo their predicted grade.

My error says : Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' grade1 = Maths, B' at line 1' in /home/u717042829/public_html/predicter.php:67 Stack trace: #0 /home/u717042829/public_html/predicter.php(67): PDO->query('SELECT * FROM p...') #1 {main} thrown in /home/u717042829/public_html/predicter.php on line 67

Line 67 is : $query = $db->query($sql);

<?php 
error_reporting(E_ALL); ini_set('display_errors', 1);
require("includes/config.php");
//if not logged in redirect to login page
if(!$user->is_logged_in()){ header('Location: login.php'); } 

//define page title
$title = "Predict a Student's Grade";

?>
<!DOCTYPE html>
<html>



<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Past Student</title>

    <!-- Bootstrap Core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">




    <!-- Custom Fonts -->
    <link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>




<?php 

    if (isset($_POST['name'])) {


        $name     = $_POST['name'];
        $subject1 = $_POST['subject1'];
        $grade1   = $_POST['grade1']; 
        $subject2 = $_POST['subject2'];
        $grade2   = $_POST['grade2'];
        $subject3 = $_POST['subject3'];
        $grade3   = $_POST['grade3'];
        $subject4 = $_POST['subject4'];
        $grade4   = $_POST['grade4'];
        $attendance = $_POST['attendance'];
        $gender     = $_POST['gender'];

          $sql= "SELECT * FROM paststudent WHERE subject1, grade1 = $subject1, $grade1";
            $query = $db->query($sql);




    }
    ?>
    <h1> Your predicted grade is <?php echo $query ?> </h1>

</body>
</html>

1 Answer

Łukasz Czuliński
Łukasz Czuliński
8,646 Points

You need to put your variables in single quotes to 'escape' them, since MySQL cannot read PHP.

"SELECT * FROM paststudent WHERE subject1, grade1 = '$subject1', '$grade1'";

And I don't see you executing the query anywhere.

$query = $db->query($sql);
$query->execute();

That being said, your query is open for SQL injection because of the user-controlled input going right in the query. I would use prepared statements to be safe, even though it's just a SELECT statement.

Something like this (note the placeholders with leading colons : which then get binded to your variables before execution):

$query = $db->prepare("SELECT * FROM paststudent WHERE subject1, grade1 = :subject1, :subject2");
$query->bindParam(':subject1', $subject1);
$query->bindParam(':subject2', $subject2);
$query->execute();

This is much safer and good practice.

Hi this is my code now

 $stmt = $db->prepare("SELECT * FROM paststudent WHERE subject1 = :subject1 AND grade1 = :grade1");
            $stmt->execute(array(':subject1' => $subject1, ':grade1' => $grade1));
            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

It only outputs your predicted grade is array.

Here is my database : == Table structure for table paststudent

|------ |Column|Type|Null|Default |------ |//id//|int(11)|No| |name|varchar(100)|No| |subject1|varchar(25)|No| |grade1|varchar(2)|No| |subject2|varchar(25)|No| |grade2|varchar(2)|No| |subject3|varchar(25)|No| |grade3|varchar(2)|No| |subject4|varchar(25)|No| |grade4|varchar(2)|No| |final_maths|varchar(3)|No| |attendance|varchar(10)|Yes|NULL |gender|varchar(10)|No| == Dumping data for table paststudent

|1|Matt G|Maths|A|Further Maths|A|Computing|A|Physics|B|A|99.1|Male |14|Jim Riley|Maths|C|Economics|A|Chemistry|A|Physics|A|B|98|Male |12|Hannah Mcsweeney|Maths|B|Chemistry|U|Economics|B|Further Maths|C|C|86|Female |13|Iyioluwa Owoyemi|Maths|B|Computing|D|Physics|E|Economics|E|B|100|Male |10|Furquan Ahmad|Maths|C|Computing|C|Economics|A|Physics|E|A|98|Male |11|Kieran Wallbanks|Maths|A|Further Maths|A|Computing|A|Physics|C|A|97|Male == Table structure for table paststudent

|------ |Column|Type|Null|Default |------ |//id//|int(11)|No| |name|varchar(100)|No| |subject1|varchar(25)|No| |grade1|varchar(2)|No| |subject2|varchar(25)|No| |grade2|varchar(2)|No| |subject3|varchar(25)|No| |grade3|varchar(2)|No| |subject4|varchar(25)|No| |grade4|varchar(2)|No| |final_maths|varchar(3)|No| |attendance|varchar(10)|Yes|NULL |gender|varchar(10)|No|