I'm struggling to add a course to a MySQL database table using PDO prepared query with positional placeholders. When the form is submitted, the database table is not updated, as expected and no error is displayed.

Please, where exactly do I place var_dump() to display the error? And how can I get it to work?

Another thing; I would appreciate pointing out security flaws in the code.

Thanks in advance.

add-course.php:

 <?php   // configuration
require("../includes/config.php");

// query users table to retrieve current admin's profile
if(isset($_GET['aid'])) {

// select a particular admin by id
$stmt = $pdo->prepare("SELECT * FROM admin WHERE aid=?", $_SESSION["aid"]);
$stmt->execute([$aid]); 
$admin = $stmt->fetch(); # get admin data

//Class import for image uploading
//classes is the map where the class file is stored (one above the root)
include ("../classes/upload/upload_class.php");

// if form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST")
{         
    //This gets all the other information from the form
    $coursename = htmlspecialchars($_POST["c_name"]);
    $course_title = htmlspecialchars($_POST["c_title"]);
    $meta_keywords = htmlspecialchars($_POST["meta_keywords"]);
    $meta_description = htmlspecialchars($_POST["meta_description"]);
    $short_desc = htmlspecialchars($_POST["short_desc"]);
    $coursedesc = htmlspecialchars($_POST["desc"]);
    //$course_image = ($_FILES["image"]["name"]);
    $courseduration = htmlspecialchars($_POST["duration"]);
    $coursecode = htmlspecialchars($_POST["code"]);
    $fees = htmlspecialchars($_POST["fees"]);
    $course_image = htmlspecialchars($row['image']);

    // validate submission
    if (empty(htmlspecialchars($_POST["c_name"])))
    {
        echo "Provide the course name.";
    }
    if (empty(htmlspecialchars($_POST["duration"])))
    {
         echo "Provide the course duration.";
    }
    if (empty(htmlspecialchars($_POST["code"])))
    {
         echo "Provide the course code.";
    }

    //This is the directory where images will be saved 
    $max_size = 1024*250; // the max. size for uploading

    $my_upload = new file_upload;

    $my_upload->upload_dir = "../images/courses/"; // "files" is the folder for the uploaded files (you have to create this folder)
    $my_upload->extensions = array(".png", ".gif", ".jpeg", ".jpg"); // specify the allowed extensions here
    // $my_upload->extensions = "de"; // use this to switch the messages into an other language (translate first!!!)
    $my_upload->max_length_filename = 50; // change this value to fit your field length in your database (standard 100)
    $my_upload->rename_file = true;

    $my_upload->the_temp_file = $_FILES['image']['tmp_name'];
    $my_upload->the_file = $_FILES['image']['name'];
    $my_upload->http_error = $_FILES['image']['error'];
    $my_upload->replace = "y";
    $my_upload->do_filename_check = "n"; // use this boolean to check for a valid filename
    if ($my_upload->upload()) // new name is an additional filename information, use this to rename the uploaded file
    {
        $full_path = $my_upload->upload_dir.$my_upload->file_copy;
        $imagename = $my_upload->file_copy;
    }
    else
    {
        $imagename = "";
    }

    if (!empty($_POST["c_name"]))
    { 
        // validate coursename
        if (!preg_match("/^[a-zA-Z0-9]*$/", $coursename))
        {
            echo "A course name can only contain letters and numbers.";
        }
        if (strlen($coursename) < 20 || strlen($coursename) > 50)
        {
             echo "A course name must be from 20 to 50 characters.";
        }
        // validate course duration
        if (!preg_match("/^[a-zA-Z0-9]*$/", $courseduration))
        {
            echo "Invalid course duration.";
        }
        // validate course code
        if (!preg_match("/^[a-zA-Z0-9]*$/", $coursecode))
        {
            echo "A course ID can only contain letters and numbers.";
        }
        //validate course code length
        if (strlen($coursecode) < 3 || strlen($coursecode) > 10)
        {
             echo "A course code must be from 3 to 10 characters.";
        }
        if ($_POST["code"] === false)
        {
             echo "The course code has already been taken.";
        }

         $result = "INSERT INTO users (c_name, c_title, meta_keywords, meta_description, short_desc, desc, duration, code, fees, image) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
         $stmt= $pdo->prepare($result);
         $stmt->execute([$coursename, $course_title, $meta_keywords, $meta_description, $short_desc, $coursedesc, $courseduration, $coursecode, $fees, $course_image]);          

        // if coursename has been taken
        if ($coursename === false)
        {
             echo "The course name has been taken.";
        }

        // redirect to list courses
        header("Location: list-courses.php");

    }
}
}

 // render the header
 include("templates/header.php");

 // render add course form
 include("templates/add-course_template.php");

// render the footer
include("templates/footer.php"); 

?>

add-course-template.php:

<h1>Admin - Add a Course</h1>
<form enctype="multipart/form-data" action="add-course.php" method="post">
    <fieldset>
        <div class="form-group">
            Course Name: <textarea autofocus class="form-control" name="c_name" cols="32" rows="2" placeholder="Course Name">
Re: How Can I Get This Insert Query Using PDO Positional Placeholders To Work? 80 80

a Few things I could pick up from the above -

This is the part that is NOT creating an error, it is returning false as no aid is returned which means your entire statement is not initialized -

// query users table to retrieve current admin's profile
if(isset($_GET['aid'])) {
// select a particular admin by id
$stmt = $pdo->prepare("SELECT * FROM admin WHERE aid=?", $_SESSION["aid"]);

I am not sure where the $_GET['aid'] is retrieved from as you are referencing the same just below in $_SESSION

So, first things first, when referencing any $_SESSION variable, you need to start session on that page. Just below (1st line of code...) the <?PHP part. add -

if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

You can now make use of any session arrays or variables.

I will then, assuming that, as per your code, that the variable 'aid' was already added to your session earlier ij your app, do the following -

$admin_aid = $_SESSION['aid'];

if (!isset($admin_aid)) {
    var_dump("oops, no aid is available");
} else{
    //run your code here as you can now return an aid and then add it to the table users...
}

For development, I normally var_dump every variable returned to confirm that each row is running fine... You can also use echo to return values.

$_GET is also not the preferred way, rather use $_REQUEST, $_POST, $_SESSION, $_COOKIE to obtain values/variables/arrays.

Lastly, try not to build url's into statements, change teh following - $stmt = $pdo->prepare("SELECT * FROM admin WHERE aid=?", $_SESSION["aid"]); to $stmt = $pdo->prepare("SELECT * FROM admin WHERE aid='".$admin_aid."'");, notice the apostraphy '.

I almost forgot, to return or show errors during development (make sure to turn this off after development), add the following code AFTER the session start block -

error_reporting(E_ALL);
ini_set('display_errors', 1);
Re: How Can I Get This Insert Query Using PDO Positional Placeholders To Work? 80 80

@AndreRet,
Thanks for your input.

There's already session_start() call in the config.php file:

<?php

    // display errors, warnings, and notices
    ini_set("display_errors", true);
    error_reporting(E_ALL);

    // requirements
    require("constants.php");
    require("functions.php");

    // enable sessions
    session_start();

    // require authentication for most pages
    if (!preg_match("{(admin/login|logout|register)\.php$}", $_SERVER["PHP_SELF"]))
    {
       if (empty($_SESSION["aid"]))
        {
           header("Location: login.php");
        }
    }
    }

?>

With the code in the config.php, is it proper to have the following in another file, add-course.php?

    // query users table to retrieve current admin's profile
    if(isset($_POST['aid'])) {

    // select a particular admin by id
    $stmt = $pdo->prepare("SELECT * FROM admin WHERE aid=?", $_SESSION["aid"]);
    $stmt->execute([$aid]); 
    $admin = $stmt->fetch(); # get admin data
commented: You MUST HAVE session_start at the top of teh page i.e first line of code is session_start then other code follows. Then to your question, if you are +14
Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.18 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.