luri/bddi

library to facilitate SQL Requests set with automatic prepared statements and automatic connexion.

v3.0BETA9 2021-02-20 14:08 UTC

README

BDD-I is a higw powerful and simple abstraction for database requests. It's simplify work with database :

  • Automatic connection
  • Automatic transaction
  • Multiple databases / logins connexion supported
  • Helpful getter for response
  • Support array variable for IN() syntax
  • Support Anonymous (?) and marqued parameter (:NAME) in prepared statement

Focus on your query!

Designed for simple use on small and medium website.

Table Of Contents

Install

Via Composer :

$ composer require luri/bddi

You must add a low level driver, for example :

$ composer require luri/bddi-mysqli-driver

Warning : This project is in BETA. You must set "minimum-stability" proprieties at "beta" :

$ composer config minimum-stability beta

Testing

For execute phpunit test : (you must install project with dev dependance)

$ composer test

About this Lib

Four years ago, I start to help the rework on a small php fan-game (SWHologame). I quickly notice that their database code is complicated to use. I think to this more simply to use if Db classes is focus on Query and if database connexion is managed by this classes. I rewrite and adapt an old database access classes. Bdd-I v2 is born.

Last Year, I want to use this Db classes for some other project, But BDD-I v2 is an enormous monolitic classes, heavely intertwine with other specific SWHologame classes. So, I start to develop this rework : BDD-I v3.

For some project, I need to have a lib who can use some differents database but I don't want to loose my helper getter. I don't want to use PDO beacause (4-5 year ago) PDO-MYSQL don't support to use a same result multiple time.

I think the better think to do is separate high level logic than low level logic (adapter for php database extension). And this can allow someone to develop driver they want.

For classes organisation, I heavily inspired through php-http/httplug by Eric GELOEN, Márk Sági-Kazár :

graph TD;
	subgraph "user Application"
	U1(Application);
	U2(user DbConfig);
	end
	subgraph "Bdd-I"
	A(Query);
	B(QuerySet);
	C(DbFactory);
	end;
	subgraph
	D(Common Interfaces);
	end;
	subgraph "Low level drivers"
	E(LlMysqli);
	F(Mock);
	G("LlSQLite (todo)");
	end
	subgraph "PHP extensions"
	H(Mysqli);
	I(SQLite 3);
	end
	classDef BlackTxt stroke:#000,fill:#ccf;
	class U1 BlackTxt;
	class U2 BlackTxt;
	class A BlackTxt;
	class B BlackTxt;
	class C BlackTxt;
	class D BlackTxt;
	class E BlackTxt;
	class F BlackTxt;
	class G BlackTxt;
	class H BlackTxt;
	class I BlackTxt;
	U1-->A;
	U1-->B;
	U2---C;
	A-->D;
	B-->D;
	D-->E;
	D-->F;
	D-->G;
	E-->H;
	G-->I;

Basic Usage

You must create your own DbConfig file, see bellow

For execute only one request, use Query class. For Example :

<?php
/* DATA SQL EXAMPLE :
 *
 * CREATE TABLE IF NOT EXISTS `singer` (
 *   `idsinger` int(11) NOT NULL AUTO_INCREMENT,
 *   `name` varchar(100) NOT NULL,
 *   `nationality` varchar(100) NOT NULL,
 *   PRIMARY KEY (`idsinger`)
 * ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 *
 * INSERT INTO `singer` (`idsinger`, `name`, `nationality`) VALUES
 * ('1', 'Bars and Melody', 'British'),
 * ('2', 'Eddy De Pretto', 'French'),
 * ('3', 'Greyson Chance', 'U.S.A.'),
 * ('4', 'Troye Sivan', 'Australian'),
 * ('5', 'Ronan Parke', 'British')
 */
require_once 'DbConfig.php'; //See below "Configuration"
require_once 'libs/autoload.php'; //composer require

use Luri\BddI\Query;
?>
<html>
    <body>
        <ul>
<?php
//Simple example
$singer = new Query("<SINGER_LIST>", "SELECT name FROM singer");
foreach ($singer as $v) {
    echo '          <li>' . htmlentities($v['name']) . "</li>\n";
}
unset($singer); //= free result
?>
        </ul>

        <h2>List of information about Ronan Parke (id:2)</h2>

