Mysqli Prepared statement usage with AJAX POST to PHP file

You said:

As you can see, the PHP file is turning out to be pretty long.

That is true, but that is not the fault of prepared statements. You must have been learning PHP development from a poorly written tutorial. This code does not need to be so long. In fact, it can be severely shortened.

Just fixing your existing code made it much more readable. I used OOP-style mysqli and I removed all these if statements. You should enable error reporting instead.

<?php

session_start();
if (isset($_POST['CT'],$_POST['CN'])) {
    require_once "golin_2.php";
    $CN = $_POST['CN'];
    $CT = $_POST['CT'];
    $ER = "";
    $arr = [
        'PASS' => "OK",
        'MSG2' => "Insert Success",
    ]; // successful state should be the default outcome

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $CONN = new mysqli($SERVER, $USER, $PASS, $DBNAME);
    $CONN->set_charset('utf8mb4'); // always set the charset

    // To check existance of data in database we use COUNT(*)
    $stmt = $CONN->prepare("SELECT COUNT(*) FROM sailors.continental_regions WHERE CONTINENT = ? AND COUNTRY = ?");
    $stmt->bind_param("ss", $CN, $CT);
    $stmt->execute();
    $NUMROWS = $stmt->get_result()->fetch_row()[0];
        
    if ($NUMROWS) {
        $ER .= "Err: duplicate '$CN' '$CT' pair";
    } else {
        $stmt = $CONN->prepare("INSERT INTO DB.continental_regions (CONTINENT,COUNTRY) values (?, ?)");
        $stmt->bind_param("ss", $CN, $CT);
        $stmt->execute();
    }
            
    if ($ER) {
        $arr = [
            'PASS' => "FAIL",
            'MSG' => $ER,
        ];
    }
    echo json_encode($arr);
} else {
    header("location: ../Error_Fail.php");
}

If you have a composite UNIQUE key on these two columns in your table then you can remove the select statement. Also, you should clean up your response preparation. The successful state should be the default and it should be replaced with the error message only if something went wrong.

In this example, I removed one SQL statement. The whole thing is now much simpler.

<?php

define('DUPLICATE_KEY', 1062);
session_start();
if (isset($_POST['CT'],$_POST['CN'])) {
    require_once "golin_2.php";
    $CN = $_POST['CN'];
    $CT = $_POST['CT'];
    $arr = [
        'PASS' => "OK",
        'MSG2' => "Insert Success",
    ]; // successful state should be the default outcome

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $CONN = new mysqli($SERVER, $USER, $PASS, $DBNAME);
    $CONN->set_charset('utf8mb4'); // always set the charset

    try {
        $stmt = $CONN->prepare("INSERT INTO continental_regions (CONTINENT,COUNTRY) values (?, ?)");
        $stmt->bind_param("ss", $CN, $CT);
        $stmt->execute();
    } catch (mysqli_sql_exception $e) {
        if ($e->getCode() !== DUPLICATE_KEY) {
            // if it failed for any other reason than duplicate key rethrow the exception
            throw $e;
        }
        // if SQL failed due to duplicate entry then set the error message
        $arr = [
            'PASS' => "FAIL",
            'MSG' => "Err: duplicate '$CN' '$CT' pair",
        ];
    }
    
    echo json_encode($arr);
} else {
    header("location: ../Error_Fail.php");
}

Regarding performance.
There is no problem with performance in this example and prepared statements don’t improve or degrade the performance. I assume you are trying to compare the performance to static SQL queries, but in your simple example there should be no difference at all. Prepared statements can make your code faster compared to static queries when you need to execute the same SQL many times.

If you find writing the 3 lines of code each time too much, then you can create a wrapper function that will reduce it for you to a single function call. In fairness you should avoid using mysqli on its own. Either switch to PDO or use some kind of abstraction library around mysqli.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top