Perpl is a fork of the unmaintained Propel2, an open-source Object-Relational Mapping (ORM) for PHP. It adds several improvements and fixes, including proper versioning.
- Replace the
requiredeclaration for Propel with Perpl:
"require": {
+ "perplorm/perpl": ">=2.0",
- "propel/propel": "dev-main as 2.0.x-dev",
},- Remove the
vcsentry for Propel2 dev in composer.json:
"repositories": [
- {
- "type": "vcs",
- "url": "git@github.com:propelorm/Propel2.git"
- }
],- Update libraries:
$ composer update- Rebuild models:
$ vendor/bin/propel --config-dir <path/to/config> model:build
$ composer dump-autoload- Open a file where you call
Query::find()and replace it withQuery::findObjects(). If everything worked, you get return typeObjectCollection<YourModelName>. Yay!
| ⚡ Don't forget to analyze your project with PHPStan (or similar) to get notice where updates are necessary due to improved types in Perpl. |
|---|
Motivation for Perpl was to make features available around code-style, typing, performance and usability.
Code is tested to run in PHP 8.5 without deprecation notices or warnings.
Improved types allow for code completion and statistic analysis.
- preserves types between calls to
useXXXQuery()/endUse() - adds methods
findObjects()/findTuples(), which return typed Collection objects
// keep query class over calls to useQuery()
$q = BookQuery::create(); // BookQuery<null>
$q = $q->useAuthorQuery(); // AuthorQuery<BookQuery<null>>
$q = $q->useEssayRelatedByFirstAuthorIdExistsQuery(); // EssayQuery<AuthorQuery<BookQuery<null>>>
$q = $q->endUse(); // AuthorQuery<BookQuery<null>>
$q = $q->endUse(); // BookQuery<null>
// keep query class over conditional chain
$q->_if($condition)
->filterBy...()
->_else()
->filterBy...()
->_endif(); // all BookQuery<null>
// findObjects() returns object collection
$o = $q->findObjects(); // BookCollection
$a = $o->populateAuthor() // AuthorCollection
$a = $a->getFirst(); // Author|null
// findTuples() returns arrays
$a = $q->findTuples(); // ArrayCollection
$r = $q->getFirst(); // array<string, mixed>|nullNote that type propagation in endUse() requires child query classes to declare and pass on the generic parameter from their parent/base class:
/*
* @template ParentQuery extends \Propel\Runtime\ActiveQuery\TypedModelCriteria|null = null
* @extends BaseBookQuery<ParentQuery>
*/
class BookQuery extends BaseBookQueryThis cannot be added automatically for existing classes. While IDEs seem to figure it out without the declaration, phpstan or psalm will (correctly) see the return type as null and report errors. Add the declaration in the child class to fix it.
Generating collection classes for models can be configured in schema.xml, (see #47 for details)
These changes mostly improve internal readability/soundness of core Propel code. They mostly allow for easier and safe maintenance, but occasionally lead to performance improvements, for example when repetitive operations on strings are replaced by proper data structures.
Some notable changes:
- columns in queries are turned to objects, which leads to more readable code and makes tons of string operations obsolete (~30-50% faster query build time, see #24)
- fixes some confusing names (Criteria vs Criterion)
- spreads out some "one size fits none" overloads, i.e.
Criteria::mapbecomesCriteria::columnFiltersandCriteria::updateValues
Introduces Criteria::combineFilters()/Criteria::endCombineFilters() which build nested filter conditions:
// A=1 AND (B=2 OR C=3) AND (D=4 OR E=5)
(new Criteria())
->addFilter('A', 1)
->combineFilters()
->addFilter('B', 2)
->addOr('C', 3)
->endCombineFilters()
->combineFilters()
->addFilter('D', 4)
->addOr('E', 5)
->endCombineFilters()Previously, this required to register the individual parts under an arbitrary name using Criteria::addCond() and then combining them with Criteria::combine(), possibly under another arbitrary name for further processing.
Propel restricts reading behaviors from repositories to one per repo. This allows to read multiple behaviors (see #25 for details).
Creates methods for all elements of ternary relation (Propel only uses first foreign key). Fixes naming issues and detects duplicates in model method names.
Built with care, tested, provided as is. Test before deployment. Let me know how it goes!
Feedback and PRs are welcome.
Thanks to Propel2!
MIT. See the LICENSE file for details.