PHPackages                             pllano/router-db - 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. pllano/router-db

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

pllano/router-db
================

One interface for different databases

1.2.0(8y ago)015MITPHPPHP &gt;=5.3.0

Since Jan 3Pushed 7y ago1 watchersCompare

[ Source](https://github.com/pllano/router-db)[ Packagist](https://packagist.org/packages/pllano/router-db)[ Docs](https://github.com/pllano/router-db)[ RSS](/packages/pllano-router-db/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (9)Dependencies (2)Versions (10)Used By (0)

routerDb
========

[](#routerdb)

One interface for working with all databases
--------------------------------------------

[](#one-interface-for-working-with-all-databases)

Simple and clear code
---------------------

[](#simple-and-clear-code)

```
use Pllano\RouterDb\Router as RouterDb;

// Table (resource)
$table = "user";
// Adapter: Pdo, Apis, ZendDb, DoctrineDbal, NetteDb (Default: Pdo)
$routerDb = new RouterDb($config, 'Pdo');
// Ping the available database for the resource
$db = $routerDb->run($routerDb->ping($table));
// Or indicate the base, without ping
// $db = $routerDb->run("mysql");

// Array for the query
$query = [];
$id = 1;
// Get user data id = 1 from mysql database
$data = $db->get($table, $query, $id);
```

```
// The same in one line
$data = ((new \Pllano\RouterDb\Router($config, 'Pdo'))->run("mysql"))->get("user", [], 1);
```

```
// More readable code
use Pllano\RouterDb\Router as RouterDb;
$routerDb = new RouterDb($config, 'Pdo');
$data = ($routerDb->run("mysql"))->get("user", [], 1);
```

```
use Pllano\RouterDb\Router as RouterDb;
$routerDb = new RouterDb($config, 'Pdo');
// To connect to the second mysql_duo database, you need to pass in the third parameter the prefix duo
$db = $routerDb->run('mysql', [], 'duo');
$data = $db->get($table, $query, $id);
```

Types of requests
-----------------

[](#types-of-requests)

```
$post = $db->post($table, $query, $field_id);
$get = $db->get($table, $query, $id, $field_id);
$put = $db->put($table, $query, $id, $field_id);
$del = $db->del($table, $query, $id, $field_id);
$count = $db->count($table, $query, $id, $field_id);
$last_id = $db->last_id($table);

// Exclusive method
$data = $db->pdo($sql)->fetchAll(); // $db->prepare($sql)->execute()->fetchAll();
$data = $db->pdo($sql, $params)->fetchAll(); // $db->prepare($sql)->execute($params)->fetchAll();

// In style PDO
$data = $db->prepare($sql)->execute($params)->fetch();
$data = $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
```

```
use Pllano\RouterDb\Router as RouterDb;
$routerDb = new RouterDb($config, 'Pdo');
$db = $routerDb->run('mysql');
$data = $db->pdo("SELECT * FROM users WHERE user_id=?", [$user_id])->fetchAll();
// or
$data = $db->prepare($sql)->execute($params)->fetch();
```

In style Slim-PDO

```
// https://github.com/FaaPz/Slim-PDO/blob/master/docs/README.md

// SELECT * FROM users WHERE id = ?
$selectStatement = $db->select()
                       ->from('users')
                       ->where('id', '=', 1234);
$stmt = $selectStatement->execute();
$data = $stmt->fetch();

// INSERT INTO users ( id , usr , pwd ) VALUES ( ? , ? , ? )
$insertStatement = $db->insert(['id', 'usr', 'pwd'])
                       ->into('users')
                       ->values([1234, 'your_username', 'your_password']);
$insertId = $insertStatement->execute(false);

// UPDATE users SET pwd = ? WHERE id = ?
$updateStatement = $db->update(['pwd' => 'your_new_password'])
                       ->table('users')
                       ->where('id', '=', 1234);
$affectedRows = $updateStatement->execute();

// DELETE FROM users WHERE id = ?
$deleteStatement = $db->delete()
                       ->from('users')
                       ->where('id', '=', 1234);
$affectedRows = $deleteStatement->execute();
```

```
public function post(string $resource = null, array $query = [], string $field_id = null): int {}
public function last_id(string $resource = null): int {}
public function get(string $resource = null, array $query = [], int $field_id = null, string $field_id = null): array {}
public function put(string $resource = null, array $query = [], int $field_id = null, string $field_id = null): int {}
public function del(string $resource = null, array $query = [], int $field_id = null, string $field_id = null): int {}
public function count(string $resource = null, array $query = [], int $field_id = null, string $field_id = null): int {}
```

```
// Configuration
$config = [
    "db" => [
        "master" => "mysql",
        "slave" => "elasticsearch",
        "mysql" => [
            "host" => "localhost",
            "dbname" => "",
            "port" => "",
            "charset" => "utf8",
            "connect_timeout" => "15",
            "user" => "",
            "password" => ""
        ],
        "mysql_duo" => [
            "host" => "localhost",
            "dbname" => "",
            "port" => "",
            "charset" => "utf8",
            "connect_timeout" => "15",
            "user" => "",
            "password" => ""
        ]
    ],
    "resource" => [
        "user" => [
            "db" => "mysql"
        ],
        "article" => [
            "db" => "elasticsearch"
        ],
        "price" => [
            "db" => "api"
        ]
    ]
];
```

Installation
------------

[](#installation)

Use [Composer](https://getcomposer.org/)

```
"require" {
    ...
-    "pllano/router-db": "1.1.*",
+    "pllano/router-db": "1.2.0",
    ...
}
```

Use [AutoRequire](https://github.com/pllano/auto-require)

```
"require" [
    {
        "namespace": "Pllano\\RouterDb",
        "dir": "/pllano/router-db/src",
        "link": "https://github.com/pllano/router-db/archive/master.zip",
        "name": "router-db",
        "version": "master",
        "vendor": "pllano"
    }
]
```

Protection against SQL injections
---------------------------------

[](#protection-against-sql-injections)

### Example injection

[](#example-injection)

An SQL injection against which prepared statements won't help

```

```

### Method 1 (Can help in 99% of cases.)

[](#method-1-can-help-in-99-of-cases)

Check the existence of the key in the table &amp; Search for keywords

We plan to embed this method in the function

```
$post = $db->post($table, $query, $field_id);
```

```
use Pllano\RouterDb\Utility;
use Pllano\RouterDb\Router as RouterDb;

$utility = new Utility();
$uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$host = $_SERVER['HTTP_HOST'];
$escaped_url = htmlspecialchars($uri, ENT_QUOTES, 'UTF-8');
$inj = 'sql_injection';

$routerDb = new RouterDb($config, 'Pdo');
$routerDb->setLogger($this->logger);
$routerDb->setMailer($this->mailer);
$db = $routerDb->run('mysql');
$table = 'users';
// The name of the table that we want the structure of.
// Get The Structure Of A MySQL Table In PHP (PDO).
// Query MySQL with the PDO objecy.
// The SQL statement is: DESCRIBE [INSERT TABLE NAME]
// Fetch our result.
$fieldMap = $db->fieldMap($table);
// The result should be an array of arrays,
// with each array containing information about the columns
// that the table has.
// var_dump($result);
$table_schema = [];
foreach($fieldMap as $column){
    $field = $column['Field'];
    $field_type = $column['Type'];
    $table_schema[$field] = $field_type;
}
// Or determine the list yourself
// $table_schema = array_flip(["id", "user_id", "name", "surname", "email", "phone"]);
// Or
// $table_schema = array_flip(explode(",", "id,user_id,name,surname,email,phone"));

$params = [];
$setStr = "";
$x = 2; // If search_injections finds $x keywords from the list
foreach ($_POST as $key => $value)
{
    if (array_key_exists($key, $table_schema)) {
        if ($utility->search_injections($value) >= $x) {
            // Write to the log. A letter to the administrator.
            $db->logger->info($inj, [
                "key" => $key,
                "value" => $value,
                "url" => $escaped_url,
                "request" => [$request]
            ]);
            $db->mailer->setFrom(['attention@'.$host => 'Attention SQL injection'])
            ->setTo(['admin@'.$host => 'Admin'])
            ->setBody('Attention SQL injection: '.$uri);
            return $inj; // Stop Execution
        } else {
            if ($key != "id") {
                $setStr .= "`".str_replace("`", "``", $key)."` = :".$key.",";
            }
            $params[$key] = filter_var($value, FILTER_SANITIZE_STRING);
        }
    } else {
        if ($utility->search_injections($key) >= 1 || $utility->search_injections($value) >= 1) {
            // Write to the log. A letter to the administrator.
            $db->logger->info($inj, [
                "key" => $key,
                "value" => $value,
                "url" => $escaped_url,
                "request" => [$request]
            ]);
            $db->mailer->setFrom(['attention@'.$host => 'Attention SQL injection'])
            ->setTo(['admin@'.$host => 'Admin'])
            ->setBody('Attention SQL injection: '.$uri);
            return $inj; // Stop Execution
        }
    }
}

if (isset($_POST['id']) ?? is_int($_POST['id'])) {
    $params['id'] = intval($_POST['id']);
    $setStr = rtrim($setStr, ",");
    $db->prepare("UPDATE $table SET $setStr WHERE id = :id")->execute($params);
}
```

### function search\_injections()

[](#function-search_injections)

Very simple function

```
public function search_injections(string $value = null, array $add_keywords = [], array $new_keywords = []): int
{
    $list_keywords = [];
    if (isset($value)) {
        if (isset($new_keywords)) {
            $list_keywords = $new_keywords;
        } else {
            $plus_keywords = [];
            if (isset($add_keywords)) {
                $plus_keywords = $add_keywords;
            }
            $list_keywords = [
            '*',
            'SELECT',
            'UPDATE',
            'DELETE',
            'INSERT',
            'INTO',
            'VALUES',
            'FROM',
            'LEFT',
            'JOIN',
            'WHERE',
            'LIMIT',
            'ORDER BY',
            'AND',
            'OR ',
            'DESC',
            'ASC',
            'ON',
            'LOAD_FILE',
            'GROUP',
            'BY',
            'foreach',
            'echo',
            'script',
            'javascript',
            'public',
            'function',
            'admin',
            'root',
            'push',
            '"false"',
            '"true"',
            'return',
            'onclick'
            ];
            $keywords = array_replace_recursive($list_keywords, $plus_keywords);
        }
        $value = str_ireplace($keywords, "👌", $value, $i);
        return $i;
    } else {
        return 0;
    }
}
```

Support, feedback, news
-----------------------

[](#support-feedback-news)

Contact:

- [issues](https://github.com/pllano/router-db/issues)
- [Commits](https://github.com/pllano/router-db/commits/master)
- [RSS](https://github.com/pllano/router-db/commits/master.atom)

License
-------

[](#license)

The MIT License (MIT). Please see [LICENSE](https://github.com/pllano/router-db/blob/master/LICENSE) for more information.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~7 days

Total

9

Last Release

2990d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/83c4d844db99c883895755ca0e1dab41ba50f6e9faedbb972c2d35230a7dc0c2?d=identicon)[joomimart](/maintainers/joomimart)

---

Top Contributors

[![ruslan-avantis](https://avatars.githubusercontent.com/u/16430046?v=4)](https://github.com/ruslan-avantis "ruslan-avantis (360 commits)")

---

Tags

routerdb

### Embed Badge

![Health badge](/badges/pllano-router-db/health.svg)

```
[![Health](https://phpackages.com/badges/pllano-router-db/health.svg)](https://phpackages.com/packages/pllano-router-db)
```

###  Alternatives

[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k46.2M402](/packages/robmorgan-phinx)[spatie/laravel-translation-loader

Store your language lines in the database, yaml or other sources

8362.9M51](/packages/spatie-laravel-translation-loader)[aura/sqlquery

Object-oriented query builders for MySQL, Postgres, SQLite, and SQLServer; can be used with any database connection library.

4572.9M34](/packages/aura-sqlquery)[laminas/laminas-db

Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations

13922.5M206](/packages/laminas-laminas-db)[envms/fluentpdo

FluentPDO is a quick and light PHP library for rapid query building. It features a smart join builder, which automatically creates table joins.

925511.7k13](/packages/envms-fluentpdo)[danielme85/laravel-log-to-db

Custom Laravel Log channel handler that can store log events to SQL or MongoDB databases. Uses Laravel native logging functionality.

135934.5k1](/packages/danielme85-laravel-log-to-db)

PHPackages © 2026

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