GithubHelp home page GithubHelp logo

wolfgangdrescher / dbi Goto Github PK

View Code? Open in Web Editor NEW
0.0 3.0 0.0 32 KB

This framework allows to handle multiple PDO connections and to send queries with prepared statements and named parameters.

License: MIT License

PHP 100.00%

dbi's Introduction

DBi

This framework allows to handle multiple PDO connections and to send queries with prepared statements and named parameters.

Wolfgang Drescher

Features

  • Prepared statements
  • Named parameters
  • Echoing the query object will display a table with results
  • Method chaining e.g. $id = Query::init($insertSql)->send()->insertId();
  • Execute statements instantly with Query::exec()
  • Nicely designed error messages with Bootstrap

Requirements

  • A server running at least PHP version 5.3.
  • Result dumps and error messages are formated with Bootstrap.

License

This framework is standing under MIT licence. Feel free to use it, but please place a reference to my name or website.

Setup

Include the Bootstrap stylesheet to your websites header. Either use the following Bootstrap CDN link, or download it directly from their server.

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

Include in your config PHP file either DBi.php or Query.php. You can make the following configurations:

// your config.php
require_once 'DBi.php';
DBi::$autoSelect = false; // (default: true) disable auto selecting a connection with `DBi::add()`
Query::$throwExceptions = false; // (default: true) disable error messages
Query::$autoSend = true; // (default: false) enable automatically sending queries when a new query object is created

I recommend the setting Query::$throwExceptions to false in a productive environment.

DBi.php

Connect to a database with DBi::connect(). This method returns an object which represents the PDO connection to a SQL server.

$handle = DBi::connect('mysql:host=localhost;dbname=cms;', 'root', 'root');

You can add a connection to the DBi class with DBi::add(). If the variable DBi::$autoSelect is set to true (default) DBi::add() will automatically set the passed connection as the currently used connection.

DBi::add(DBi::connect($dsn, $user, $password));

Multiple connections at the same time are possible. Set the current connection with DBi::set($key) and use the same key as second argument in DBi::add().

DBi::$autoSelect = false;
DBi::add(DBi::connect($dsn, $user, $password), 'live');
DBi::add(DBi::connect($dsn, $user, $password), 'debug');
DBi::set('live');
// do some stuff in the live database
DBi::set('debug');
// do some other stuff in the debug database

You can get a connection with DBi::get(). This function will not set the current connection.

DBi::get(); // returns the current connection
DBi::get('live'); // returns a specific connection

Query.php

Use SQL strings like these examples:

$sqlNamedParams = "SELECT * FROM user WHERE email = :email LIMIT :limit";
$sqlParams = "SELECT * FROM user WHERE email = ? LIMIT ?";
$sql = "SELECT * FROM user WHERE email = '".DBi::e($email)."' LIMIT ".intval($limit);
$insertSql = "INSERT INTO user SET email = :email";

However I recommend always using prepared statements like $sqlNamedParams and $sqlParams. But if you know what you are doing use DBi::escape($str[, $connection]) or its shortcut DBi::e() to escape a sql string. You can also write your own function for escaping:

function e() {
	return call_user_func_array('DBi::escape', func_get_args());
}

Use ->prepare() to set the SQL string. Bind named parameters as array with ->bindParams(). This method will autodetect the type of the passed parameters (string, int, float). Execute a statement with ->send(). The colons in front of the named parameters in ->bindParams() are optional but they are required in the SQL string.

$stmt = new Query();
$stmt->prepare($sqlNamedParams);
$stmt->bindParams(array(
	':limit' => 1,
	'email' => $email // colon automatically added by the class
));
$stmt->send();

Display the result of a query as table by echoing the query object.

echo $stmt;

Set the connection for a single statement with ->setConnection(). Remember to always set the connection at the very beginning directly after creating the Query class object.

$stmt->setConnection(DBi::get('debug'));

Use the second argument of ->prepare() to bind named parameters directly to it.

$stmt->prepare($sqlNamedParams, array(
	'limit' => 1,
	':email' => $email
));

The SQL string can also be passed as first argument of new Query($sql). Bind parameters to an unnamed SQL string (params will replace the ?) as comma seperated arguments of ->bindParams(). This method will autodetect the type of bound parameters.

$stmt = new Query($sqlParams);
$stmt->bindParams($email, 1);

Bind a single parameter with ->bindParam(). The first argument is the key of the named parameter in the SQL string, the second is the value, and the optional third will set the type (Query::ParamStr, Query::ParamInt, Query::ParamFloat and Query::ParamLOB). If the third parameter is not set the method will autodetect the value's type.

