StormPHP Queries is a combination of a query builder and an Object-Relational Mapping (ORM) library designed to fetch data effectively. It’s intuitive, lightweight, and flexible — with zero configuration required.
composer require stormmore/queries
StormPHP Queries uses PDO:
use Stormmore\Queries\ConnectionFactory;
use Stormmore\Queries\StormQueries;
$connection = ConnectionFactory::createFromString("dsn", "user", "password");
$queries = new StormQueries($connection);
Find product by ID:
$product = $queries->find('products', ['id' => 5]);
Find all products in a category:
$products = $queries->findAll('products', ['category_id' => 10]);
Insert:
$id = $queries->insert('products', [
'name' => 'Golden watch',
'price' => 756
]);
Update:
$queries->update('products', ['id' => $id], ['name' => 'Renamed product']);
Delete:
$queries->delete('products', ['id' => $id]);
Count:
$count = $queries->count('products', ['in_sale' => true]);
Existence check:
$exists = $queries->exist('products', ['id' => 5]);
Map to class:
use Stormmore\Queries\Mapper\Map;
$product = $queries->find('products', ['id' => 5], Map::select([
'product_id' => 'id',
'product_name' => 'name'
], UserProduct::class));
Build a query step by step with a fluent API:
$queries
->select("table", ["column1", "column2"])
->where('id', 2)
->find();
Each method (select
, join
, leftJoin
, where
, orderBy
, etc.) adds parameters instead of replacing them.
$queries->select('columnA')->select('columnB')->select('columnC');
// SELECT columnA, columnB, columnC
$queries->select('products')->count();
$queries->select('products')->min('price');
$queries->select('products')->max('price');
$queries->select('products')->sum('price');
$queries->select('products')->avg('price');
$queries
->select('tableA')
->join('tableB', ['tableB.id' => 'tableA.id')
->find();
//or
$queries
->select('tableA')
->join('tableB', ['tableB.id' => 'tableA.id'])
->find();
$queries
->select('tableA')
->leftJoin('tableB', ['tableB.id' => 'tableA.id'])
->find();
//or
$queries
->select('tableA')
->leftJoin('tableB', ['tableB.id' => 'tableA.id'])
->find();
Supports many operators:
$queries
->select('tableA')
->where('column', 'val1')
->where('column', '=', 'val1')
->where('column', 'IN', ['val2', 'val3'])
->where('column', 'LIKE', '%a%')
->where('column', '<>', 15)
->where('column', 'BETWEEN', 5, 10)
->where('column', 'IS NULL')
->where('columnA = ? and columnB = ?', ['valA', 'valB']);
Default conjunction is AND
. Use orWhere
for OR
.
Nested conditions:
$queries
->select('tableA')
->where('columnA', 'val1')
->where(function($q) {
$q->where('column', 'val2')->orWhere('column', 'val3');
});
$queries->select('table')->orderByDesc('column1');
$queries->select('table')->orderByAsc('column1');
$queries->select('table')->groupBy('column1', 'column2');
$queries
->select('customers', 'country, city, count(*)')
->groupBy('country, city')
->having('count(*)', '>', 1)
->find();
Define mappings for query results:
$orders = $queries
->select('orders o', Map::select("orders", [
'order_id' => 'id',
'order_date' => 'date'
]))
->leftJoin('shippers sh', ['sh.shipper_id' => 'o.shipper_id'], Map::one('shipper', [
'shipper_id' => 'id',
'shipper_name' => 'name'
]))
->findAll();
Supports:
From:
$queries
->select(SubQuery::create($queries->select('products'), 'p'))
->where('p.product_id', 7)
->find();
Left Join:
$queries
->select(SubQuery::create($queries->from('products'), 'p'))
->leftJoin(SubQuery::create($queries->from('suppliers'), 's'), ['s.supplier_id' => 'p.supplier_id'])
->findAll();
Where with subquery:
$queries
->select("products")
->where("category_id", 1)
->where('price', '<=', $queries
->select("avg(price)")
->from("products")
->where("category_id", 1)
)
->findAll();
$query = $queries
->select('products')
->join('product_photos', ['product_photos.product_id' => 'products.id'])
->where('is_in_sale', true);
if ($criteria->hasCategory()) {
$query->where('category_id', $criteria->getCategoryId());
}
if ($criteria->hasOrder()) {
$query->orderBy($criteria->getOrderField(), $criteria->getOrderDirection());
}
if ($criteria->hasSearchPhrase()) {
$query->where('description', "LIKE", '%' . $criteria->getPhrase() . '%');
}
$products = $query->findAll();
$id = $queries->insert('person', ['name' => 'Michael']);
Insert many:
$queries
->insertMany('person', [
['name' => 'Michael'],
['name' => 'Kevin'],
['name' => 'LeBron']
])
->execute();
$queries->update('person', ['id' => 2], ['name' => 'Matthew']);
Or with query builder:
$queries->updateQuery('products')
->where('id', 3)
->set('price = price + 5')
->execute();
$queries->delete('person', ['id' => 1]);
Or with query builder:
$queries->deleteQuery('person')->where('id', 1)->execute();
$connection->onSuccess(function(string $sql, DateInterval $interval) {
// log successful queries
});
$connection->onFailure(function(string $sql, DateInterval $interval, Exception $e) {
// log failed queries
});
Run tests with Docker:
docker-compose up
./run.mysql.cmd
See the tests
directory for more detailed use cases.
Michał Czerski
StormPHP Queries is licensed under the MIT License.