ThingEngineer / PHP-MySQLi-Database-Class

Wrapper for a PHP MySQL class, which utilizes MySQLi and prepared statements.
Other
3.3k stars 1.34k forks source link

Update duplicate problem #1030

Closed JuliusFroglet closed 4 months ago

JuliusFroglet commented 4 months ago

Hey, I am updating datasets but one, or sometime more, columns are unique. So when I enter an existing name, an error is thrown.

Is there a way to detect that and than setting a var to True instead of getting the script disrupting error message?

JuliusFroglet commented 4 months ago

I tried this, but I always get the entire PHP Error Message, no matter what... It not getting towards the "Update failed....." Echo


 if ($db->getLastErrno() === 0)
    echo 'Update succesfull';
    else
    echo 'Update failed. Error: '. $db->getLastError();
JuliusFroglet commented 4 months ago

I worked around all this like this now. However, I feel that is not the elegant solution.


    try{

        $db->where("id",$_POST["id"]);

        $return["update values"]=$_POST["update"];

        $on_update = $db->update($table,$_POST["update"]);
        if($on_update)
        {
            $return["updated"]=$_POST["id"];
        }
    }
    catch (Exception $e) {
        //print_r($e);
        if($e->getCode()==1062)
        {
            preg_match("/for key '(.*)'/", $e->getMessage(), $matches, PREG_OFFSET_CAPTURE);
            if(isset($matches[1]))
            {
                if(!isset($return["duplicate"])) $return["duplicate"] = [];
                $return["duplicate"][]=$matches[1][0];

            }

        }

    }
ThingEngineer commented 4 months ago

Hi @JuliusFroglet thank you for chiming in on this and sharing your example of handling duplicate key errors gracefully.

First off, you are on the right track. Exception handling is generally preferred for better code structure, so using the try...catch block is the way to go.

It is technically possible to implement what you are asking but not generally how error handling is managed.

I don't know your specific use case, but you could also check for unique columns before updating and provide appropriate error messages if they encounter duplicates beforehand (avoiding the exception in the first place). Think something like, picking a username where, as the user types in their desired username, if it's taken they are notified immediately with live feedback (error message, red box around the input, etc.).

Here's a revised approach that combines unnecessary lines, uses clearer variable names, sets a specific error message for clarity, and improves readability while maintaining duplicate key error handling functionality by leveraging built-in exception handling. Also, instead of a technical error message, the user receives a specific message indicating a the duplicate entry for 'column_name'. This helps them understand the exact issue and potentially fix their data before retrying the update, as well as preventing the possible display of sensitive db info.

try {
  $db->where("id", $_POST["id"])
     ->update($table, $_POST["update"]);
  $return["updated"] = $_POST["id"]; // Update successful, set updated ID
} catch (\mysqli_sql_exception $e) {
  if ($e->getCode() === 1062) {
    // Extract duplicate column (same logic you used)
    preg_match("/for key '(.*)'/", $e->getMessage(), $matches, PREG_OFFSET_CAPTURE);
    if (isset($matches[1])) {
      $duplicateColumn = $matches[1][0];
      $return["error"] = "Duplicate entry for column '$duplicateColumn'";
    } else {
      $return["error"] = "Duplicate key error.";
    }
  } else {
    // Handle other exceptions (optional)
    $return["error"] = "Update failed: Unexpected error.";
  }
}

In short, if you are using exception handling correctly you should never had a

'script disrupting error message'.

If I missed the your point or you have another issue feel free to add additional comments.