PHPackages                             quioteframework/propulsion - 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. quioteframework/propulsion

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

quioteframework/propulsion
==========================

Propulsion is an object-relational mapping (ORM) for PHP, forked from Propel 1.

021↑471.4%

Since Jul 7Compare

[ Source](https://github.com/quioteframework/propulsion)[ Packagist](https://packagist.org/packages/quioteframework/propulsion)[ RSS](/packages/quioteframework-propulsion/feed)WikiDiscussions Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Propulsion
==========

[](#propulsion)

[![Tests](https://github.com/quioteframework/propulsion/actions/workflows/tests.yml/badge.svg)](https://github.com/quioteframework/propulsion/actions/workflows/tests.yml)[![codecov](https://camo.githubusercontent.com/def24e95edac88254cfff5e757940a40d8d54c926069f03ebddcc8d7ed3aed74/68747470733a2f2f636f6465636f762e696f2f67682f7175696f74656672616d65776f726b2f70726f70756c73696f6e2f67726170682f62616467652e737667)](https://codecov.io/gh/quioteframework/propulsion)[![Latest release](https://camo.githubusercontent.com/92e0336692b5bfa53b4a2f1e4e523d4c9b73068706e0e255a3e100f5c92f9213/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f7175696f74656672616d65776f726b2f70726f70756c73696f6e)](https://github.com/quioteframework/propulsion/releases)[![PHP](https://camo.githubusercontent.com/b719098f6822b3d5de8b35671fbdb321acb3cccdf7de5a69073aa7965deeaf3f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344382e352d373737626234)](composer.json)[![License: MIT](https://camo.githubusercontent.com/4a393297e1cd4ae3f7c8fc2004b2cea08314d1dba4b9c489acf770973dd7b225/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7175696f74656672616d65776f726b2f70726f70756c73696f6e)](LICENSE)

Propulsion is an object-relational mapper (ORM) for PHP, forked from [Propel 1](https://github.com/propelorm/Propel1) and modernized to target PHP 8.5+.

Propel 1 development had wound down and the project was effectively unmaintained; Propulsion picks up that codebase, renames it, and carries it forward — modern PHP syntax and types throughout, Phing replaced by a plain console app, PostgreSQL promoted to the default/recommended database, and ongoing bug fixes. See `NOTICE.md` for attribution details and `KNOWN_ISSUES.md` for a running log of what's changed and what's still in progress.

Database support
----------------

[](#database-support)

**PostgreSQL is the recommended and default database for new projects**(PostgreSQL 15+; see `KNOWN_ISSUES.md` for the version-support note). It's what this codebase's own test suite, CI, and code generator default to — `generator/default.php`'s `propulsion.database` is `pgsql` out of the box, and `PgsqlPlatform` gets the most feature-parity attention of the bundled platforms. MySQL, SQLite, Oracle, and MSSQL/SQL Server are also supported and exercised by the test suite, and remain a simple per-project override — set `propulsion.database` in your own `build.php` (a plain PHP file returning an array; `--config`, repeatable, on the console commands — a legacy `build.properties` text file is also still accepted), or pass `--database`directly, if you need a different target.

Logging
-------

[](#logging)

Propulsion logs through [PSR-3](https://www.php-fig.org/psr/psr-3/)(`Psr\Log\LoggerInterface`). It does not bundle a concrete logger implementation — bring your own (e.g. [Monolog](https://github.com/Seldaek/monolog), or any other PSR-3 implementation) and register it once, typically right after `Propulsion::init()`:

```
use Propulsion\Propulsion;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

Propulsion::init('/path/to/runtime-conf.php');

$logger = new Logger('propulsion');
$logger->pushHandler(new StreamHandler('/path/to/propulsion.log'));
Propulsion::setLogger($logger);
```

If no logger is registered, `Propulsion::log()` is a no-op and nothing is written anywhere — there is no implicit fallback to `error_log()` or a file on disk.

`Propulsion::LOG_EMERG` .. `Propulsion::LOG_DEBUG` are aliases for the corresponding `Psr\Log\LogLevel::*` string constants, so existing call sites like `Propulsion::log($message, Propulsion::LOG_ERR)` keep working unchanged.

A `PropulsionPDO` connection can also be given its own logger, overriding the globally-registered one for just that connection:

```
$con->setLogger($logger);
```

Migrating `useQuery()`/`endUse()` to `withQuery()` with Rector
--------------------------------------------------------------

[](#migrating-usequeryenduse-to-withquery-with-rector)

`useQuery()`/`endUse()` (and the generated `useQuery()` wrappers) are still fully supported, but are `@deprecated` in favor of a closure-scoped replacement: `withQuery()` on `ModelCriteria`, and a generated `withQuery()` sibling next to every `useQuery()`. The reason: `endUse()` can't statically know which concrete query class originally called `useQuery()` (that information is only tracked at runtime), so it's typed to return the generic `ModelCriteria` base class — which collapses the type of every chained call after it, breaking IDE autocomplete and PHPStan inference for the rest of the chain. The closure form doesn't have this problem: there's no `endUse()` to mistype, since "switching back" is just the callback returning.

```
// before
$books = BookQuery::create()
    ->useAuthorQuery()
        ->filterByFirstName('Jane')
    ->endUse()
    ->find();

// after
$books = BookQuery::create()
    ->withAuthorQuery(fn ($q) => $q->filterByFirstName('Jane'))
    ->find();
```

This also works for relations nested inside other relations, to any depth — including several sibling relations queried inside the same outer relation:

```
$q->withAuthorQuery(fn ($author) => $author
    ->withBookQuery(fn ($book) => $book->filterByTitle('War And Peace'))
    ->withPublisherQuery(fn ($publisher) => $publisher->filterByName('Penguin')));
```

### Automated migration

[](#automated-migration)

Propulsion ships a [Rector](https://github.com/rectorphp/rector) rule, `Propulsion\Generator\Rector\UseQueryToWithQueryRector`, that mechanically rewrites `useQuery()->...->endUse()` chains (including the generated `useQuery()` form, and nested/sibling chains at any depth) into the `withQuery()`/`withQuery()` form shown above. It ships as part of this package's own source, so it's available as soon as you `composer require quioteframework/propulsion` — you just need Rector itself installed to run it:

```
composer require --dev rector/rector
```

Then point your own `rector.php` at the rule:

```
