Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine1 Bundle Laravel Package

diablomedia/doctrine1-bundle

Symfony bundle for Doctrine1 ORM, adapted from DoctrineBundle, that lets you configure Doctrine1 via Symfony config and adds query details to the profiler and debug toolbar. Install via Composer; works with the recommended diablomedia/doctrine1 fork.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Check your PHP version first (1.2.0 change):

    • 1.2.0 requires PHP 8.2+ and adds support for PHP 8.5. PHP 8.0/8.1 are no longer supported.
    • On PHP < 8.2, pin the previous release:
      composer require diablomedia/doctrine1-bundle:^1.1.4 diablomedia/doctrine1
      
  2. Installation:

    composer require diablomedia/doctrine1-bundle diablomedia/doctrine1
    
    • The doctrine1 fork is recommended for better PHP compatibility (and is what 8.2–8.5 support is tested against).
  3. Enable Bundle (this is a Symfony bundle — it registers console commands, a DI service, and config):

    // config/bundles.php
    DiabloMedia\Bundle\Doctrine1Bundle\Doctrine1Bundle::class => ['all' => true],
    
  4. Configure Database — create config/packages/doctrine1.yaml:

    doctrine1:
      default_connection: default
      connections:
        default:
          url: '%env(resolve:DATABASE_URL)%'
          cache_class: 'Doctrine_Cache_Array'
          enable_query_cache: true
          enable_result_cache: true
    
  5. First Use Case — inject the service and run a raw query:

    use DiabloMedia\Bundle\Doctrine1Bundle\Doctrine1;
    
    public function __construct(private Doctrine1 $doctrine) {}
    
    public function index()
    {
        $rows = $this->doctrine->getConnection()
            ->fetchAll('SELECT * FROM users WHERE active = 1');
    
        return view('users.index', ['users' => $rows]);
    }
    
  6. First thing to try in 1.2.0 — generate models from schema:

    php bin/console list doctrine1   # confirm the exact command name/options on your install
    php bin/console doctrine1:generate-models
    

    The new command wraps Doctrine1's CLI generate-models-from-yaml, so a YAML schema in config/doctrine/ (or wherever your schema_path/models_path config points) produces Base_* + concrete * record classes. Run it once during onboarding to see exactly what the package is generating for your project — that's the fastest way to understand how the bundle expects you to work.

  7. Where to look first:

    • vendor/diablomedia/doctrine1-bundle/src/Command/ — the new generate-models command and its options (output dir, connection, schema path).
    • vendor/diablomedia/doctrine1-bundle/src/DependencyInjection/Configuration.php — the authoritative list of config keys; the docs lag behind.
    • Doctrine1 service class — the small API surface you actually call day-to-day (getConnection(), named connections).

Implementation Patterns

Usage Patterns

  1. Schema-first models (the mainstream path):

    • Define tables in YAML schema files, then generate:
      # config/doctrine/schema.yml
      User:
        tableName: users
        columns:
          id:    { type: integer(8), primary: true, autoincrement: true }
          email: { type: string(255), notnull: true, unique: true }
          active:{ type: boolean, default: 1 }
      
      php bin/console doctrine1:generate-models
      
    • Never hand-edit Base_User / Base_* classes — they are regenerated. Put custom behaviour in the concrete subclass (User extends Base_User).
  2. Connection management:

    • Use named connections for read/write splitting:
      $writer = $this->doctrine->getConnection('writer');
      $reader = $this->doctrine->getConnection('reader');
      
  3. Query building:

    • Doctrine1's Doctrine_Query is the idiomatic option:
      $q = Doctrine_Query::create()
          ->select('u.*')
          ->from('User u')
          ->where('u.active = ?', true);
      
      $users = $q->execute();
      
  4. Model/ActiveRecord access:

    • Prefer the generated models over raw SQL for anything involving relations:
      $user = Doctrine_Core::getTable('User')->findOneByEmail($email);
      $user->active = false;
      $user->save();
      
  5. Caching per connection:

    connections:
      default:
        cache_class: 'Doctrine_Cache_Redis'
        redis_host: '%env(REDIS_HOST)%'
        enable_query_cache: true
        enable_result_cache: true
    
  6. Schema changes:

    • Use the bundle's schema/migration tooling where available, or raw SQL for one-offs. Regenerate models after any schema change and commit the generated Base_* classes alongside the YAML.

Workflows

  1. Repository/service wrapper (keeps Doctrine1 out of controllers):

    class UserRepository
    {
        public function __construct(private Doctrine1 $doctrine) {}
    
        public function findActive(): array
        {
            return Doctrine_Query::create()
                ->from('User u')
                ->where('u.active = ?', true)
                ->execute()
                ->toArray();
        }
    }
    
  2. Transactions:

    $conn = $this->doctrine->getConnection();
    $conn->beginTransaction();
    try {
        $conn->execute('UPDATE accounts SET balance = balance - 100 WHERE id = ?', [1]);
        $conn->execute('UPDATE accounts SET balance = balance + 100 WHERE id = ?', [2]);
        $conn->commit();
    } catch (\Throwable $e) {
        $conn->rollBack();
        throw $e;
    }
    
  3. Lifecycle listeners:

    $this->doctrine->getConnection()->listen('postInsert', function ($event) {
        // audit / post-save side effects
    });
    
  4. Regenerate-models in CI:

    • Run doctrine1:generate-models in a CI job and git diff --exit-code afterwards. It catches schema changes that were never regenerated — the single most common source of "works locally" bugs with Doctrine1.

