ThingEngineer / PHP-MySQLi-Database-Class

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

Undefined Offset Notice When Creating Table #1027

Closed cahilbey closed 2 months ago

cahilbey commented 6 months ago

Hello,

I'm encountering an issue while trying to create a temporary table:

$SQL = "CREATE TEMPORARY TABLE TempOrder (
           OrderID INT AUTO_INCREMENT PRIMARY KEY,
           CustomerID INT
       ) ENGINE=InnoDB; ";
try{
    $RS = $db->rawQuery($SQL); 
}catch (\Exception $e) {
    echo $e->getMessage();
}

This SQL query successfully creates the temporary table. However, I am receiving a PHP notice:

NOTICE: UNDEFINED OFFSET: 0 IN /... PHP/VENDOR/THINGENGINEER/MYSQLI-DATABASE-CLASS/MYSQLIDB.PHP ON LINE 559

Could you please provide some insight or guidance on what might be causing this notice and how to resolve it? Any help would be greatly appreciated.

Thank you

huseyinaslim commented 6 months ago

Your code for creating a temporary database table is running successfully. In PHP, try-catch blocks capture thrown errors. However, what you have mentioned here is not a thrown error, but a NOTICE type feedback. Therefore, it does not come from within the catch block and is completely unrelated to this code block.

This notice in PHP is received due to trying to call an invalid index of an array. For example;

$array = ['1' => 'apple', '2' => 'banana'];
echo $array[0];

Such a call would return the notice you received because there is no array element with index 0.

NOTICE: UNDEFINED OFFSET: 0 IN /... PHP/VENDOR/THINGENGINEER/MYSQLI-DATABASE-CLASS/MYSQLIDB.PHP ON LINE 559

The reason you receive the notice seems to be due to a called array in the library returning empty, like not being able to find that index but to provide better assistance here, we need to know which version of the library you are using. However, this is feedback and not a critical error that will stop or disrupt the operation, so it can be ignored. Still, if you specify the version, we can understand what code the relevant line refers to and check the index in that area.

Looking at the relevant line in the latest version, this piece of code was on line 559;

/**
 * Prefix add raw SQL query.
 *
 * @author Emre Emir <https://github.com/bejutassle>
 * @param string $query      User-provided query to execute.
 * @return string Contains the returned rows from the query.
 */
public function rawAddPrefix($query){
    $query = str_replace(PHP_EOL, '', $query);
    $query = preg_replace('/\s+/', ' ', $query);
    preg_match_all("/(from|into|update|join|describe) [\\'\\´]?([a-zA-Z0-9_-]+)[\\'\\´]?/i", $query, $matches);
    list($from_table, $from, $table) = $matches;

    return str_replace($table[0], self::$prefix.$table[0], $query);
}

Here, if the table prefix is specified in the link, the function adjusts it in the query. However, there is no such need in the create query because we specify the full table name. Indeed, in the code, the addition of prefixes for certain keywords is executed with regex. However, create queries must not have been considered, as they don't include the specified key selectors (from|into|update|join|describe), so the list function cannot catch the correct match.

As a result, the $table variable is not set correctly. We need to check for the existence of $table[0] and make a return accordingly.

This can be modified as follows:

/**
 * Prefix add raw SQL query.
 *
 * @author Emre Emir <https://github.com/bejutassle>
 * @param string $query      User-provided query to execute.
 * @return string Contains the returned rows from the query.
 */
public function rawAddPrefix($query){
    $query = str_replace(PHP_EOL, '', $query);
    $query = preg_replace('/\s+/', ' ', $query);
    preg_match_all("/(from|into|update|join|describe) [\\'\\´]?([a-zA-Z0-9_-]+)[\\'\\´]?/i", $query, $matches);
    list($from_table, $from, $table) = $matches;

    if(isset($table[0]))
        return str_replace($table[0], self::$prefix.$table[0], $query);
    else
        return $query;

}

Have a good day.