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

Oraclebundle Laravel Package

fi/oraclebundle

FI OracleBundle brings Oracle Database connectivity to PHP applications, simplifying bundle configuration, connection setup, and Doctrine DBAL usage so teams can query and manage Oracle data within familiar framework workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

fi/oraclebundle is a Symfony bundle (not a Laravel package) published by the Comune di Firenze for internal "Fifree2" projects. Practically, it is a thin integration layer around Doctrine DBAL / OCI8 that wires an Oracle connection and related services into a Symfony container. Treat it as reference material rather than a dependency you pull into a Laravel app unchanged — with 0 stars and 0 dependents it has no community surface, no issue history to learn from, and no Flex recipe.

Where to look first (in this order):

  1. composer.json — the real contract. Check require for php, symfony/* version ranges, doctrine/dbal, and whether ext-oci8 is declared. This tells you if it will even resolve against a modern Laravel/Symfony stack.
  2. src/*Bundle.php (the Bundle subclass) — shows what is registered and whether there are compiler passes.
  3. src/DependencyInjection/Configuration.php — the config tree. This is the documentation when the README is sparse or in Italian.
  4. src/DependencyInjection/*Extension.php — reveals the service IDs and parameters you can override.
  5. README.md / any docs/ — expect Italian, expect it to describe an internal environment (hostnames, schema names) you do not have.

Minimal smoke test (Symfony context, where it belongs):

composer require fi/oraclebundle
// config/bundles.php
Fi\OracleBundle\FiOracleBundle::class => ['all' => true],
# config/packages/fi_oracle.yaml — keys come from Configuration.php, verify them
fi_oracle:
    connections:
        default:
            host: '%env(ORACLE_HOST)%'
            port: 1521
            service: '%env(ORACLE_SERVICE)%'
            user: '%env(ORACLE_USER)%'
            password: '%env(ORACLE_PASSWORD)%'
            charset: AL32UTF8

Then prove the wiring before writing any feature code:

$conn = $container->get('doctrine.dbal.oracle_connection');
$row  = $conn->fetchAssociative('SELECT 1 AS OK FROM DUAL');

First use case: read-only access to an existing Oracle schema — pulling a table into your app to sync or report on. Do not start by trying to run migrations against Oracle through this bundle; that is where the sharp edges are.

Laravel reality check: there is no Illuminate\Support\ServiceProvider, no extra.laravel manifest, no facade. If you are on Laravel, the realistic paths are (a) don't use it and use yajra/laravel-oci8 + config/database.php directly, or (b) vendor the useful classes into app/Support/Oracle/ and wrap them in your own service provider. Option (b) is only worth it if the bundle contains non-trivial logic (type casting, CLOB handling, NLS setup) you'd rather not rewrite.

Implementation Patterns

Isolate Oracle behind a repository, always. Oracle-specific SQL (ROWNUM, DUAL, NVL, CONNECT BY, sequences) will leak into your codebase if you let it. Keep it in one namespace so a future migration or test double is a single-file change.

final class OracleCustomerRepository
{
    public function __construct(private Connection $conn) {}

    public function findActive(int $limit): array
    {
        // 12c+: OFFSET/FETCH. 11g: wrap with ROWNUM — see gotchas.
        $sql = 'SELECT id, name FROM customers
                WHERE status = :status
                ORDER BY id
                FETCH FIRST :lim ROWS ONLY';

        return $this->conn->fetchAllAssociative($sql, ['status' => 'A', 'lim' => $limit]);
    }
}

Use DBAL, not the ORM, for a read-only Oracle schema. Mapping an Oracle schema you don't own into Doctrine entities is a losing battle: sequence-based PKs, NUMBER(1) booleans, and DATE columns with time components all fight the ORM's assumptions. fetchAllAssociative() + explicit hydration into your own DTOs is less code and far less debugging.

Configure two connections rather than replacing the default. Keep MySQL/Postgres as default and add Oracle as a named connection. This lets you run Eloquent and raw Oracle reads side by side, and keeps migrations pointed at the database you actually control.

doctrine:
    dbal:
        connections:
            default: { url: '%env(DATABASE_URL)%' }
            oracle:  { url: '%env(ORACLE_URL)%' }

Porting to Laravel — wrap, don't inherit the bundle. If you extract classes, register them explicitly:

// app/Providers/OracleServiceProvider.php
public function register(): void
{
    $this->app->singleton(OracleConnection::class, fn ($app) => new OracleConnection(
        config('database.connections.oracle')
    ));

    $this->app->bind(OracleCustomerRepository::class, fn ($app) =>
        new OracleCustomerRepository($app->make(OracleConnection::class))
    );
}

Test with a fake at the repository boundary, not with a live Oracle. Nobody in CI wants an Instant Client. Put an interface in front of the repository, bind a fixture-backed implementation in tests/, and reserve the real connection for a single manually-run integration test.

Sync jobs are the sweet spot. Scheduled Artisan command / Symfony command that reads Oracle and writes to your own store. Wrap in a transaction on your side, not Oracle's — you usually lack write grants, and holding a transaction open against a municipal production DB is a good way to get a phone call.

Gotchas and Tips

Framework mismatch is the headline gotcha. This is a Symfony bundle. Laravel's package auto-discovery will not load it, config/bundles.php is meaningless to Laravel, and any services.yaml it ships is inert. If the description "oracle per progetti Fifree2" made you hope for a Laravel Oracle driver, that is not what this is.

ext-oci8 plus Oracle Instant Client is a hard prerequisite. No Instant Client, no extension, no connection — and the error surfaces at oci_connect, not at composer install. In Docker, that means a build step that downloads the client libraries. Budget a day the first time.

Empty string is NULL in Oracle. This one silently breaks validation and where('col', '') logic ported from MySQL. WHERE name = '' never matches anything. Normalize on the way in and out.

Unquoted identifiers are uppercased. SELECT id FROM customers returns a column keyed ID, not id. This breaks naive array access and any hydration that assumes lowercase keys. Either quote consistently in SQL ("id") or normalize keys in your hydration layer — pick one and be consistent, because mixing them produces "why is this field missing" bugs.

No auto-increment. Oracle pre-12c uses sequences + triggers; 12c+ uses GENERATED AS IDENTITY. Eloquent's $incrementing/$keyType will not help you against a sequence. For inserts, either let the trigger assign the PK and re-query via RETURNING ... INTO, or fetch seq.NEXTVAL explicitly in the same statement.

Booleans. Before Oracle 23c there is no boolean type; expect NUMBER(1) with 0/1 or CHAR(1) with Y/N. Cast explicitly in your DTO hydration; don't rely on the driver.

Charset and NLS. Set AL32UTF8 deliberately. Session-level NLS settings (date formats, decimal separators) are per-session and per-environment; if dates come back wrong, check NLS_DATE_FORMAT before you suspect your code.

CLOB/BLOB memory. Lazy-loading semantics differ from what you're used to; large CLOBs can be truncated or blow memory depending on driver flags. If you see silent truncation, that's the first place to look.

Pagination differs by version. 12c+ supports OFFSET ... FETCH; 11g requires the nested ROWNUM wrapper. Ask which Oracle version the target schema runs — the answer changes your SQL.

Debugging. Enable DBAL SQL logging (doctrine.dbal.logging: true in dev) and read the ORA- code, not the wrapper exception message. ORA-00942 is a grants problem, not a typo — you probably can't see the table with that user. ORA-12154 is a TNS/service-name resolution issue, usually a bad service vs SID config key.

Maintenance posture is the real risk. Zero stars, zero dependents, no public issue traffic, municipal-internal origin. Pin to an explicit commit hash in composer.json, commit your composer.lock, and assume no upstream fixes. Fork it into your own VCS if you plan to depend on it for anything long-lived, so a deleted repo doesn't break your build.

Extension points, if you stay on Symfony. Override services via services.yaml using the IDs from the extension class, and prefer decoration (decorates:) over editing vendor code. If there is a compiler pass, check what it expects before you add your own — passes run in registration order and a misordered one produces confusing "service not found" errors.

Read the license before shipping. Municipal code is often released under terms that are fine internally but need a look before redistribution. Check for a LICENSE file and, if absent, treat it as all-rights-reserved and ask.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums