perplorm / perpl
Perpl is an improved and still maintained fork of Propel2, an open-source Object-Relational Mapping (ORM) for PHP.
Requires
- php: >=8.1
- ext-json: *
- ext-pdo: *
- ext-xml: *
- psr/log: ^1.0 || ^2.0 || ^3.0
- symfony/config: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/console: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/filesystem: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/finder: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/polyfill-php82: ^1.33
- symfony/polyfill-php83: ^1.33
- symfony/polyfill-php84: ^1.33
- symfony/polyfill-php85: ^1.33
- symfony/translation: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/validator: ^6.0.0 || ^7.0.0 || ^8.0.0
- symfony/yaml: ^6.0.0 || ^7.0.0 || ^8.0.0
Requires (Dev)
- mikey179/vfsstream: ^1.6
- monolog/monolog: ^1.3 || ^2.3 || ^3.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.0
- phpstan/phpstan-deprecation-rules: ^2.0
- phpunit/phpunit: ^9.5.0
- psalm/phar: ^6
- spryker/code-sniffer: ^0.17.2
Suggests
- monolog/monolog: The recommended logging library to use with Propel.
Replaces
- propel/propel: dev-main as 2.0.x-dev
- dev-main
- v2.7.0
- v2.6.0
- v2.5.0
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.0
- dev-master / 2.0.x-dev
- v2.0.0
- 2.0.0-alpha12
- 2.0.0-alpha11
- 2.0.0-alpha10
- 2.0.0-alpha9
- 2.0.0-alpha8
- 2.0.0-alpha7
- 2.0.0-alpha6
- 2.0.0-alpha5
- 2.0.0-alpha4
- 2.0.0-alpha3
- 2.0.0-alpha2
- 2.0.0-alpha1
- dev-bugfix-text-defaults-handling
- dev-update-readme
- dev-develop
- dev-enum_fixup
- dev-object_builder_cleanup
This package is auto-updated.
Last update: 2026-03-11 16:24:03 UTC
README
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.
Installation
- 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. |
|---|
Features
Motivation for Perpl was to make features available around code-style, typing, performance and usability.
Ready for PHP 8.5
Code is tested to run in PHP 8.5 without deprecation notices or warnings.
Type-preserving queries
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>|null
Note 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 BaseBookQuery
This 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)
Code cleanup and improved performance
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
Nested filters through operators
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.
Read multiple behaviors from same repository
Propel restricts reading behaviors from repositories to one per repo. This allows to read multiple behaviors (see #25 for details).
Fixed cross-relations
Creates methods for all elements of ternary relation (Propel only uses first foreign key). Fixes naming issues and detects duplicates in model method names.
Disclaimer
Built with care, tested, provided as is. Test before deployment. Let me know how it goes!
Feedback and PRs are welcome.
Thanks to Propel2!
License
MIT. See the LICENSE file for details.