Integration Tips

  1. Regenerating into a container-aware app:

    • Generated classes live in a fixed models_path. Make sure that path is PSR-0/PSR-4 autoloadable (Doctrine1's generated class names are not namespaced by default) — add it to composer.json autoload.classmap and composer dump-autoload after the first generation.
  2. Testing:

    • Wrap each test in a transaction and roll back, so generated models and raw queries share one cheap reset:
      protected function setUp(): void
      {
          $this->conn = $this->doctrine->getConnection();
          $this->conn->beginTransaction();
      }
      
      protected function tearDown(): void
      {
          $this->conn->rollBack();
      }
      
  3. Performance:

    • Enable query + result cache on read-heavy connections; keep both disabled on writer connections to avoid stale writes.
  4. Legacy interop:

    • Doctrine_Connection::fetchAll() / fetchRow() accept raw SQL, so existing PDO-era code can migrate incrementally to models.

Gotchas and Tips

Pitfalls

  1. PHP version floor moved to 8.2:

    • 1.2.0 drops PHP < 8.2. If CI still runs 8.1, composer update will silently keep you on 1.1.4 (or fail on a strict platform check). Bump CI images and composer.json require.php at the same time, and only then update.
  2. The generate-models command overwrites files:

    • It regenerates Base_* classes wholesale. Any customisation placed in a Base_* file is lost. Also commit or stash first — an accidental run on a dirty tree makes the diff hard to review. The command name/options vary by install, so confirm with php bin/console list doctrine1 rather than copying a signature from a blog post.
  3. It's a Symfony bundle, not a Laravel package:

    • The service container, config loading (config/packages/*.yaml), and the new console command are all Symfony. In a Laravel app you get the Doctrine1 service and connection config; you do not get the bundle's profiler, toolbar, or console commands without a Symfony kernel. Don't plan Laravel work around php artisan.
  4. Profiler / debug toolbar is not a Laravel feature:

    • Anything referencing /_profiler, Profiler/doctrine1.html.twig, or config/packages/dev/doctrine1.yaml profiler flags applies to Symfony apps only. In Laravel, use DB::listen-style logging or enable Doctrine1's own SQL logging instead.
  5. No connection pooling:

    • Doctrine1 has no built-in pooling. For high-traffic services, front it with a pooler (PgBouncer/ProxySQL) rather than trying to configure one in the bundle.
  6. Identifier quoting and reserved words:

    • Doctrine1 quoting behaviour differs by platform; use the connection's quote helpers or the query builder rather than hand-writing quoted identifiers.
  7. No auto-discovery of models:

    • There is no metadata auto-detection. Models exist only because YAML was generated (or written by hand). If a table "isn't found", the answer is almost always: run the generate-models command, or check models_path.
  8. Transactions don't nest:

    • Doctrine1 uses savepoints poorly by default. Guard with $conn->getTransactionLevel() and implement your own nesting helper instead of assuming beginTransaction() is re-entrant.

Debugging

  1. SQL logging:

    doctrine1:
      connections:
        default:
          logging: true
    
    • Log to a file/stderr via the connection's logger; there's no framework-agnostic query panel.
  2. Verify config actually loaded:

    • Typos in connection keys fail quietly and fall back to defaults. Dump the resolved service config (bin/console debug:config doctrine1 in Symfony) before debugging anything else.
  3. Connection failures:

    • Check the url DSN format (mysql://user:pass@host/db), and check cache_class names — Doctrine1's Doctrine_Cache_* classes are not interchangeable with Doctrine\Common\Cache\*.
  4. Generated-model errors after upgrade:

    • After 1.2.0, re-run the generate-models command and re-run composer dump-autoload. Stale Base_* classes plus new PHP 8.5 deprecation behaviour is the usual cause of "worked before the upgrade".
  5. Deprecation noise on PHP 8.4/8.5:

    • Suppress temporarily (error_reporting(E_ALL & ~E_DEPRECATED)) to see real errors, but don't ship that to production — fix the callsites instead.

Tips

  1. Pin the version during the upgrade window:

    • "diablomedia/doctrine1-bundle": "^1.2" after verifying PHP 8.2+ everywhere; "^1.1.4" if any environment is still on older PHP.
  2. Treat generated models as build artefacts with intent:

    • Commit them (so deploys don't need schema access), but add a CI check that regeneration produces no diff.
  3. Environment-specific config:

    • Keep prod connections logging-free and cache-enabled; enable logging only in dev/staging. Copy connection blocks via YAML anchors rather than duplicating them per environment.
  4. Upgrade checklist for 1.2.0:

    • Bump PHP images → composer update diablomedia/doctrine1-bundle diablomedia/doctrine1 → regenerate models → composer dump-autoload → run the test suite → check for new deprecations on the highest PHP version you support.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource