PHPackages                             voku/simple-mysqli - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. voku/simple-mysqli

ActiveLibrary[Database &amp; ORM](/categories/database)

voku/simple-mysqli
==================

Simple MySQLi library

8.3.1(3y ago)4547.9k—0%11[1 issues](https://github.com/voku/simple-mysqli/issues)[1 PRs](https://github.com/voku/simple-mysqli/pulls)4MITPHPPHP &gt;=7.0

Since Dec 4Pushed 8mo ago8 watchersCompare

[ Source](https://github.com/voku/simple-mysqli)[ Packagist](https://packagist.org/packages/voku/simple-mysqli)[ Docs](https://github.com/voku/simple-mysqli)[ Fund](https://www.paypal.me/moelleken)[ GitHub Sponsors](https://github.com/voku)[ RSS](/packages/voku-simple-mysqli/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (7)Versions (141)Used By (4)

[![Build Status](https://camo.githubusercontent.com/cdb2f8f023ab677f69b766a127538d5f23bc9fd28722bd4ba18974c4b4b37aa3/68747470733a2f2f7472617669732d63692e6f72672f766f6b752f73696d706c652d6d7973716c692e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/voku/simple-mysqli)[![FOSSA Status](https://camo.githubusercontent.com/d51d8307522ef57dde23575595ec6052f1431459cbd4caaef3d7d1cb8a2225d8/68747470733a2f2f6170702e666f7373612e696f2f6170692f70726f6a656374732f6769742532426769746875622e636f6d253246766f6b7525324673696d706c652d6d7973716c692e7376673f747970653d736869656c64)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoku%2Fsimple-mysqli?ref=badge_shield)[![Coverage Status](https://camo.githubusercontent.com/24e60a8c729b928f0ff32217ead0a9760213a720240133ed8de95ee25da57356/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f766f6b752f73696d706c652d6d7973716c692f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/voku/simple-mysqli?branch=master)[![Codacy Badge](https://camo.githubusercontent.com/f7e2bd3536db701308fc599068cfc4ed8c28a9f71b15f537871363ec0ba85294/68747470733a2f2f6170692e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f3739376261336261363537643465306538366630626164653639323366646563)](https://www.codacy.com/app/voku/simple-mysqli)[![Latest Stable Version](https://camo.githubusercontent.com/abda95c08a8796cb2e7c75308dd2287920cb6484701fed525969637cb4c211b0/68747470733a2f2f706f7365722e707567782e6f72672f766f6b752f73696d706c652d6d7973716c692f762f737461626c65)](https://packagist.org/packages/voku/simple-mysqli)[![Total Downloads](https://camo.githubusercontent.com/80175ec23f320ad80c98d299ed8c1ed26d65f95edc8bdeffecacf188f2bdb0ae/68747470733a2f2f706f7365722e707567782e6f72672f766f6b752f73696d706c652d6d7973716c692f646f776e6c6f616473)](https://packagist.org/packages/voku/simple-mysqli)[![License](https://camo.githubusercontent.com/07e632c772f63eb200fa2654705132474e1f459e07faa5acfbbf8e0252e2439d/68747470733a2f2f706f7365722e707567782e6f72672f766f6b752f73696d706c652d6d7973716c692f6c6963656e7365)](https://packagist.org/packages/voku/simple-mysqli)[![Donate to this project using Paypal](https://camo.githubusercontent.com/0d6e4d8b50b5983a58205941b1a581b1305903393b7a39da574e3f60af3c7f5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f70617970616c2d646f6e6174652d79656c6c6f772e737667)](https://www.paypal.me/moelleken)[![Donate to this project using Patreon](https://camo.githubusercontent.com/f9e075baad95563481d35174d43ef50757281abb6bc795d0f473fad452afa030/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f70617472656f6e2d646f6e6174652d79656c6c6f772e737667)](https://www.patreon.com/voku)

💎 Simple MySQLi Class
=====================

[](#gem-simple-mysqli-class)

This is a simple MySQL Abstraction Layer compatible with PHP 7+ &amp; PHP 8.0 that provides a simple and *secure* interaction with your database using mysqli\_\* functions at its core. This is perfect for small scale applications such as cron jobs, facebook canvas campaigns or micro frameworks or sites.

You can also use the 💍 ["Simple Active Record"](https://github.com/voku/simple-active-record)-class, it's based on this db class and add some OOP syntax. But please inform you about "Active Record" vs "Data Mapper" before you use it.

### Get "Simple MySQLi"

[](#get-simple-mysqli)

You can download it from here, or require it using [composer](https://packagist.org/packages/voku/simple-mysqli).

```
  {
      "require": {
        "voku/simple-mysqli": "8.*"
      }
  }
```

### Install via "composer require"

[](#install-via-composer-require)

```
  composer require voku/simple-mysqli
```

- [Starting the driver](#starting-the-driver)
- [Multiton &amp;&amp; Singleton](#multiton--singleton)
- [Doctrine/DBAL as parent driver](#doctrinedbal-as-parent-driver)
- [Using the "DB"-Class](#using-the-db-class)
    - [Selecting and retrieving data from a table](#selecting-and-retrieving-data-from-a-table)
    - [Inserting data on a table](#inserting-data-on-a-table)
    - [Binding parameters on queries](#binding-parameters-on-queries)
    - [Transactions](#transactions)
- [Using the "Result"-Class](#using-the-result-class)
    - [Fetching all data](#fetching-all-data)
    - [Fetching database-table-fields](#fetching-database-table-fields)
    - [Fetching + Callable](#fetching--callable)
    - [Fetching + Transpose](#fetching--transpose)
    - [Fetching + Pairs](#fetching--pairs)
    - [Fetching + Groups](#fetching--groups)
    - [Fetching + first](#fetching--first)
    - [Fetching + last](#fetching--last)
    - [Fetching + slice](#fetching--slice)
    - [Fetching + map](#fetching--map)
    - [Fetching + aliases](#fetching--aliases)
    - [Fetching + Iterations](#fetching--iterations)
- [Using the "Prepare"-Class](#using-the-prepare-class)
    - [INSERT-Prepare-Query (example)](#insert-prepare-query-example)
    - [SELECT-Prepare-Query (example)](#select-prepare-query-example)
- [Logging and Errors](#logging-and-errors)
- [Changelog](#changelog)

### Starting the driver

[](#starting-the-driver)

```
  use voku\db\DB;

  require_once 'composer/autoload.php';

  $db = DB::getInstance('yourDbHost', 'yourDbUser', 'yourDbPassword', 'yourDbName');

  // example
  // $db = DB::getInstance('localhost', 'root', '', 'test');
```

### Multiton &amp;&amp; Singleton

[](#multiton--singleton)

You can use `DB::getInstance()` without any parameters and you will get your (as "singleton") first initialized connection. Or you can change the parameter and you will create an new "multiton"-instance which works like an singleton, but you need to use the same parameters again, otherwise (without the same parameter) you will get an new instance.

### Doctrine/DBAL as parent driver

[](#doctrinedbal-as-parent-driver)

```
  use voku\db\DB;

  require_once 'composer/autoload.php';

  $connectionParams = [
      'dbname'   => 'yourDbName',
      'user'     => 'yourDbUser',
      'password' => 'yourDbPassword',
      'host'     => 'yourDbHost',
      'driver'   => 'mysqli', // 'pdo_mysql' || 'mysqli'
      'charset'  => 'utf8mb4',
  ];
  $config = new \Doctrine\DBAL\Configuration();
  $doctrineConnection = \Doctrine\DBAL\DriverManager::getConnection(
      $connectionParams,
      $config
  );
  $doctrineConnection->connect();

  $db = DB::getInstanceDoctrineHelper($doctrineConnection);
```

Using the "DB"-Class
--------------------

[](#using-the-db-class)

There are numerous ways of using this library, here are some examples of the most common methods.

#### Selecting and retrieving data from a table

[](#selecting-and-retrieving-data-from-a-table)

```
  use voku\db\DB;

  $db = DB::getInstance();

  $result = $db->query("SELECT * FROM users");
  $users  = $result->fetchAll();
```

But you can also use a method for select-queries:

```
  $db->select(string $table, array $where); // generate an SELECT query
```

Example: SELECT

```
  $where = [
      'page_type ='         => 'article',
      'page_type NOT LIKE'  => '%öäü123',
      'page_id >='          => 2,
  ];
  $articles = $db->select('page', $where);

  echo 'There are ' . count($articles) . ' article(s):' . PHP_EOL;

  foreach ($articles as $article) {
      echo 'Type: ' . $article['page_type'] . PHP_EOL;
      echo 'ID: ' . $article['page_id'] . PHP_EOL;
  }
```

Here is a list of connectors for the "WHERE"-array: 'NOT', 'IS', 'IS NOT', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN', 'LIKE', 'NOT LIKE', '&gt;', '&lt;', '&gt;=', '&lt;=', '&lt;&gt;', '+', '-'

INFO: use an array as $value for "\[NOT\] IN" and "\[NOT\] BETWEEN"

INFO: use + / - in the value not in the key of the $data

Example: UPDATE with "page\_template = page\_template + 1"

```
  $where = [
      'page_type LIKE'     => '%foo',
      'page_type NOT LIKE' => 'bar',
  ];
  $data = [
      'page_template' => ['page_template +' => 1],
      'page_type'     => 'lall',
  ];
  $resultSelect = $db->update('page', $data, $where);
```

Example: SELECT with "NOT IN"

```
  $where = [
      'page_type NOT IN' => [
          'foo',
          'bar'
      ],
      'page_id >'        => 2,
  ];
  $resultSelect = $db->select('page', $where);
```

Example: SELECT with Cache

```
  $resultSelect = $db->execSQL("SELECT * FROM users", true, 3600);
```

The result (via $result-&gt;fetchAllArray()) is only cached for 3600s when the query was a SELECT statement, otherwise you get the default result from the `$db->query()` function.

#### Inserting data on a table

[](#inserting-data-on-a-table)

to manipulate tables you have the most important methods wrapped, they all work the same way: parsing arrays of key/value pairs and forming a safe query

the methods are:

```
  $db->insert( string $table, array $data );                // generate an INSERT query
  $db->replace( string $table, array $data );               // generate an REPLACE query
  $db->update( string $table, array $data, array $where );  // generate an UPDATE query
  $db->delete( string $table, array $where );               // generate a DELETE query
```

All methods will return the resulting `mysqli_insert_id()` or true/false depending on context. The correct approach if to always check if they executed as success is always returned

Example: DELETE

```
  $deleteArray = ['user_id' => 9];
  $ok = $db->delete('users', $deleteArray);
  if ($ok) {
    echo "user deleted!";
  } else {
    echo "can't delete user!";
  }
```

**note**: all parameter values are sanitized before execution, you don't have to escape values beforehand.

Example: INSERT

```
  $insertArray = [
    'name'   => "John",
    'email'  => "johnsmith@email.com",
    'group'  => 1,
    'active' => true,
  ];
  $newUserId = $db->insert('users', $insertArray);
  if ($newUserId) {
    echo "new user inserted with the id $new_user_id";
  }
```

Example: REPLACE

```
  $replaceArray = [
      'name'   => 'lars',
      'email'  => 'lars@moelleken.org',
      'group'  => 0
  ];
  $tmpId = $db->replace('users', $replaceArray);
```

#### Binding parameters on queries

[](#binding-parameters-on-queries)

Binding parameters is a good way of preventing mysql injections as the parameters are sanitized before execution.

```
  $sql = "SELECT * FROM users
    WHERE id_user = :id_user
    AND active = :active
    LIMIT 1
  ";
  $result = $db->query($sql, ['id_user' => 11, 'active' => 1]);
  if ($result) {
    $user = $result->fetchArray();
    print_r($user);
  } else {
    echo "user not found";
  }
```

#### Transactions

[](#transactions)

Use `begin()`, `commit()`, and `rollback()` to manage transactions:

```
$db->beginTransaction();

$db->query(
    'UPDATE `users` SET `foo` = :foo WHERE id = :id',
    ['foo' => 100, 'id' => 1]
);
$db->query(
    'UPDATE `users_noop` SET `foo` = :foo WHERE id = :id',
    ['foo' => 100, 'id' => 2]
);

$db->endTransaction();
```

Any SQL errors between `begin()` and `commit()` will yield a `RuntimeException`.

You can also use the `DB->transact()` method. The following is equivalent to the above:

```
$db->transact(function($db) {
    $db->query(
        'UPDATE `users` SET `foo` = :foo WHERE id = :id',
        ['foo' => 100, 'id' => 1]
    );
    $db->query(
        'UPDATE `users_noop` SET `foo` = :foo WHERE id = :id',
        ['foo' => 100, 'id' => 2]
    );
});
```

### Using the "Result"-Class

[](#using-the-result-class)

After executing a `SELECT` query you receive a `Result` object that will help you manipulate the resultant data. there are different ways of accessing this data, check the examples bellow:

#### Fetching all data

[](#fetching-all-data)

```
  $result = $db->query("SELECT * FROM users");
  $allUsers = $result->fetchAll();
```

Fetching all data works as Result::RESULT\_TYPE\_\* the `fetchAll()` and `fetch()` method will return the default based on the `$_default_result_type` config. Other methods are:

```
  $row = $result->fetch();        // fetch an single result row as defined by the config (array, object or Arrayy)
  $row = $result->fetchArray();   // fetch an single result row as array
  $row = $result->fetchArrayy();  // fetch an single result row as Arrayy object
  $row = $result->fetchObject();  // fetch an single result row as object
  $row = $result->fetchYield();   // fetch an single result row as Generator

  $data = $result->fetchAll();        // fetch all result data as defined by the config (array, object or Arrayy)
  $data = $result->fetchAllArray();   // fetch all result data as array
  $data = $result->fetchAllArrayy();  // fetch all result data as Array object
  $data = $result->fetchAllObject();  // fetch all result data as object
  $data = $result->fetchAllYield();   // fetch all result data as Generator

  $data = $result->fetchColumn(string $column, bool $skipNullValues);    // fetch a single column as string
  $data = $result->fetchAllColumn(string $column, bool $skipNullValues); // fetch a single column as an 1-dimension array

  $data = $result->fetchArrayPair(string $key, string $value);           // fetch data as a key/value pair array
```

#### Fetching database-table-fields

[](#fetching-database-table-fields)

Returns rows of field information in a result set:

```
$fields = $result->fetchFields();
```

Pass `true` as argument if you want each field information returned as an associative array instead of an object. The default is to return each as an object, exactly like the `mysqli_fetch_fields` function.

#### Fetching + Callable

[](#fetching--callable)

Fetches a row or a single column within a row:

```
$data = $result->fetch($row_number, $column);
```

This method forms the basis of all fetch\_ methods. All forms of fetch\_ advances the internal row pointer to the next row. `null` will be returned when there are no more rows to be fetched.

#### Fetching + Transpose

[](#fetching--transpose)

Returns all rows at once, transposed as an array of arrays:

```
$plan_details = $plans->fetchTranspose();
```

Transposing a result set of X rows each with Y columns will result in an array of Y rows each with X columns.

Pass a column name as argument to return each column as an associative array with keys taken from values of the provided column. If not provided, the keys will be numeric starting from zero.

e.g.:

```
$transposedExample = [
  'title' => [
    1 => 'Title #1',
    2 => 'Title #2',
    3 => 'Title #3',
  ],
);
```

#### Fetching + Pairs

[](#fetching--pairs)

Returns all rows at once as key-value pairs using the column in the first argument as the key:

```
$countries = $result->fetchPairs('id');
```

Pass a column name as the second argument to only return a single column as the value in each pair:

```
$countries = $result->fetchPairs('id', 'name');

/*
[
  1 => 'Title #1',
  2 => 'Title #2',
  3 => 'Title #3',
]
*/
```

#### Fetching + Groups

[](#fetching--groups)

Returns all rows at once as a grouped array:

```
$students_grouped_by_gender = $result->fetchGroups('gender');
```

Pass a column name as the second argument to only return single columns as the values in each groups:

```
$student_names_grouped_by_gender = $result->fetchGroups('gender', 'name');
```

#### Fetching + first

[](#fetching--first)

Returns the first row element from the result:

```
$first = $result->first();
```

Pass a column name as argument to return a single column from the first row:

```
$name = $result->first('name');
```

#### Fetching + last

[](#fetching--last)

Returns the last row element from the result:

```
$last = $result->last();
```

Pass a column name as argument to return a single column from the last row:

```
$name = $result->last('name');
```

#### Fetching + slice

[](#fetching--slice)

Returns a slice of rows from the result:

```
$slice = $result->slice(1, 10);
```

The above will return 10 rows skipping the first one. The first parameter is the zero-based offset; the second parameter is the number of elements; the third parameter is a boolean value to indicate whether to preserve the keys or not (optional and defaults to false). This methods essentially behaves the same as PHP's built-in `array_slice()` function.

#### Fetching + map

[](#fetching--map)

Sets a mapper callback function that's used inside the `Result->fetchCallable()` method:

```
$result->map(function($row) {
    return (object) $row;
});
$object = $result->fetchCallable(0);
```

The above example will map one row (0) from the result into a object. Set the mapper callback function to null to disable it.

#### Fetching + aliases

[](#fetching--aliases)

```
  $db->get()                  // alias for $db->fetch();
  $db->getAll()               // alias for $db->fetchAll();
  $db->getObject()            // alias for $db->fetchAllObject();
  $db->getArray()             // alias for $db->fetchAllArray();
  $db->getArrayy()            // alias for $db->fetchAllArrayy();
  $db->getYield()             // alias for $db->fetchAllYield();
  $db->getColumn($key)        // alias for $db->fetchColumn($key);
```

#### Fetching + Iterations

[](#fetching--iterations)

To iterate a result-set you can use any fetch() method listed above.

```
  $result = $db->select('users');

  // using while
  while ($row = $result->fetch()) {
    echo $row->name;
    echo $row->email;
  }

  // using foreach (via "fetchAllObject()")
  foreach($result->fetchAllObject() as $row) {
    echo $row->name;
    echo $row->email;
  }

  // using foreach (via "Result"-object)
  foreach($result as $row) {
    echo $row->name;
    echo $row->email;
  }

  // using foreach (via "Generator"-object)
  foreach($result->fetchAllYield() as $row) {
    echo $row->name;
    echo $row->email;
  }

  // INFO: "while + fetch()" and "fetchAllYield()" will use less memory that "foreach + "fetchAllObject()", because we will fetch each result entry seperatly
```

#### Executing Multi Queries

[](#executing-multi-queries)

To execute multiple queries you can use the `$db->multi_query()` method. You can use multiple queries separated by "`;`".

Return-Types:

- "Result"-Array by "**SELECT**"-queries
- "bool" by only "**INSERT**"-queries
- "bool" by only (affected\_rows) by "**UPDATE / DELETE**"-queries
- "bool" by only by e.g. "DROP"-queries

e.g.:

```
$sql = "
    INSERT INTO foo
      SET
        page_template = 'lall1',
        page_type = 'test1';
    INSERT INTO lall
      SET
        page_template = 'lall2',
        page_type = 'test2';
    INSERT INTO bar
      SET
        page_template = 'lall3',
        page_type = 'test3';
";
$result = $this->db->multi_query($sql); // true

$sql = "
    SELECT * FROM foo;
    SELECT * FROM lall;
    SELECT * FROM bar;
";
$result = $this->db->multi_query($sql); // Result[]
foreach ($result as $resultForEach) {
    $tmpArray = $resultForEach->fetchArray();
    ...
}
```

Using the "Prepare"-Class
-------------------------

[](#using-the-prepare-class)

Prepare statements have the advantage that they are built together in the MySQL-Server, so the performance is better.

But the debugging is harder and logging is impossible (via PHP), so we added a wrapper for "bind\_param" called "bind\_param\_debug". With this wrapper we pre-build the sql-query via php (only for debugging / logging). Now you can e.g. echo the query.

INFO: You can still use "bind\_param" instead of "bind\_param\_debug", e.g. if you need better performance.

#### INSERT-Prepare-Query (example)

[](#insert-prepare-query-example)

```
  use voku\db\DB;

  $db = DB::getInstance();

  // -------------
  // prepare the queries

  $query = 'INSERT INTO users
    SET
      name = ?,
      email = ?
  ';

  $prepare = $db->prepare($query);

  $name = '';
  $email = '';

  $prepare->bind_param_debug('ss', $name, $email);

  // -------------
  // execute query no. 1

  // INFO: "$template" and "$type" are references, since we use "bind_param" or "bind_param_debug"
  $name = 'name_1_中';
  $email = 'foo@bar.com';

  $prepare->execute();

  // DEBUG
  echo $prepare->get_sql_with_bound_parameters();

  // -------------
  // execute query no. 2

  // INFO: "$template" and "$type" are references, since we use "bind_param" or "bind_param_debug"
  $name = 'Lars';
  $email = 'lars@moelleken.org';

  $prepare->execute();

  // DEBUG
  echo $prepare->get_sql_with_bound_parameters();
```

#### SELECT-Prepare-Query (example)

[](#select-prepare-query-example)

```
  use voku\db\DB;

  $db = DB::getInstance();

  // -------------
  // insert some dummy-data, first

  $data = [
      'page_template' => 'tpl_test_new123123',
      'page_type'     => 'ö\'ä"ü',
  ];

  // will return the auto-increment value of the new row
  $resultInsert[1] = $db->insert($this->tableName, $data);
  $resultInsert[2] = $db->insert($this->tableName, $data);

  // -------------
  // prepare the queries

  $sql = 'SELECT * FROM ' . $this->tableName . '
    WHERE page_id = ?
  ';

  $prepare = $this->db->prepare($sql);
  $page_id = 0;
  $prepare->bind_param_debug('i', $page_id);

  // -------------
  // execute query no. 1

  $page_id = $resultInsert[1];
  $result = $prepare->execute();
  $data = $result->fetchArray();

  // $data['page_template'] === 'tpl_test_new123123'
  // $data['page_id'] === $page_id

  // -------------
  // execute query no. 2

  $page_id = $resultInsert[2];
  $result = $prepare->execute();
  $data = $result->fetchArray();

  // $data['page_id'] === $page_id
  // $data['page_template'] === 'tpl_test_new123123'
```

### Logging and Errors

[](#logging-and-errors)

You can hook into the "DB"-Class, so you can use your personal "Logger"-Class. But you have to cover the methods:

```
$this->trace(string $text, string $name) { ... }
$this->debug(string $text, string $name) { ... }
$this->info(string $text, string $name) { ... }
$this->warn(string $text, string $name) { ... }
$this->error(string $text, string $name) { ... }
$this->fatal(string $text, string $name) { ... }
```

You can also disable the logging of every sql-query, with the "getInstance()"-parameter "logger\_level" from "DB"-Class. If you set "logger\_level" to something other than "TRACE" or "DEBUG", the "DB"-Class will log only errors anymore.

```
DB::getInstance(
    getConfig('db', 'hostname'),        // hostname
    getConfig('db', 'username'),        // username
    getConfig('db', 'password'),        // password
    getConfig('db', 'database'),        // database
    getConfig('db', 'port'),            // port
    getConfig('db', 'charset'),         // charset
    true,                               // exit_on_error
    true,                               // echo_on_error
    'cms\Logger',                       // logger_class_name
    getConfig('logger', 'level'),       // logger_level | 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'
    getConfig('session', 'db')          // session_to_db
);
```

Showing the query log: The log comes with the SQL executed, the execution time and the result row count.

```
  print_r($db->log());
```

To debug mysql errors, use `$db->errors()` to fetch all errors (returns false if there are no errors) or `$db->lastError()` for information about the last error.

```
  if ($db->errors()) {
    echo $db->lastError();
  }
```

But the easiest way for debugging is to configure "DB"-Class via "DB::getInstance()" to show errors and exit on error (see the example above). Now you can see SQL-errors in your browser if you are working on "localhost" or you can implement your own "checkForDev()" via a simple function, you don't need to extend the "Debug"-Class. If you will receive error-messages via e-mail, you can implement your own "mailToAdmin()"-function instead of extending the "Debug"-Class.

### Changelog

[](#changelog)

See [CHANGELOG.md](CHANGELOG.md).

### Support

[](#support)

For support and donations please visit [Github](https://github.com/voku/simple-mysqli/) | [Issues](https://github.com/voku/simple-mysqli/issues) | [PayPal](https://paypal.me/moelleken) | [Patreon](https://www.patreon.com/voku).

For status updates and release announcements please visit [Releases](https://github.com/voku/simple-mysqli/releases) | [Twitter](https://twitter.com/suckup_de) | [Patreon](https://www.patreon.com/voku/posts).

For professional support please contact [me](https://about.me/voku).

### Thanks

[](#thanks)

- Thanks to [GitHub](https://github.com) (Microsoft) for hosting the code and a good infrastructure including Issues-Managment, etc.
- Thanks to [IntelliJ](https://www.jetbrains.com) as they make the best IDEs for PHP and they gave me an open source license for PhpStorm!
- Thanks to [Travis CI](https://travis-ci.com/) for being the most awesome, easiest continous integration tool out there!
- Thanks to [StyleCI](https://styleci.io/) for the simple but powerfull code style check.
- Thanks to [PHPStan](https://github.com/phpstan/phpstan) &amp;&amp; [Psalm](https://github.com/vimeo/psalm) for relly great Static analysis tools and for discover bugs in the code!

### License

[](#license)

[![FOSSA Status](https://camo.githubusercontent.com/a807f72cd323f42adc528bcf480b8f500541ee7cf0085120180d3631c2986223/68747470733a2f2f6170702e666f7373612e696f2f6170692f70726f6a656374732f6769742532426769746875622e636f6d253246766f6b7525324673696d706c652d6d7973716c692e7376673f747970653d6c61726765)](https://app.fossa.io/projects/git%2Bgithub.com%2Fvoku%2Fsimple-mysqli?ref=badge_large)

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance44

Moderate activity, may be stable

Popularity40

Moderate usage in the ecosystem

Community26

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 92.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~27 days

Recently: every ~176 days

Total

130

Last Release

1380d ago

Major Versions

v4.4.3 → v5.0.02017-07-22

v5.4.7 → v6.0.02017-11-13

v5.4.8 → 6.1.12017-12-21

6.1.1 → 7.0.02017-12-23

7.4.1 → 8.0.02018-12-20

PHP version history (3 changes)0.9PHP &gt;=5.2.0

v1.1PHP &gt;=5.3.0

v6.0.0PHP &gt;=7.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/6456fe693db197c458272cb758bf78958bc7d3e787ccd59db4bf3cf41654316a?d=identicon)[voku](/maintainers/voku)

---

Top Contributors

[![voku](https://avatars.githubusercontent.com/u/264695?v=4)](https://github.com/voku "voku (406 commits)")[![entomb](https://avatars.githubusercontent.com/u/57768?v=4)](https://github.com/entomb "entomb (22 commits)")[![scrutinizer-auto-fixer](https://avatars.githubusercontent.com/u/6253494?v=4)](https://github.com/scrutinizer-auto-fixer "scrutinizer-auto-fixer (3 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (2 commits)")[![etlam](https://avatars.githubusercontent.com/u/1208133?v=4)](https://github.com/etlam "etlam (2 commits)")[![fossabot](https://avatars.githubusercontent.com/u/29791463?v=4)](https://github.com/fossabot "fossabot (1 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (1 commits)")[![dependabot-support](https://avatars.githubusercontent.com/u/112581971?v=4)](https://github.com/dependabot-support "dependabot-support (1 commits)")

---

Tags

databasedatabase-connectordbhacktoberfestmysqlimysqli-to-pdophpsqlphpdbmysqlisimple db

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/voku-simple-mysqli/health.svg)

```
[![Health](https://phpackages.com/badges/voku-simple-mysqli/health.svg)](https://phpackages.com/packages/voku-simple-mysqli)
```

###  Alternatives

[stefangabos/zebra_database

An advanced, compact and lightweight MySQL database wrapper library, built around PHP's MySQLi extension.

11812.0k](/packages/stefangabos-zebra-database)[swoft/db

swoft database component

24167.4k11](/packages/swoft-db)[webparking/laravel-db-rebuild

A laravel package that allows for quick database rebuilds with presets.

448.8k](/packages/webparking-laravel-db-rebuild)[simple-swoole/db

A db component for Simps.

216.3k3](/packages/simple-swoole-db)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
