MySQL connection using a static connection I have been using a static class to connect and retrieve information from a MySQL database and also reading about how static works in php. I'm still not sure if the code is bad or not and why (besides the usual static are dangerous). Also, code improvements suggestions will be appreciated.

class Database {

    const STOREDPROCEDURE = 1;
    const ADHOC = 2;

    private static $instance;

    private static function call() {

        if (!isset(self::$instance)) {
            self::$instance = new MySQLi('localhost', 'root', '', 'alfred');
            if (self::$instance -&gt; connect_error) throw new Exception(self::$instance -&gt; connect_error);
            self::$instance -&gt; set_charset('utf8');
        }

        return self::$instance;

    }

    public static function query() {

        //
        $arguments = func_get_args();
        $count = count($arguments);

        //
        $references = array();
        for ($i = 2; $i &lt;= count($arguments) - 1; $i++) $references[$i] = &amp;$arguments[$i];

        //
        $query = $count === 0 ? '' : str_repeat('?, ', $count - 4) . '?';
        $query = 'CALL' . ' ' . $arguments[1] . '(' . $query . ');';

        //
        $stmt = self::call() -&gt; prepare($query);
        if ($count &gt; 2) call_user_func_array(array($stmt, 'bind_param'), $references);

        //
        $stmt -&gt; execute();
        $stmt -&gt; store_result();

        //
        $result = array();
        while ($metadata = $stmt -&gt; result_metadata()) {

            //
            $fields = array();
            foreach ($metadata -&gt; fetch_fields() as $field) {
                $reference[$field -&gt; name] = '';
                $fields[$field -&gt; name] = &amp;$reference[$field -&gt; name];
            }

            //
            call_user_func_array(array($stmt, 'bind_result'), $fields);

            //
            $rows = array();
            while ($stmt -&gt; fetch()) {
                $row = new stdClass();
                foreach ($fields as $name =&gt; $value) $row -&gt; $name = $value;
                array_push($rows, $row);
            }

            //
            array_push($result, empty($rows) ? null : $rows);

            //
            $stmt -&gt; next_result();

        }

        //
        $stmt -&gt; free_result();
        $stmt -&gt; close();

        //
        return $result;

    }

}


You can use the code by doing:

        $response = Database::query(
            Database::STOREDPROCEDURE,
            'UserRead',
            'sss',
            $useremail,
            $userpassword,
            $userhash
        );
Right now, it does not seem possible to run every type of query. For example: "SHOW FULL PROCESSLIST" or just "SELECT id FROM xyz LIMIT 0,10". Apart from this, there are a lot of things which might possibly go wrong.

What if I call the function with just one argument? arguments[1] would not exist and the query would become CALL (?). This statement is prepared and executed, but there is nothing executed.

I would suggest keeping things more easy instead of trying to merge several things together.


create a single query method which just runs "ADHOC" queries (no prepare)
create a prepare statement where you can bind parameters to the query (and execute)