- Is Rowcast a Laravel package or an Eloquent replacement?
- Neither. Rowcast is a framework-agnostic PHP 8.4 library built on PDO and reflection, with no service provider, facade, config file, or Artisan commands, so in a Laravel app it is a parallel persistence path that sits beside Eloquent and the DB facade rather than replacing them. It is best framed as a low-level persistence utility you consume in narrow places such as bulk imports, ETL jobs, reporting read models, and legacy-schema access. If you need relationships, observers, soft deletes, or global scopes, stay with Eloquent.
- How do I install and configure Rowcast in a Laravel application?
- Run composer require ascetic-soft/rowcast, then construct a Connection via Connection::create() with your DSN and wrap it in a DataMapper instance. Because the package ships nothing Laravel-specific, you write roughly a 30-line service provider yourself that binds Connection and DataMapper as singletons and reads DSN and transaction settings from a config file you add. The installation is trivial; the real effort is setting conventions for mapping ownership, converter registration, and when to call save() versus upsert().
- What PHP version and database drivers does Rowcast require?
- Rowcast requires PHP 8.4 or newer plus ext-pdo, which is a hard floor rather than a soft recommendation. That version constraint, not the package itself, is usually the gating item: if your CI images, production runtimes, or shared libraries are pinned to PHP 8.2 or 8.3, adoption is blocked or forces an unrelated upgrade program. Confirm your fleet is on 8.4 before evaluating anything else.
- How do auto mapping and explicit mapping work in Rowcast?
- With auto mapping you pass a class-string on reads and a table name on writes, and column and property names are converted through a NameConverterInterface (the default is SnakeCaseToCamelCase), with table names derived from the DTO class such as User mapping to users. Explicit mapping lets you pass a Mapping object to control the table name, column-to-property pairs, and ignored properties. Hydration and extraction are reflection-based with type conversion, so typed DTO properties such as int, bool, and string are populated from raw PDO values without hand-written casts.
- Can Rowcast handle bulk inserts and upserts better than Eloquent?
- Rowcast exposes a fluent query builder with dialect-aware UPSERT, emitting the right syntax per driver, which is typically what you want for large batch writes, imports, and idempotent sync jobs where model lifecycle overhead is pure cost. Be aware that save() is read-before-write: two statements with a race window and no conflict constraint required, so upsert() is the efficient and safer path when the schema has the matching unique key. Write down a team rule for when each is allowed, because developers will otherwise pick save() by default.
- Does Rowcast support relationships, events, soft deletes, or global scopes?
- No. Rowcast has no relationship loading, no model events or observers, no soft deletes, no global scopes, no multi-tenant filtering, and no model-level authorization. Rebuilding any of that on top of it would defeat the purpose of using a thin mapper. If your domain needs those features, keep that code on Eloquent and reserve Rowcast for plain DTO reads and writes.
- Which SQL dialects does Rowcast support, and are there portability traps?
- Only mysql, pgsql, and sqlite are mapped to dedicated dialect classes; anything else silently falls back to GenericDialect, so unsupported drivers fail quietly rather than loudly. ILIKE and NOT ILIKE are Postgres-only, which is a real trap if your test suite runs on Postgres while production runs MySQL. Check every query that uses case-insensitive matching or dialect-specific UPSERT syntax against the driver you actually deploy on.
- Is Rowcast safe with Laravel Octane and long-running queue workers?
- No Octane or persistent-worker guarantees are published, and the known mutable surface is Mapping, which is documented as configured in place. If you bind Connection and DataMapper as singletons, treat all mapping configuration as immutable after boot; if you need per-job mappings, construct a fresh DataMapper inside the job instead. Ask the maintainer directly about static state and long-lived PDO connections before running this under Octane in production.
- How do I test Laravel code that uses Rowcast?
- Because there are no facades or container magic, you can build a Connection with Connection::create('sqlite::memory:') and a DataMapper directly in a unit test, which makes fast in-memory integration tests straightforward. For feature tests, bind a test connection in the container so your service provider wiring is exercised too. Keep at least a small suite running against your production driver, since SQLite will not catch MySQL-specific UPSERT or case-sensitivity differences.
- What are the production risks of adopting Rowcast today?
- It has effectively zero adoption, so you would be the only known production user: no field-tested failure modes, no Stack Overflow corpus, and no third-party tutorials, with a bus factor of one. Performance is unquantified, since reflection-based extract and hydrate run on hot paths with no published benchmarks, and findAll materializes results while iterateAll streaming behavior needs verification against a real cursor. Verify tags, commit cadence, BC policy, and the security disclosure process on Packagist before depending on it, and consider wrapping the API behind your own interface so a future breaking change stays contained.