Skip to content

Using a PHP ORM with Swoole and OpenSwoole

Can a long-running, coroutine-based PHP service use an ORM? Yes, provided that database connections are managed correctly and one checked-out connection is not used concurrently by multiple coroutines.

Small Swoole Entity Manager supplies entity mapping, managers, relational query builders, and connection pooling for applications using Swoole or OpenSwoole.

When is an ORM useful?

An ORM can reduce repetitive field mapping and result hydration when a service reads and modifies structured relational objects. With Small Swoole Entity Manager, applications describe entities with PHP attributes and use managers to load or persist them.

It does not remove the need to design indexes, choose transaction boundaries, inspect queries or manage worker lifecycle. Performance depends on the query, data model and database; there is no universal latency guarantee.

Which runtime and database should I choose?

Environment Relevant capability Important constraint
Swoole 6 with MySQL PDO connector and connection pool Enable Swoole coroutine runtime hooks before database I/O
Swoole/OpenSwoole with PostgreSQL Pooled PostgreSQL connections Check transaction semantics for the operation and driver
Swoole tables Small Swoole DB in-memory driver Not all SQL features, including statistics queries, are supported
Symfony service ORM Symfony bundle Install versions permitted by the bundle's Composer constraints

For current Core 3.1, use PHP 8.4 or newer. The runtime and database driver guide describes connection settings and the distinctions between backends.

How do I start?

Install the framework-independent Core package:

composer require small/swoole-entity-manager-core:^3.1

Then define an attributed entity, associate a manager with the database table, configure a connection factory, and use the manager to create and query objects. The complete getting-started guide includes concrete PHP examples.

How do I handle concurrent work and transactions?

A persistence thread batches work on one connection. Its flush() method is not an implicit ACID transaction. Check the documented behavior of commit() for the selected driver, especially PostgreSQL.

For multi-table business states that must remain invisible until the whole build succeeds, the optional Strates package allows a new UUIDv7 snapshot to be constructed separately and made visible by publishing a release pointer. Snapshot release is not a replacement for all local transaction guarantees.

See persistence threads and transactions and Strates operations.

What if I already use Symfony?

Use the Symfony bundle for dependency-injection integration, connection configuration and database layers. The released bundle 3.0 declares a Core 3.0.* dependency; do not assume it can be installed with Core 3.1 until its Composer requirements change.

For details about ORM entities, queries and persistence, follow the Core documentation independently of the framework.

Further questions

Read the FAQ for direct answers to common installation, database and versioning questions.