<?php
//Fluent interface syntax
//Remember all variable is insecure ! You must use prepared statement if you use variable :
$id = 5; //probably a $_GET['xxx'] here. Think verify validy of your $_GET parameter
$infos = Query::factory('<INFO>')
    ->addReq('SELECT * FROM singer WHERE idsinger = :ID')
    ->addDatas([':ID' => $id])
    ->exe()
    ->getLineNumber(); //this return the first line of the result
?>

        <p>Nom : <?php echo htmlentities($infos['name']); ?></p>
        <p>Nationality : <?php echo htmlentities($infos['nationality']); ?></p>
...

For execute 2 or more Query at once, like a set of INSERT or UPDATE request, use the QuerySet class.

Configuration

Weel, you must configure bdd account. This can be easy with include at top of your script you're own DbConfig.php.

Example of DbConfig.php :

<?php
namespace Luri\BddI {
	/**
	 * Configuration Class
	 */
	abstract class DbConfig {

		/**
		 * Config of database
		 * Here, We have 3 accessible db with id trampo, gac and forum.
		 * trampo is the database 'test' in local server
		 * gac is the database 'gac' in local server
		 * forum is the dabase 'forum' in forum.example.org server
		 */
		protected const DBCONFIG = [
			'trampo' => [ //db id for use in you apps
				'name' => 'test', //Db name in SQL server
				'server' => 'local' //SQL server Id in SERVERCONFIG
			],
			'gac' => [ //db id for use in you apps
				'name' => 'gac', //Db name in SQL server
				'server' => 'local' //SQL server Id in SERVERCONFIG
			],
			'forum' => [ //db id for use in you apps
				'name' => 'forum', //Db name in SQL server
				'server' => 'db2' //SQL server Id in SERVERCONFIG
			],
		];

		/**
		 * Config of server
		 * Here, we have 2 configured server with id local and db2. This id must be used in DBCONFIG['xx']['server'] parameter (see overhead)
		 * You can also define 2 servers in same address but with different login.
		 */
		protected const SERVERCONFIG = [
			'local' => [ ////SQL server Id
				'login' => 'root', //Login for this connexion (you MUST not use root)
				'password' => 'root', //Password for this connexion (you MUST create a robust password)
				'address' => '127.0.0.1', //IP address for SQL server
				'lowLevelDriver' => '\Luri\BddI\LowLevel\LlMysqli', //Name of low level driver class to use
				'charset' => 'utf8' //Charset to use
			],
			'db2' => [ ////SQL server Id
				'login' => 'root', //Login for this connexion (you MUST not use root)
				'password' => 'root', //Password for this connexion (you MUST create a robust password)
				'address' => 'forum.example.org', //IP address for SQL server
				'lowLevelDriver' => '\Luri\BddI\LowLevel\LlMysqli', //Name of low level driver class to use
				'charset' => 'utf8' //Charset to use
			],
		];


		/**
		 * Default database
		 *
		 * This is the database used if no database id is passed to Query or QuerySet class.
		 * 
		 * @var string
		 */
		protected const DEFAULTDATABASE = 'trampo';


	}
}
namespace {
	// you're global code

}
?>

Well, you can choose other name than DbConfig.php for file name. But don't change class name or namespage name.

Low level driver

  • Mysqli driver
  • Mock driver

Mysqli driver not use advanced feature than persistent connections. If you want, you can develop a new driver.

Why a mysqli driver and not a PDO driver ? When I create V2 many year ago, I compare PDO and Mysqli for my use (small database). With mysqli, I can use a same result several time but i can't use named placeholders. With PDO i can use named placeholders but i can't use a same result several time. So I choose to use mysqli and develop named placeholders support for mysqli.

Create a new low level driver

If you want add powerful capabilities think this must be simple to use and configure .

To be continued....

TODO list

before V1 :

  • Define a set of exception
  • Add Log support
  • ay'a un troisième truc mais je ne sais plus
  • Make documentation

Documentation

TODO ;-)

Author

I'm Luri form France (alps) and I'm develop in PHP since school and php 3. But PHP is my hobbie (like olympic trampoline, ski...) not my work. I don't have a lot of time to develop. Any help is welcome. If someone want take over this lib, write me, you're welcome.

Mail : Luri AT e DOT email If you know french, please use it. (Otherwise use english.)

Licence

BDD-I is distributed with term of CECILL-C licence : EN | FR

CECILL-C is a free software license recognised by Open Source Initiative (OSI). This licence is more protective than an L-GPL licence because is protected by French law. (French law not recognise software patent)