Installation Add the package via Composer:
composer require deviscoding/propel1-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Deviscoding\PropelBundle\DeviscodingPropelBundle::class => ['all' => true],
];
Configuration
Update config/packages/deviscoding_propel.yaml (or create it) with your database connection:
deviscoding_propel:
dbal:
connections:
default:
wrapper_class: Propel\Runtime\Connection\ConnectionWrapper
params:
dsn: 'mysql:host=localhost;dbname=your_db'
user: 'your_user'
password: 'your_password'
First Use Case Generate a model from an existing database table:
php bin/console propel:model:build --no-confirmation
Then generate a CRUD controller:
php bin/console propel:generate:crud User
Schema Updates Modify your database schema, then regenerate models:
php bin/console propel:model:build --no-confirmation
Use --write-sql to preview SQL changes before applying them:
php bin/console propel:model:build --write-sql
Querying Data Use Propel’s QueryBuilder for type-safe queries:
use App\Models\UserQuery;
$users = UserQuery::create()
->filterByActive(true)
->find();
Relationships
Define relationships in YAML (e.g., schema.xml) and leverage Propel’s lazy-loading:
$user = UserQuery::create()->findPk(1);
$posts = $user->getPosts(); // Lazy-loaded collection
Forms
Use Propel’s ModelForm for seamless form integration:
use Propel\Runtime\Form\ModelForm;
$form = ModelForm::createForm(User::class, $user);
Validation
Define validation rules in schema.xml or use Propel’s built-in validators:
<column name="email" type="VARCHAR" size="255" required="true">
<validator type="email" message="Invalid email format" />
</column>
Events & Listeners
Subscribe to Propel events (e.g., postSave) in Symfony’s EventDispatcher:
$dispatcher->addListener('propel.post_save', function ($event) {
// Handle post-save logic
});
Database-First Development
propel:model:diff to compare schema changes:
php bin/console propel:model:diff
Test-Driven Propel
$connection = Propel::getConnection();
$connection->beginTransaction();
// Test logic
$connection->rollBack();
Migration Strategy
propel:model:build with --write-sql to generate migration scripts manually.PHP 7.x/Symfony 3.x Compatibility
createCallable() for anonymous functions).Propel::getConnection() (prefer dependency injection).$query->filterById(Propel::createCallable(function ($id) {
return $id > 10;
}));
Caching Issues
php bin/console cache:clear
propel.runtime.conf.cache_enabled = false in app/config/properties.ini).Relationship Loading
N+1 queries by using withColumn() or eager-loading:
$users = UserQuery::create()->withColumn('Posts')->find();
Transaction Handling
DoctrineBridge. Use Propel’s native transactions:
$connection = Propel::getConnection();
$connection->begin();
try {
// Operations
$connection->commit();
} catch (\Exception $e) {
$connection->rollBack();
}
Enable Propel Logging
Add to config/packages/monolog.yaml:
handlers:
propel:
type: stream
path: "%kernel.logs_dir%/propel.log"
level: debug
channels: ["propel"]
Then configure Propel to use the channel in app/config/properties.ini:
propel.logger = PropelLogger
propel.logger.level = debug
SQL Query Inspection
Enable SQL logging in app/config/properties.ini:
propel.logger.sql = true
Schema Validation Validate your schema before generating models:
php bin/console propel:model:validate
Custom Query Classes
Extend Propel\Runtime\ActiveQueryModel to add reusable query methods:
class UserQuery extends \BaseUserQuery {
public function activeOnly() {
return $this->filterByActive(true);
}
}
Behavior Classes
Use Propel’s behavior system (e.g., Timestampable, Sluggable) via schema.xml:
<behavior name="timestampable">
<parameter name="column_create" value="created_at" />
<parameter name="column_update" value="updated_at" />
</behavior>
Event Listeners
Create custom listeners for Propel events (e.g., postInsert, preUpdate):
class UserListener {
public function postInsert($event) {
$user = $event->getObject();
// Custom logic
}
}
Register in app/config/properties.ini:
propel.behaviors.User.post_insert = [UserListener, postInsert]
Connection Management
Ensure your Symfony database_url in .env matches the Propel connection config. Example:
DATABASE_URL="mysql://user:pass@localhost/db_name"
Propel will use this for its default connection unless overridden.
Case Sensitivity Propel 1.x is case-sensitive for column/table names. Stick to lowercase or configure case-insensitive queries:
UserQuery::create()->setFormatter(ModelCriteria::FORMAT_PHPCAS);
Legacy Propel 1.x Features
Some features (e.g., Propel::getSingle()) are deprecated. Use alternatives:
// Instead of:
$user = Propel::getSingle(UserQuery::create()->findPk(1));
// Use:
$user = UserQuery::create()->findPk(1);
How can I help you explore Laravel packages today?