gabord
8/4/2016 - 8:27 PM

A PHP class that abstracts mysqli requests and (hopefully) returns an array of rows or TRUE. Can be used for parameterized or non-parameter

A PHP class that abstracts mysqli requests and (hopefully) returns an array of rows or TRUE. Can be used for parameterized or non-parameterized requests. Currently tested for SELECTs and INSERTs.

<?php

class SqlQuery {

    private $insertId;
    private $connection = null;

    function __construct(mysqli $mysqliConnection) {
        $this->connection = $mysqliConnection;
        $this->insertId = null;
    }

    public function getConnection() {
        return $this->connection;
    }

    public function getInsertId() {
        return $this->insertId;
    }
    
    private function checkConnection() {
        if ($this->connection->connect_errno)
            throw new Exception("Connection failed: " . $this->connection->connect_error);
        if (!$this->connection->ping())
            throw new Exception("Server problem: " . $this->connection->error);    
    }
    
    public function sqlQuery($query, $paramFormat="", ...$paramsToBind) {
        try {
            return $this->sqlQueryImp($query, $paramFormat, $paramsToBind);
        } catch (Exception $ex) {
            echo $ex->getMessage().PHP_EOL.$ex->getTrace();
        }
    }
    
    private function sqlQueryImp($query, $paramFormat, $paramsToBind) {
        $this->checkConnection();
        // Simple query or parameterized query?
        if (empty($paramFormat) || empty($paramsToBind)) {
            return $this->simpleQuery($query); // SQL query without parameterization
        } else {
            return $this->paramQuery($query, $paramFormat, $paramsToBind);
        }
    }

    private function simpleQuery($query) {
        if (($result = $this->connection->query($query))) {
            $this->insertId = $this->connection->insert_id;
            if (is_bool($result)) return TRUE; // mysqli only returned TRUE, not a mysqli result
            return $this->fetchResultToArray($result);
        }
        else
            throw new Exception("Error: " . $query . PHP_EOL . $this->connection->error);
    }

    private function makeBindParams($paramFormat, $paramsToBind) {
        $params = array();
        $params[] = & $paramFormat;
        foreach ($paramsToBind as $param) {
            $params[] = & $param;
            unset($param);
        }
        return $params;
        
    }
    private function paramQuery($query, $paramFormat, $paramsToBind) {
        if (strlen($paramFormat) != count($paramsToBind))
            throw new Exception("Error: parameter format length doesn't equal length of parameters!");
        if (!($stmt = $this->connection->prepare($query)))
            throw new Exception("Error: " . $this->connection->error);
        
        $params = $this->makeBindParams($paramFormat, $paramsToBind);
        
        if (!call_user_func_array(array($stmt, 'bind_param'), $params))
            throw new Exception("Error: " . $stmt->error);

        if (!$stmt->execute()) {
            throw new Exception("Error: " . $stmt->error);
        }
        $this->insertId = $stmt->insert_id;
        if ($result = $stmt->get_result())
            return $this->fetchResultToArray($result);
        else 
            return TRUE; // Query executed, but can't get a result, prob. because it's an INSERT / UPDATE
    }

    private function fetchResultToArray($mysqliResult) {
        $endArray = array();
        if ($mysqliResult == TRUE)
            while ($sor = $mysqliResult->fetch_assoc()) {
                $endArray[] = $sor;
            }
        return $endArray;
    }
}

?>