In my older projects, I used a function to 'shorten' my code a bit when doing queries.
Instead of using the usual approach of
$conn = [...]
$stmt = $conn->prepare(...)
$stmt->bind_param(...)
$stmt->execute();
$stmt->close();
$conn->close();
I got a function to do that fore me, called dynamic_db_reader($mysqli, $param, $qry).
It returns an array (or null) like: $array[index]['column_name'] = value
Or at least, that's what it used to do in previous versions. (Worked in PHP 7.4.16)
Here is the code to my function:
/**
 * Dynamically executes a given sql statement as prepared statement (?-placeholder).
 * Expects correct parameters as an array to replace ?.
 * Returns an array with ($arr[index]['column_name'] = value), or null.
 *
 * @param $ms       mysqli
 * @param $params   array
 * @param $qry      string
 * @return array|null
 */
function dynamic_db_reader($ms, $params, $qry){
    $fields = array();
    $results = array();
    // Replace prefix (DBPREF in: inc/config.php)
    if (strpos($qry, 'prefix_') !== false){
        $qry = str_replace('prefix', DBPREF, $qry);
    }
    // Set charset
    mysqli_set_charset($ms, 'utf8mb4');
    if ($stmt = $ms->prepare($qry)){
        // Dynamically bind parameters from $params
        if (!isset($params) || !empty($params)){
            // Parameters are set
            $types = '';
            foreach($params as $param){
                // Set parameter data type
                if (is_string($param)){
                    $types .= 's';              // Strings
                } else if (is_int($param)){
                    $types .= 'i';              // Integer
                } else if (is_float($param)){
                    $types .= 'd';              // Double/Float
                } else {
                    $types .= 'b';              // Default: Blob and unknown types
                }
            }
            $bind_names[] = $types;
            for ($i = 0; $i < count($params); $i++){
                $bind_name = 'bind' . $i;
                $$bind_name = $params[$i];
                $bind_names[] = &$$bind_name;
            }
            call_user_func_array(array($stmt, 'bind_param'), $bind_names);
        }
        $stmt->execute();
        $meta = $stmt->result_metadata();
        // Dynamically create an array to bind the results to
        while ($field = $meta->fetch_field()){
            $var = $field->name;
            $$var = null;
            $fields[$var] = &$$var;
        }
        // Bind results
        call_user_func_array(array($stmt, 'bind_result'), $fields); // --> Error :(
        // Fetch results
        $i = 0;
        while ($stmt->fetch()){
            $results[$i] = array();
            foreach($fields as $k => $v){
                $results[$i][$k] = $v;
            }
            $i++;
        }
        // Close statement
        $stmt->close();
        if (sizeof($results) > 0){
            return $results;
        }
    }
    return NULL;
}
The error:
Fatal error:  Uncaught ArgumentCountError: mysqli_stmt::bind_result() does not accept unknown named parameters in [...]\inc\db.php:87
Stack trace:
#0 [...]\root\inc\db.php(87): mysqli_stmt->bind_result(data_key: NULL, data_value: NULL)
#1 [...]\root\inc\func\common.php(76): dynamic_db_reader(Object(mysqli), Array, 'SELECT * FROM v...')
#2 [...]\root\www\index.php(22): getTestArray()
#3 {main}
  thrown in [...]\root\inc\db.php on line 87
How can I fix this code, so that it works in PHP 8 too?
 
     
    