$stmt->bindParam('email', $email, Query::ParamStr);
$stmt->bindParam(':limit', 1); // autodetects type Query::ParamInt
// $fp = fopen($_FILES['file']['tmp_name'], 'rb');
// $stmt->bindParam(':file', $fp, Query::ParamLOB);

Named parameters can also be bound as an array argument of ->send().

$stmt->send(array(
	':limit' => 1,
	':email' => $email
));

Query methods can be chained. You can also chain a query in one single line with Query::init().

$stmt = new Query();
$stmt->prepare($sqlParams)->bindParams($email, 1)->send();

echo $id = Query::init($insertSql, array('email' => $email))->send()->insertId();

Execute statements instantly with Query::exec(). This method will always send a statement directly without considering the value of Query::$autoSend.

echo $rows = Query::exec("SELECT * FROM user")->rows();

If you know what you are doing make a statement without parameters or the PDO prepare method. Remember to escape the variables with DBi::e().

$stmt = new Query();
$stmt->setSql($sql)->send();

Set the static variable Query::$autoSend to true if you want to execute a statement automatically with new Query() or Query::init().

Query::$autoSend = true;
$stmt = new Query($sqlNamedParams, array('limit' => 1, 'email' => $email));
$stmt = Query::init($sqlParams, array($email, 1));

Get the duration of a statement with ->getDuration() (in milliseconds). You can set the number of decimal points as an argument.

echo $stmt->getDuration(5); // echo's milliseconds

Set the result pointer of the result stack with ->seek($index).

Fetch a result row with ->fetch($mode). The default fetching method will be ->fetchObject(). ->fetchAssoc() will return an associative array of the current result row.

$stmt = new Query($sqlNamedParams, array('email' => $email, 'limit' => 1));
$stmt->send();
if($stmt->rows()) {
	while($row = $stmt->fetch()) {
		echo '<pre>'.print_r($row, true).'</pre>';
	}
}

->fetchNum() will return a result row as an enumerated array.

->fetchObject() will return the current row of the result set as an object (default object is stdClass).

class User { /*...*/ }
while($row = $stmt->fetchObject('User', array($arg1, $arg2))) {
	echo '<pre>'.print_r($row, true).'</pre>';
}

The method ->fetchAll() will return an array with the complete result.

Get the whole result as a JSON string with ->getJSON().

Thanks for using

Contribute to this repository and help to improve this framework by fixing issues and commenting them.

dbi's People

Contributors

wolfgangdrescher avatar

Watchers

 avatar  avatar  avatar

dbi's Issues

Reconsider logic of DBi class

Return a new instance of this class ith the method DBi::connect() and pass the connection variables to it. Like this is would be easy calling DBi::get()->dump() or DBi::get()->getHandle().

class DBi {
    // ...
    private $host;
    private $user;
    private $password;
    private $dbname;
    private $port;
    public $handle; // private with getHandle() method

    public function __construct($array) {
        foreach($array as $key => $value) {
            $this->$key = $value;
        }
    }

    public function connect(/*...*/) {
        // ...
        return new self(array(
            'handle' => $connection,
            'host' => $host,
            'user' => $user,
            'password' => $password,
            'dbname' => $dbname,
            'port' => $port
        ));
    }
}

Support for PHP version 5.3.x

Test the classes with PHP version 5.3.x and ensure backward compatibility.
Find an alternative function for array_column() in method Query::parseNamedParams().

$foundKey = array_search($value, array_column($params, 'key')); // 5.5.0
// $foundKey = array_search($value, array_map(function($element) { return $element['key']; }, $params)); // 5.3.0

Optimize Query::bindResult()

The Query::bindResult() method (view source) currently needs all parameters you want to bind a result to explicit as referenced method arguments, which limits the number of parameters to maximum of 26 variables (&$a = null, … &$z = null).

This method is also forced to use debug_backtrace(false) to pass the reference to a internal class variable, since func_get_args() does not support a return of the references.

Rename the Query class with `Statement`

Since the current version of this MySQLi framework no longer makes simple mysqli_query function calls, but instead uses prepared statements and bound parameters, perhaps Statement will be a better name for the Query class.

Reconsider names of the Query class constants

Would it be easier to just use Query::INT instead of Query::PARAM_INT?
Create new constants for fetch methods (e.g. Query::BOTH, Query::ROW, Query::ASSOC, ->fetch(Query::FETCH_ALL), ->fetch(Query::FETCH_ASSOC),…)?

Interference between mysqlnd get_result() and the other fetch methods

When mysqlnd is enabled on the server that is running this class the following error occurs. Discovered by updating MAMP to the newest version with PHP 5.5 and newer.
Storing the result of a Statement with mysqlnd and the Method get_result() will cause a problem with fetching the result data since it cannot decide whether it should fetch the result with get_result() or with the methods i wrote for it.

MySQL Error: 2014 - "Commands out of sync"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.