PHPackages                             elie29/oci-driver - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. elie29/oci-driver

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

elie29/oci-driver
=================

OCI Driver

v2.0.2(1mo ago)19.1k1MITPHPPHP ^8.2CI passing

Since Oct 7Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/elie29/oci-driver)[ Packagist](https://packagist.org/packages/elie29/oci-driver)[ RSS](/packages/elie29-oci-driver/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (4)Versions (25)Used By (0)

OCI Driver
==========

[](#oci-driver)

[![build](https://github.com/elie29/oci-driver/actions/workflows/php-build.yml/badge.svg)](https://github.com/elie29/oci-driver/actions/workflows/php-build.yml)[![Coverage Status](https://camo.githubusercontent.com/a38589a87d853723f341075e565de6f9f459f3bc59cdbde870a2dbf322b07125/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f656c696532392f6f63692d6472697665722f62616467652e737667)](https://coveralls.io/github/elie29/oci-driver)[![PHP Version](https://camo.githubusercontent.com/bbe4a45f4c7d8767028ef8ed488cfe282a2767a4fc6073a346388472301a971d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f656c696532392f6f63692d6472697665722e737667)](https://packagist.org/packages/elie29/oci-driver)

Text file encoding
------------------

[](#text-file-encoding)

- UTF-8

Code style formatter
--------------------

[](#code-style-formatter)

- PSR-4

Installation
------------

[](#installation)

Run the command below to install via Composer:

```
composer require elie29/oci-driver
```

Getting Started
---------------

[](#getting-started)

OCI Query Builder provides a lightweight builder to dynamically create SQL queries. It **does not** validate the query at all.

### Select builder

[](#select-builder)

```
// SELECT * FROM params ORDER BY name ASC
$sql = Select::start() // aka (new Select)
    ->column('*')
    ->from('params')
    ->orderBy('name')
    ->build();
```

### Select builder with union

[](#select-builder-with-union)

```
// SELECT p.id FROM params p UNION SELECT p.id FROM params_his p ORDER BY id ASC
$sql = Select::start() // aka (new Select)
    ->column('p.id')
    ->from('params', 'p')
    ->union()
    ->column('p.id')
    ->from('params_his', 'p')
    ->orderBy('id')
    ->build();
```

### Delete builder

[](#delete-builder)

```
// DELETE FROM params WHERE id = 2
$sql = Delete::start() // aka (new Delete)
    ->from('params')
    ->where('id = 2')
    ->build();
```

### Update builder

[](#update-builder)

```
// UPDATE users u SET u.name = 'O''neil' WHERE u.user_id = 1
$sql = Update::start() // aka (new Update)
    ->table('users', 'u')
    ->set('u.name', Update::quote("O'neil"))
    ->where('u.user_id = 1')
    ->build();
```

### Insert builder

[](#insert-builder)

```
// INSERT INTO params (user_id, name) VALUES (:id, :name)
$sql = Insert::start() // aka (new Insert)
    ->into('params')
    ->values([
        'user_id' => ':id',
        'name'    => ':name',
    ])
    ->build();
```

> More examples are found in tests/OCI/Query/Builder folder.

Using OCI Driver Class
----------------------

[](#using-oci-driver-class)

### Using the factory

[](#using-the-factory)

The `Factory::create()` method is the recommended way to create a Driver instance. It provides several benefits:

**Purpose:**

- Automatically configures the Oracle session with proper NLS settings
- Sets up the appropriate debugger based on the environment
- Ensures consistent date/time and numeric formats across all queries

**Environment Parameter (`$env`):**

The second parameter defines the execution environment and controls debugging behavior:

- `'prod'` or `'production'`: Production mode - uses DebuggerDumb (no output)
- `'dev'` or `'development'` or `'test'`: Development mode - uses DebuggerDump (outputs debug information using VarDumper)

**Session Configuration:**

Factory automatically alters the Oracle session to set:

- `NLS_DATE_FORMAT`: 'YYYY-MM-DD' (ISO format)
- `NLS_TIMESTAMP_FORMAT`: 'YYYY-MM-DD HH24:MI:SS' (ISO format)
- `NLS_NUMERIC_CHARACTERS`: '.,' (dot as decimal separator, comma as thousand separator)

This eliminates the need to use `TO_CHAR` or `TO_DATE` in your SQL queries:

```
// Create a driver with development debugging
$connection = new Connection(USERNAME, PASSWORD, SCHEMA);
$driver = Factory::create($connexion->connect(), 'dev');

$sql = 'SELECT * FROM A1 WHERE N_DATE BETWEEN :YESTERDAY AND :TOMORROW';

$bind = (new Parameter())
    ->add(':YESTERDAY', date('Y-m-d', time() - 86400)) // Direct ISO format
    ->add(':TOMORROW', date('Y-m-d', time() + 86400));

$rows = $driver->fetchAllAssoc($sql, $bind);
```

### Insert/Update Example

[](#insertupdate-example)

#### With Autocommit

[](#with-autocommit)

Autocommit is the default behavior of OCI Driver:

```
$connection = oci_pconnect('username', 'pass', 'schema', 'UTF8');
$driver = Factory::create($connection, 'dev');

$sql = 'INSERT INTO A1 (N_NUM) VALUES (5)';
$count = $driver->executeUpdate($sql);
echo $count; // displays 1
```

#### With Transaction

[](#with-transaction)

To start a transaction, you should use beginTransaction as follows:

```
$connection = oci_pconnect('username', 'pass', 'schema', 'UTF8');
$driver = Factory::create($connection, 'dev');

$driver->beginTransaction();

try {
   $count = $driver->executeUpdate($sql);
   $driver->commitTransaction();
   echo $count; // displays 1
} catch (DriverException $e) {
   echo $e->getMessage();
}
```

**N.B.**: When an error occurred using a transaction, rollback is called automatically.

#### Bind parameters

[](#bind-parameters)

```
$connection = oci_pconnect('username', 'pass', 'schema', 'UTF8');
$driver = Factory::create($connection, 'dev');

$sql = 'INSERT INTO A1 (N_CHAR, N_NUM, N_NUM_3) VALUES (:N1, :N2, :N3)';

$parameter = (new Parameter())
    ->add(':N1', 'c')
    ->add(':N2', 1)
    ->add(':N3', 0.24);

$count = $driver->executeUpdate($sql, $parameter);
echo $count; // displays 1
```

### Fetch one row

[](#fetch-one-row)

```
$connection = oci_pconnect('username', 'pass', 'schema', 'UTF8');
$driver = Factory::create($connection, 'dev');

$sql = 'SELECT * FROM A1 WHERE N_NUM = 2';

$row = $driver->fetchAssoc($sql);
```

**N.B.**: For binding parameters, follow the same insertion example above.

### Fetch many rows

[](#fetch-many-rows)

```
$connection = oci_pconnect('username', 'pass', 'schema', 'UTF8');
$driver = Factory::create($connection, 'dev');

$sql = 'SELECT * FROM A1';

$rows = $driver->fetchAllAssoc($sql);
```

**N.B.**: For binding parameters, follow the same insertion example above.

Running Oracle via Docker
-------------------------

[](#running-oracle-via-docker)

If Oracle is not installed locally, use Docker to spin up an Oracle Free 23 container before running integration tests:

```
docker run -d \
  --name oracle-free \
  -p 1521:1521 \
  -e ORACLE_PASSWORD=MyPassword \
  -e APP_USER=myuser \
  -e APP_USER_PASSWORD=MyPassword \
  gvenzl/oracle-free:23-slim
```

- `ORACLE_PASSWORD` — required; sets the password for the SYS and SYSTEM accounts.
- `APP_USER` / `APP_USER_PASSWORD` — optional; creates a dedicated application user in `XEPDB1`. If omitted, connect as `SYSTEM` with `ORACLE_PASSWORD` instead.

Wait for the container to be ready (this can take 1–2 minutes):

```
docker logs -f oracle-free
```

The database is ready when the logs show:

```
DATABASE IS READY TO USE!

```

Then configure `tests/integration/config-connection.php` with:

- `USERNAME` → `APP_USER` if set, otherwise `SYSTEM`
- `PASSWORD` → `APP_USER_PASSWORD` if set, otherwise `ORACLE_PASSWORD`
- `SCHEMA` → `localhost:1521/XEPDB1`

To stop and remove the container when done:

```
docker stop oracle-free && docker rm oracle-free
```

Continue with the steps below to set up and run the integration tests.

Prepare for the test
--------------------

[](#prepare-for-the-test)

Before launching integration tests, you should follow these steps:

### 1. Configure database connection

[](#1-configure-database-connection)

Rename `config-connection.php.dist` in `./tests/integration` to `config-connection.php`:

```
cd tests/integration
cp config-connection.php.dist config-connection.php
```

Modify `USERNAME`, `PASSWORD` and `SCHEMA` according to your Oracle Database Information.

> SCHEMA could be one of the following:

- IP:PORT/SID eg: `11.22.33.25:12005/HR`
- SID name if you are executing the tests on the same database server or if you have a configured SID in tnsnames.ora
    - Use the following TNS:

        ```
        (DESCRIPTION =
            (ADDRESS =
            (PROTOCOL = TCP)(HOST = DATABASE_IP)(PORT=DATABASE_PORT)
            )
            (CONNECT_DATA =
            (SID=DATABASE_SCHEMA)(SERVER=DEDICATED|POOLED)
            )
        )

        ```

### 2. Create A1 and A2 tables

[](#2-create-a1-and-a2-tables)

#### Option A: Using the automated setup script (Recommended)

[](#option-a-using-the-automated-setup-script-recommended)

Run the composer script to automatically create the required tables:

```
composer setup-tables
```

This will:

- Drop existing A1 and A2 tables if they exist
- Create fresh A1 and A2 tables with the correct structure
- Verify the connection and provide helpful error messages

#### Option B: Manual SQL creation

[](#option-b-manual-sql-creation)

Alternatively, you can manually create the tables:

```
CREATE TABLE A1
(
    "N_CHAR" CHAR(5 BYTE
) ,
  "N_NUM"    NUMBER,
  "N_NUM_3"  NUMBER(6,3),
  "N_VAR"    VARCHAR2(4000),
  "N_CLOB"   CLOB,
  "N_DATE"   DATE,
  "N_TS"     TIMESTAMP,
  "N_LONG"   LONG
);

CREATE TABLE A2
(
    "N_LONG_RAW" LONG RAW
);
```

### 3. Run tests

[](#3-run-tests)

Once the setup is complete, you can run the integration tests:

```
vendor/bin/phpunit --testsuite "Integration Tests"
```

Development Prerequisites
-------------------------

[](#development-prerequisites)

### Test Structure

[](#test-structure)

The project uses PHPUnit for testing with two test suites as configured in `phpunit.xml.dist`:

- **Unit Tests** (`tests/units/`): Fast, isolated tests that don't require database connections

    - Query Builder tests (Select, Insert, Update, Delete)
    - Helper utility tests (FloatUtils, ClauseInParamsHelper)
- **Integration Tests** (`tests/integration/`): Tests that require Oracle database connection

    - Driver tests (Connection, Query execution, Transaction management)
    - Factory and SessionInit tests

### Composer commands

[](#composer-commands)

- `setup-tables`: Creates A1 and A2 test tables in the Oracle database (required for integration tests)
- `test`: Runs PHPUnit tests without coverage
- `test-coverage`: Runs PHPUnit unit tests with code coverage
- `cover`: Runs tests with coverage and starts a local server at

You can run specific test suites:

```
vendor/bin/phpunit --testsuite "Unit Tests"
vendor/bin/phpunit --testsuite "Integration Tests"
```

###  Health Score

56

—

FairBetter than 97% of packages

Maintenance93

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity84

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~121 days

Recently: every ~489 days

Total

24

Last Release

35d ago

Major Versions

v1.0.20 → v2.0.02025-12-13

PHP version history (2 changes)v1.0.0PHP ^7.1

v2.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/712b1d0a9ef2f110cd5b58873f1769badaab198d7c128560e45bfb3ee61a8723?d=identicon)[elie29](/maintainers/elie29)

---

Top Contributors

[![elie29](https://avatars.githubusercontent.com/u/11255270?v=4)](https://github.com/elie29 "elie29 (148 commits)")

---

Tags

dbalocioci-driverphpquery-builder

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/elie29-oci-driver/health.svg)

```
[![Health](https://phpackages.com/badges/elie29-oci-driver/health.svg)](https://phpackages.com/packages/elie29-oci-driver)
```

###  Alternatives

[symbiote/silverstripe-advancedworkflow

Adds configurable workflow support to the CMS, with a GUI for creating custom workflow definitions.

46302.4k9](/packages/symbiote-silverstripe-advancedworkflow)[yurunsoft/phpmailer-swoole

PHPMailer 支持 Swoole 协程环境

31190.3k11](/packages/yurunsoft-phpmailer-swoole)[riverskies/laravel-vue-component

Helper package to aid usage of Vue Components within Laravel projects

201.2k](/packages/riverskies-laravel-vue-component)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
