ORM for PHP: Comparison of Doctrine, Eloquent, and Propel with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

ORM for PHP: comparison of Doctrine, Eloquent and Propel



Object-Relational Mapping (ORM) is a technology that allows developers to work with databases using an object-oriented approach instead of writing raw SQL queries. For PHP, there are several mature ORM solutions, each with its own strengths. In this article, we will compare in detail the three most popular ORMs: Doctrine, Eloquent (from Laravel) and Propel, and also provide practical code examples.



1. Doctrine: powerful DataMapper



Doctrine is perhaps the most mature and feature-rich ORM for PHP. It implements the DataMapper pattern, which means a complete separation of business logic and database logic. Main characteristics:



  • Support for multiple DBMS (MySQL, PostgreSQL, SQLite, Oracle, MSSQL)
  • Flexible query system via DQL (Doctrine Query Language)
  • Built-in support for migrations, events, proxy objects (lazy loading)
  • High performance with proper caching configuration


Example: entity definition and query



// User entityuse Doctrine\\ORM\\Mapping as ORM;

#[ORM\\Entity]#[ORM\\Table(name: "users")]class User{ #[ORM\\Id] #[ORM\\GeneratedValue] #[ORM\\Column(type: "integer")] private int $id;

#[ORM\\Column(type: "string", length: 100)] private string $name;

#[ORM\\Column(type: "string", length: 255, unique: true)] private string $email;

// Getters and setters public function getId(): int { return $this->id; } public function getName(): string { return $this->name; } public function setName(string $name): void { $this->name = $name; } public function getEmail(): string { return $this->email; } public function setEmail(string $email): void { $this->email = $email; }}

// Query via EntityManager$userRepository = $entityManager->getRepository(User::class);$users = $userRepository->findBy(['name' => 'Ivan'], ['id' => 'DESC'], 10);foreach ($users as $user) { echo $user->getName() . ' - ' . $user->getEmail() . PHP_EOL;}


2. Eloquent: simplicity and elegance



Eloquent is the standard ORM of the Laravel framework, implementing the ActiveRecord pattern. Each model is both an entity and a repository. Main advantages:



  • Minimal code for standard operations
  • Beautiful fluent query builder interface
  • Built-in relationships (belongsTo, hasMany, morphMany, etc.)
  • Excellent documentation and a huge community


Example: model and queries



// User model (file app/Models/User.php)namespace App\\Models;

use Illuminate\\Database\\Eloquent\\Model;

class User extends Model{ protected $fillable = ['name', 'email']; // Defining a "one to many" relationship public function posts() { return $this->hasMany(Post::class); }}

// Usage in a controller$users = User::where('name', 'LIKE', '%Ivan%') ->orderBy('created_at', 'desc') ->limit(10) ->get();

foreach ($users as $user) { echo $user->name . ' - ' . $user->email . PHP_EOL; // Lazy loading of related records foreach ($user->posts as $post) { echo ' Post: ' . $post->title . PHP_EOL; }}


3. Propel: performance and code generation



Propel is an ORM that generates classes based on a database schema (XML or YAML). It uses the ActiveRecord pattern, but with an emphasis on performance and strict typing. Key features:



  • Generation of model classes (no need to write getters/setters manually)
  • Built-in

Recommendations