Installation:
composer require propel/propel1
Propel1 requires manual schema configuration (unlike Propel2, which is more modern). Start by defining your database schema in an XML file (e.g., schema.xml) in config/propel/schema/.
First Use Case: Generate a base model and CRUD operations via CLI:
vendor/bin/propel-gen model build
vendor/bin/propel-gen sql build
vendor/bin/propel-gen convert --output=app/Models
This creates PHP classes for your tables (e.g., UserQuery, UserPeer).
Basic Query:
use Models\UserQuery;
$users = UserQuery::create()->find();
foreach ($users as $user) {
echo $user->getName();
}
Database Connection:
Configure config/propel/propel.ini with your Laravel .env credentials (e.g., dsn=mysql:host=127.0.0.1;dbname=laravel).
Schema-First Development:
vendor/bin/propel-gen model build
vendor/bin/propel-gen convert
Querying Data:
$criteria = new Criteria();
$criteria->add(UserPeer::NAME, 'John', Criteria::EQUAL);
$users = UserPeer::doSelect($criteria);
$users = UserQuery::create()
->filterByName('John')
->find();
Relationships:
hasMany, belongsTo) via generated methods:
$user = UserQuery::create()->findOneById(1);
$posts = $user->getPosts(); // Assuming a hasMany relationship
Transactions:
use Propel\Runtime\Connection\ConnectionManager;
$conn = ConnectionManager::getConnection('default');
$conn->beginTransaction();
try {
// Business logic
$conn->commit();
} catch (\Exception $e) {
$conn->rollBack();
}
Integration with Laravel:
Peer classes alongside Laravel’s service container:
$this->app->bind('propel.connection', function () {
return ConnectionManager::getConnection('default');
});
Migrations: Propel1 lacks built-in migrations. Use Laravel’s migrations to alter the database, then update the XML schema manually and regenerate models.
Validation:
Propel1 doesn’t include validation rules. Use Laravel’s built-in validation or extend Propel’s BaseObject to add custom logic.
Caching:
Enable Propel’s query caching in propel.ini:
propel.query.cache.enabled = true
propel.query.cache.lifetime = 3600
Events:
Extend Propel’s BaseObject to trigger Laravel events:
class User extends BaseUser {
public function save() {
event(new UserSaved($this));
return parent::save();
}
}
Outdated Ecosystem:
propel:install artisan command).XML Schema Rigidity:
propel:diff-schema sparingly—it’s not foolproof.Naming Conflicts:
Peer and Query classes that may clash with Laravel’s autoloading. Exclude them from PSR-4 autoloading in composer.json:
"autoload-exclude": ["app/Models/*Peer.php", "app/Models/*Query.php"]
Lazy Loading:
$users = UserQuery::create()
->withColumn('Posts') // or ->with('Posts')
->find();
Connection Management:
$conn = ConnectionManager::getConnection('default');
// Use $conn directly instead of DB facade
SQL Logging:
Enable Propel’s debug mode in propel.ini:
propel.logger.level = debug
Logs appear in storage/logs/propel.log.
Common Errors:
composer dump-autoload) and regenerate models.app/Models/ and regenerate if the schema XML is updated.Custom Behavior:
Extend Propel’s BaseObject to add Laravel-specific logic:
class User extends BaseUser {
public function getFullName() {
return "{$this->getFirstName()} {$this->getLastName()}";
}
}
Plugins:
Propel1 supports plugins (e.g., for behaviors). Example: Add a SoftDelete trait to BaseObject.
Custom Query Methods:
Add static methods to Query classes for reusable queries:
class UserQuery extends BaseUserQuery {
public static function findActive() {
return self::create()->filterByIsActive(true);
}
}
Batch Operations:
Use doBulkInsert() or doBulkUpdate() for bulk operations instead of loops.
Indexing: Define indexes in your XML schema to optimize queries:
<table name="users">
<column name="email" type="VARCHAR" size="255" primaryKey="true" />
<index name="idx_email">
<column name="email" />
</index>
</table>
Avoid find() in Loops:
Cache results or use iterate() for large datasets:
UserQuery::create()->find()->each(function ($user) {
// Process user
});
How can I help you explore Laravel packages today?