Preventing SQL injection without using prepared statements I'm learning OOP and totally new to this way of coding. I've always scripted PHP the procedurial way. Now I've written a working class, which creates a database connection and has the method to create a query which is impossible to SQL-inject by hexing the non-integer data. (I know how to use prepared statements, but i just don't want to use them because there is a slight performance penalty in my case)

Note: When hexing data the right way, its not possible to inject.Have a look at Zaffy's answer.

My questions: 


What could I've done better? 
Is it 'wrong' to use this class because its not good OOP (besides its function), or does it not really matter, because it works as how i want it to work? (nobody else is going to maintain the script)


And I must say, I've read multiple tutorials, but it's really difficult to fully understand howto write OOP style if you've never done before!

databaseconnection.class.php

&lt;?php
class DatabaseConnection {
    private $data, $sql, $conn, $host, $user, $pass, $dtbs;

    public function __construct($host, $user, $pass, $dtbs) {
        $this-&gt;host = $host;
        $this-&gt;user = $user;
        $this-&gt;pass = $pass;
        $this-&gt;dtbs = $dtbs;

        $this-&gt;conn = new mysqli($this-&gt;host, $this-&gt;user, $this-&gt;pass, $this-&gt;dtbs);
        if ($this-&gt;conn) {
            return $this-&gt;conn;
        } else {
            return false;
        }
    }

    public function query($sql, $data) {
        $this-&gt;data = $data;
        $this-&gt;sql = $sql;
        foreach ($data as $val) {
            if (strpos($this-&gt;sql, "'%i'") !== false || strpos($this-&gt;sql, "'%s'") !== false || strpos($this-&gt;sql, '"%i"') !== false || strpos($this-&gt;sql, '"%i"') !== false) {
                echo "SQL incorrect: There can't be any quotes around the parameters, because this function does that automaticly for you";
                exit();
            }
            $pos = strpos($this-&gt;sql, '%');
            $type = substr($this-&gt;sql, $pos, 2);
            if ($type == '%i') {
                if (is_int($val)) {
                    $this-&gt;sql = substr_replace($this-&gt;sql, $val, $pos, 2);
                } else {
                    echo "Parameter incorrect: Data is not an integer value";
                    exit();
                }
            } elseif ($type == '%s') {
                if (!is_int($val)) {
                    $this-&gt;sql = substr_replace($this-&gt;sql, "UNHEX('".bin2hex($val)."')", $pos, 2);
                } else {
                    echo "Parameter incorrect: Data is an integer value";
                    exit();
                }
            } else {
                echo "Parameter incorrect: Parameter %i for integer of %s for all other types of data";
                exit();
            }
        }

        $this-&gt;query = $this-&gt;conn-&gt;query($this-&gt;sql);
        return $this-&gt;query;

    }

    public function fetch($query) {
        return $query-&gt;fetch_assoc();
    }

    public function num_rows($query) {
        return $query-&gt;num_rows;
    }

}
?&gt;


index.php

&lt;?php
function __autoload($class){
  require('classes/' . strtolower($class) . '.class.php');
}
require('config.php');

$sql = new DatabaseConnection(DB_HOST, DB_USER, DB_PASS, DB_DTBS);
// The DB_xxxx constants are defined in config.php
?&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;title&gt;OOP - Object Orientated Programming&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
&lt;?php
$data = array(1, "Brian o'Reilly");
$query = $sql-&gt;query("SELECT * FROM users WHERE id = %i AND name = %s", $data);
if ($sql-&gt;num_rows($query) &gt; 0) {
    while ($r = $sql-&gt;fetch($query)) {
        echo '&lt;p&gt;User ' . $r['name'] . ' has ID ' . $r['id'] . '&lt;/p&gt;';
    }
} else {
    echo "&lt;p&gt;No results&lt;/p&gt;";   
}
?&gt;
&lt;/body&gt;
&lt;/html&gt;
never return from constructor
avoid having new statements in the constructor
on error, throw an exception instead of echo + exit
% is used in MySQL's LIKE syntax 
you should refactor your DatabaseConnection::query() method - it's too high cyclomatic complexity 
constants are global immutable state (it's not as bad as mutable globals, but still a bad idea)
you should be using spl_autoload_register instead of the archaic __autoload
you are mixing HTML with logic .. bad idea, try this approach instead
don't use ".class.php" in filenames, because then you will be screwed, when you start adding interfaces (which one would want to autoload too)