PHP Data Access Libraries (ORM, ActiveRecord, Persistence)

2017-12-21 16:47:00
For description on the comparison criteria, please read full article here:
DoctrineAgile DataEloquentYii ORMCake ORMFuel ORMRed Bean PHPTingSpiral ORM..
Site webhttp://www.doctrine-project.org
DescriptionData Access Framework for high-latency databases (Cloud SQL/NoSQL).RedBeanPHP is an easy to use ORM for PHP. It's a Zero Config ORM lib that 'automagically' builds your database schema.Simple: no magic inside : it’s basically SQL queriesORM engine with automatic database scaffolding, strict schemas, code discovery, modular database partitions and various relation loaders.
Github / Bitbucket / Sourceforge
LicenceMITMITBSD-3New BSD / GPLApache 2MIT
Dernière version2.5.51.2.x2.
How schema is defined?PHP, XML, YAMLin PHP. Method init() in Model class defines fields, relations, conditions, etc.Model class propertiesActive record magic properties.Automatically discovered on the fly.PHPPHP Const array. Column class.
Code generationOui schema-toolOui Web and console generator
Can be used in Any FrameworkOui composer / packagistOui Through composer/packagistOui Through Capsule- Planned in 2.1.xOuiOui composer / packagist
Automated CacheOui Frameworks focuses on optimizing queries rather then caching. Still possible with cross-persistence saving.OuiOui
Anti-patterns (purposely included)Model close-coupled with Persistence and Field classes.Eloquent is a God Class; Global functions; DB Conection is global;
DependenciesMedium: ±5 packages.Minimal: 2 packages: DSQL Query Builder ( 3, pimple, doctrine/cache, aura/sqlquery
Simplicité0 aucune note5.0 2 notes0 aucune note5.0 2 notes0 aucune note0 aucune note0 aucune note5.0 1 note0 aucune note0 aucune note
Enterprise Compliance5.0 1 note5.0 2 notes3.0 1 note4.5 2 notes0 aucune note0 aucune note0 aucune note5.0 1 note0 aucune note0 aucune note
Minimum PHP Version5.
Basic Features
PDO SupportOui YesOui YesOuiOui- But made a custom driver to support it is easyOui
Transparent support for NoSQL- Through 3rd party drivers.Non Eloquent is built on Query Builder. Perhaps moloquent? Also - Through Caching backend, but not as ORM native persistence.Oui Avialable cross sql and nosql datababase relations ( Build around plain queries.NonNon No, through ODM (
How to invoke db-vendor-specific extensions?Oui DBALOui For SQL - save/load/delete operations are expressed in DSQL Queries that can be manipulated: Through Query Builder / RAW queries.Oui SQL - Query Builder.- Can add SQL code chunks.Oui Ting use native query, you can use everyting of your SGBDOui Query models:
Array as a persistenceOui CRUD operations supportedOui
RestAPI as a persistence- Through 3rd party extension.- To extend BaseActiveRecordNonNon
JSON string as a persistenceOui Supported with few extra lines of code.- To extend BaseActiveRecordNonNon
Same model, multiple persistencesOui Same class. Different object.- (no docs)
Basic Single-record operations (C,R,U,D)
Table Name MappingOui YesOui YesOui Same as model class name by defaultOui Using static method of active record. mapping no longer supported.Oui Yes
Field Name MappingOui Yes, (Annotations in PHP)Oui Yes (Field::actual property)- Through accessors/3rd party extensionOuiNon mapping no longer supported.Oui Yes
Map Entity to SubQueryNon Must be physical tableOui Yes. Extension exist for UNION-models. Must be physical table.- table = new Expression(..)NonNon This concept is no-sense for Ting
Map property to expressionNon Must be physical fieldOui $model->addExpression()Non Must be physical table- (couldn't find docs)NonNon This concept is no-sense for Ting
Map native types (DateTime)Oui $field->type = 'date'Oui Accessors and MutatorsOui Active record behaviorsOuiOui Yes- No support for DateTime.
User-defined types (e.g. "23 USD")Oui Type classOui Yes. Independent from Model. by extending Field class.Oui Accessors and MutatorsOui Active record behaviorsOui Yes, with custom serializer
Map field of related Entity ('currency' = currency_id->Model Specific record onlyOui Transparently maps into sub-select.- Relationship, but only single record.Oui $model->currency->nameNonOui Yes
Map field to sub-query on related entity (Client.balance = Client->orders->sum(total))NonOui Yes. hasMany()->addField(..aggregate)Non- (couldn't find docs)Non- This concept is no-sense for Ting
Entity to join multiple tables (adding new record populates both tables)Oui AssociationsOui $model->join('other_table')NonNon No native support.NonOui Yes
Criteria, Scope, Conditions (Model will refuse to work with records that does not match criteria)
Support model-level criteriaOui Yes. Applied on loading / saving / update.- Global Scope (querying only)NonNon
Soft-deleteOui ExtensionOui Through criteria. Example given in the docs.Oui Trait and ScopeOui Events and behaviorsNon
Domain Model CriteriaOui $m->addCondition('gender','M'); where 'gender' can be arbitrary expression, sub-select, field from association(join) or mapped no another physical field.- Scopes, but not in domain model.Non Only for specific query: User::find()->byEmail('...')->active()->one()Non
Expression-based conditionOui $m->addCondition($m->expr('..'));Oui through Query BuilderNon Only for query: User::find()->andWhere('...')->all()Non
Criteria Compliance (new record must match condition)Oui Transaction rollback and exception. Automated-rloading.NonNon
Dynamic criteriaOui $user->addCondition('is_expired', false)Non Only Querying: User::find()->where(['a' => '1', 'b' => true])->all();Non
Query Building (Convert Model into Query object for further SQL tweaking)
Convert Model into Query ObjectOui $q = $model->action('select');Oui Model is a Query object. See: Model::where()Oui \yii\db\ActiveRecord::find()NonOui RecordSelector
Raw expressionOui new Expression('any sql')Oui DB::raw()Oui new \yii\db\Expression('...')OuiOui
Nested/Composite Queries/ExpressionsOui Expression can be in any part of queryNonOui Expression can be in any part of queryNon
Reference domain-model field in queryOui through Expressionable interfaceNon No fields. Only properties.Non Field is class property.NonNon
field, where, order, limitOui Expressions and Parametric valuesOuiOui \yii\db\ActiveQueryNonOui
options, rollup, partition- Through custom templates, or expressions.- not sure.
UPDATE, DELETE, INSERT query buildingOuiOuiNonOui
REPLACE, TRUNCATEOui- Throught raw sql in \yii\db\Command- wipe(),
SHOW, DESCRIBE, CALL- Supported through Expressions or Custom query template- Throught raw sql in \yii\db\Command- Automatic schema alter / discovery.
ALTER, CREATE query buildingOui Addon:
User-defined query templateOui Templates for all queriesOui (please link doc)Non
full support for OR conditionsOui Through Object Composition and Expressions- Partial-Non only raw query
Use Domain logic in multi-record update- Supported, but must map fields/values manually.NonNonNon
Data Fetching (different ways to retrieve data from database)
Get All Data (2x array)OuiOuiOui \yii\db\Query::all()Oui exportAll()Oui
Associative Array (id=>value)Non PlannedOui lists()
Select only required fieldsOui
Typecasting (e.g. DateTime)OuiOui
Import (multiple records)OuiOui
Respect domain model mapping (and criteria)Oui
Single rowOui loadAnyOuiOui \yii\db\Query::one()Oui
Single ValueOui Through actionOuiOui \yii\db\Query::scalar()Oui
Single Column- may need to map resulting arrayOuiOui \yii\db\Query::column()OuiOui
Bypass persistence mappingOui action('select')->getAll()Oui ?? (e..g prevent date from being transformed into Carbon)
Loading and Saving individual records
Load by IDOui load(id)Oui User::findOne(1)OuiOui get(id)Oui findByPK
Load by other fieldOui loadBy('field', $value)Oui User::findOne(['id' => 1])NonOui getBy(['propertyName' => 'value']);
Read-only ModelsOui YesNon
Model without primary keyOui Yes, but only in Read-only ModeNonOui
Specify fields to loadOui onlyFields()Non Fields load with SELECT *Oui User::find()->select([])->one()NonOui
Save only sends dirty fieldsOuiOuiOui- (there is Dirty support, so I assuming it is supported)OuiOui
Guarded / Fillable propertiesOui Conditions and OnlyFields do same thing but more reliably.Oui Prevents "create($_GET)" from messing up important fields.
Object Hierarchy Model
Admin extends User, adds criteria (is_admin=1)Oui Yes, recommended pattern. "User" class adds condition.NonNon Can be done as wrapper: User::findAdmin(..) or custom CDbCriteriaNon
Admin extends User, adds accessible fieldsOui Yes, recommended pattern.NonNonNon
Extend model, add Join (Disjoined SubTypes)Oui Yes. Unlimited number of joins.NonNonNon
Extend model change tableOui Yes. Used to tweak 3rd party models.Non
Relations/References (One model can relate to another model. NOT A TABLE JOIN)
Model can define relation to other ModelOui References are implemented as ObjectsOui RelationsOui RelationsOui
One-to-ManyOui $user->hasMany('Orders', new Order());OuiOui
One-to-many traversal strategyReturns destination model instance with dynamically applied criteria (parent_id=123). No queries are executed. Inserting record into this model will ensure association with parent model.Returns array of objects that may either be pre-loaded with record data or only contain IDs (lazy-loaded).Uses classical eager/lazy loading approach. with() can help pre-fetch the data for related entities.pre-fetch and store objects in an array.
Lazy/Eager-loadingNon Anti-patternOuiOuiOui
One-to-OneOui $order->hasOne('user_id', new User());OuiOui
Many-to-ManyOui $user->addCondition('vip', true)->ref('Orders');Oui relations() method of an entity can define.
Deep Many-to-Many traversal.NonOui $user->ref('Orders')->ref('Payments')->action('count'); No intermediate queries.- only with "to-one" references: $book->author->address->street; Executes multiple queries.- only with to-one references. Executes multiple queries.
Cross-Persistence traversalOui $user->hasMany('Log', new Log($mongodb));- No docs.Non
Cross-persistence joins, aggregation, reporting
Multi-persistence joinNonNonNonNon
UNION existing modelsNonOui Yes, in add-on Can join UNION result with more tables.NonNon
Domain-model AggregationOui Group by multiple fields. Apply aggregation functions. Preserve types.Non
Model to Model joinNon Planned.Non
Multi-persistence UNIONNonNonNonNon
Behaviours / Hooks
Before/After operationOuiOui
Override standard C,R,U,D operationsOuiOui
Persistence-specific hooks (to modify Query)Oui- (no docs)
User-defined hooksOuiOui
Global AuditingOui
Store old/new field valuesOui Yes in JSON and user-readable string.Oui
Revert action (undo) and replay (redo)OuiNonNon
Reactive actionsOui Each action will be automatically linked with sub-actions which may be invoked through Hooks.
Store log in any persistenceOuiNon
Override, Add fields to audit logRecord dirty fields before persisting. Type-cast into JSON string and store in a single field of AuditLog Model. This model can be persisted anywhere, table, file, etc.
Custom eventsOuiOui
Access to record-specific historyOui $item->ref('AuditLog');- Through a custom query.
Date of creation, modification- No but easy to add through hook.Oui \yii\behaviors\TimestampBehaviorOui TimestampTrait
User/IP creation, modification- Easy to add through a hook.Oui \yii\behaviors\BlameableBehavior
Store incremental revisions- Easy to add through a hookOui
Field meta-information providedType, caption, possible values, mapped field, join table spec, encryption, serialization, UI-specific settings, validation rules.
UI extensionsNonOui CRUD, Form, Table, Grid, Entity-manager. (see
API extensionsOui RestFULL API, automated CRUD operations + RPC
J'aime 0 2 0 0 0 0 0 0 0 0
  • 2016-10-18 22:08:00
    2017-12-21 16:47:00
  • Produits
  • Compare Doctrine vs Agile Data vs Eloquent vs Yii ORM vs Cake ORM vs Fuel ORM vs x vs x
  • Publique
  • Creative Commons License CC-BY-SA 3.0 / GNU FDL
    Gérer les sauvegardes


Laisser un commentaire

Créer des tableaux comparatifs ou listes sur tout !

C'est gratuit et rapide de créer des tableaux originaux

Créer un tableau