paragonie/easydb — a data project — sits at 737 GitHub stars in the Data space. Easy-to-use PDO wrapper for PHP projects.
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
PDO lacks brevity and simplicity; EasyDB makes separating data from instructions
easy (and aesthetically pleasing).
EasyDB was created by Paragon Initiative Enterprises
as part of our effort to encourage better application security practices.
Check out our other open source projects too.
If you're looking for a full-fledged query builder, check out
Latitude and Aura.SqlQuery,
which can be used with EasyDB.
If you'd like to use EasyDB but cache prepared statements in memory for
multiple queries (i.e. to reduce database round-trips), check out our
EasyDB-Cache wrapper class.
If you've installed Composer in /usr/bin, you can replace
/path/to/your/local/composer.phar with just composer.
Why Use EasyDB? Because it's cleaner!
Let's refactor a dangerous PHP snippet that previously used string concatenation to pass user input
instead of prepared statements. For example, imagine something that just dropped {$_GET['blogpostid']} into the
middle of a mysql_query() statement. Let's make it secure.
The PDO Way
$db = new \PDO(
'mysql:host=localhost;dbname=something',
'username',
'putastrongpasswordhere'
);
$statement = $db->prepare('SELECT * FROM comments WHERE blogpostid = ? ORDER BY created ASC');
$exec = $statement->execute([$_GET['blogpostid']]);
$rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$template_engine->render('comment', $row);
}
That's a little wordy for such a simple task. If we do this in multiple places,
we end up repeating ourselves a lot.
The EasyDB Solution
$db = \ParagonIE\EasyDB\Factory::fromArray([
'mysql:host=localhost;dbname=something',
'username',
'putastrongpasswordhere'
]);
$rows = $db->run('SELECT * FROM comments WHERE blogpostid = ? ORDER BY created ASC', $_GET['blogpostid']);
foreach ($rows as $row) {
$template_engine->render('comment', $row);
}
This is equivalent to the following SQL query (assuming $_POST['blogpostid']
is equal to 123, $_SESSION['user'] is equal to 234, $_POST['body'] is
equal to test, and $_POST['replyTo'] is equal to 3456):
This is equivalent to the following SQL query
(assuming $_POST['comment'] is equal to 789):
UPDATE comments
SET
column = 'foo',
otherColumn = 123456,
approved = TRUE
WHERE commentid = 789
Delete a row from a database table
// Delete all of this user's comments
$db->delete('comments', [
'userid' => 3
]);
This is equivalent to the following SQL query:
DELETE FROM comments WHERE userid = 3
Fetch a single row from a table
$userData = $db->row(
"SELECT * FROM users WHERE userid = ?",
$_GET['userid']
);
Note: This expects a variadic list of arguments, not an array. If you have
multiple parameters, stack them like this:
$userData = $db->row(
"SELECT * FROM users WHERE userid = ? AND other = ?",
$_GET['userid'],
$_GET['other']
);
This is wrong:
$userData = $db->row(
"SELECT * FROM users WHERE userid = ? AND other = ?",
array($userid, $other) // WRONG, should not be in an array
);
Fetch a single column from a single row from a table
$exists = $db->cell(
"SELECT count(id) FROM users WHERE email = ?",
$_POST['email']
);
/* OR YOU CAN CALL IT THIS WAY: */
$exists = $db->single(
"SELECT count(id) FROM users WHERE email = ?",
array(
$_POST['email']
)
);
Note: cell() expects a variadic list of arguments, not an array. If you have
multiple parameters, stack them like this:
$exists = $db->cell(
"SELECT count(id) FROM users WHERE email = ? AND username = ?",
$_POST['email'],
$_POST['usenrame']
);
This is wrong:
$exists = $db->cell(
"SELECT count(id) FROM users WHERE email = ? AND username = ?",
array($email, $username) // WRONG, should not be in an array
);
Alternatively, you can use single() instead of cell() if you really
want to pass an array.
Try to perform a transaction
$save = function (EasyDB $db) use ($userData, $query) : int {
$db->safeQuery($query, [$userData['userId']]);
return \Some\Other\Package::CleanUpTable($db);
};
// auto starts, commits and rolls back a transaction as necessary
$returnedInt = $db->tryFlatTransaction($save);
Generate dynamic query conditions
$statement = EasyStatement::open()
->with('last_login IS NOT NULL');
if (strpos($_POST['search'], '@') !== false) {
// Perform a username search
$statement->orWith('username LIKE ?', '%' . $db->escapeLikeValue($_POST['search']) . '%');
} else {
// Perform an email search
$statement->orWith('email = ?', $_POST['search']);
}
// The statement can compile itself to a string with placeholders:
echo $statement; /* last_login IS NOT NULL OR username LIKE ? */
// All the values passed to the statement are captured and can be used for querying:
$user = $db->single("SELECT * FROM users WHERE $statement", $statement->values());
Note: Passing values with conditions is entirely optional but recommended.
Variable number of "IN" arguments
// Statements also handle translation for IN conditions with variable arguments,
// using a special ?* placeholder:
$roles = [1];
if ($_GET['with_managers']) {
$roles[] = 2;
}
$statement = EasyStatement::open()->in('role IN (?*)', $roles);
// The ?* placeholder is replaced by the correct number of ? placeholders:
echo $statement; /* role IN (?, ?) */
// And the values will be unpacked accordingly:
print_r($statement->values()); /* [1, 2] */
Grouping of conditions
// Statements can also be grouped when necessary:
$statement = EasyStatement::open()
->group()
->with('subtotal > ?')
->andWith('taxes > ?')
->end()
->orGroup()
->with('cost > ?')
->andWith('cancelled = 1')
->end();
echo $statement; /* (subtotal > ? AND taxes > ?) OR (cost > ? AND cancelled = 1) */
Insert and Update with custom placeholder
Since Version 2.12.0, EasyDB supports placeholders for calling stored procedures and SQL functions
when inserting or updating data.
The EasyPlaceholder class is constructed in the same fashion as other EasyDB methods: The first
argument, the "mask", must be a string. The mask may contain ? placeholders, and any subsequent
arguments will fill in for the ? placeholders when the query is executed.
EasyDB's run() method is a variadic wrapper for safeQuery(), so either
solution is correct.
Support Contracts
If your company uses this library in their products or services, you may be
interested in purchasing a support contract from Paragon Initiative Enterprises.
The most recent commit recorded on paragonie/easydb was 4 months ago, based on the GitHub push timestamp. The repository has 87 forks — one of the better signals of community interest.
How many stars does paragonie/easydb have?
paragonie/easydb has 737 GitHub stars — refresh the page for the live number, or check github.com/paragonie/easydb. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is paragonie/easydb open source?
Yes — paragonie/easydb ships under the MIT license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/paragonie/easydb.
What else is in the Data space?
paragonie/easydb is tracked by TopGit under the Data category, alongside 9 GitHub-tagged topics. Trending and Topics pages list peer repositories of comparable stars and language.
What topics is paragonie/easydb associated with?
GitHub's repository topics for paragonie/easydb: "database", "databases", "mysql", "pdo", "php", "postgresql", "prepared-statements", "secure-by-default", "sqlite". TopGit's editorial category is Data.
Where can I see paragonie/easydb in action?
The project maintains a homepage at https://paragonie.com/projects. The README tab on this page also usually contains screenshots and a quickstart.
Where do I read more about paragonie/easydb?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/paragonie/easydb is the definitive source.
Read full README in the tab above.
Is easydb worth your time?
ChatGPT, Claude and Perplexity can all read this page. Ask one of them what it makes of easydb.