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

Builder Laravel Package

iter8/builder

A fluent, Laravel-friendly builder for constructing complex queries and reusable data pipelines with a clean, chainable API. Compose filters, sorting, and pagination into readable, testable components while keeping controllers slim and logic organized.

View on GitHub
Deep Wiki
Context7

Getting Started

iter8/builder is a Silex service provider, so it only makes sense if you are already inside a Silex 2.x application. It wraps PhpSpreadsheet and Spout behind a single "builder" abstraction so you define columns and rows once and switch the underlying writer via config.

Minimum steps:

  1. Install with Composer. Because the package is from 2018, expect a resolution fight — Silex 2.x pins Symfony ^2.8|^3.0, PhpSpreadsheet 1.x wants PHP 7.1+, and modern PhpSpreadsheet/Spout releases will not satisfy its constraints. Pin the whole trio explicitly rather than letting composer update drift.
    composer require iter8/builder:^1.0 phpoffice/phpspreadsheet:^1.0 box/spout:^3.0
    
  2. Read the provider first. Open the *ServiceProvider class in src/. Everything you need to know — the container keys it registers (typically a builder / spreadsheet.builder service plus an options array) and the config keys it expects — is in register(). The README is thin; the provider is the documentation.
  3. Register it in app.php / bootstrap.php:
    $app->register(new Iter8\Builder\BuilderServiceProvider(), [
        'builder.engine' => 'spout',   // or 'phpspreadsheet'
    ]);
    
    Confirm the exact key names against the provider — this is the single most common source of "class not found" / "options undefined" errors on first run.
  4. First use case: a single export endpoint. Grab the service from the container, define your columns, push an array of rows, and return a download response. Do not start by building a generic export framework; prove the round-trip with five rows and two columns first.

Implementation Patterns

Fluent define-then-fill, per request. The natural shape of this library is: resolve the builder from the container, declare headers/columns, append rows (arrays or objects), then ask for a StreamedResponse/Response download. Keep that whole sequence inside one controller action for your first export.

Wrap each export in a small definition class. Once you have three exports, inline fluent chains become copy-paste soup. Define one class per report — OrderExport, InvoiceExport — each with columns() and a rows() generator. Controllers then become three lines: build, fill, stream. This also makes the definition unit-testable without touching the container.

Choose the engine per export, not just globally. PhpSpreadsheet buys you formatting, merged cells, formulas, multiple sheets, and real .xlsx output. Spout buys you streaming, constant memory, and speed on six-figure row counts — but no styling. A good default is Spout globally, with a per-request override on the builder for the handful of "pretty" reports. Check whether the package exposes a per-call setter before assuming you must mutate $app['builder.engine'].

Feed rows lazily. The builder's row-append API works best with a generator. If you're on Doctrine, use ->toIterable() (or a manual doctrine.dbal cursor) and yield rows into the builder rather than ->getResult() into an array. This matters far more than which engine you pick.

Return a streamed response, not a string. For anything over a few thousand rows, build the response with StreamedResponse and set Content-Type / Content-Disposition yourself. If the library hands you a writer object, save('php://output') inside the callback is the usual integration.

Test by reading the output back. Generate into a temp file (tempnam), then parse it with PhpSpreadsheet's reader (it reads CSV and XLSX) and assert on cell values. This catches header drift, off-by-one column mapping, and type coercion — the three bugs this kind of code actually produces. Do not mock the builder; you'll be testing your mocks.

Gotchas and Tips

  • Silex is EOL. Silex was abandoned in 2018, the same year as this package's last release. There are no security patches coming for the framework or, realistically, for this provider. Treat it as legacy maintenance: pin every version, commit the lock file, and plan the exit. The migration target is usually Slim 4 or a plain Symfony app — and in either case you drop the service provider and call PhpSpreadsheet/Spout directly. The abstraction layer is thin enough that the port is mostly mechanical.
  • Engine mismatch is silent until output. If you configure spout but call a formatting method that only PhpSpreadsheet supports, you may get an exception, or you may get an unstyled file with no warning. Decided the engine early and keep formatting calls out of shared code paths.
  • Memory. PhpSpreadsheet holds the whole workbook in memory; a 50k-row export can blow past a 128M memory_limit and surface as a confusing fatal in the middle of a response. Spout streams and stays flat. If you must use PhpSpreadsheet on large data, chunk across multiple sheets rather than raising the limit.
  • Missing PHP extensions. PhpSpreadsheet needs ext-zip, ext-xml, ext-gd (for some features), and ext-mbstring; Spout needs ext-zip and ext-xmlreader. A bare Docker image will fail at runtime with a generic exception. Add them to the image, not to the composer suggestions.
  • CSV and Excel disagree about UTF-8. Excel on Windows wants a BOM (\xEF\xBB\xBF) for UTF-8 CSVs; adding a BOM to an .xlsx corrupts it. Branch on the output format, and always send an explicit Content-Type with charset=UTF-8.
  • Content-Disposition filenames. Non-ASCII filenames need RFC 5987 encoding (filename*=UTF-8''...) plus a plain ASCII filename fallback, or browsers mangle them. This package won't do it for you.
  • Formula injection. Any cell whose value starts with =, +, -, or @ will be interpreted by Excel when a user opens the file. Prefix user-supplied strings with a single quote or a tab. This is a real vulnerability, not a cosmetic issue, and it is your responsibility — the builder passes values through.
  • Dates come out as serial numbers. If you pass a DateTime and the path is Spout (or an unformatted PhpSpreadsheet cell), you get 43831 instead of 2020-01-01. Pre-format dates to strings in the row mapper unless you specifically need Excel-native date cells.
  • Output buffering kills streaming. If any echo, notice, or debug output happens before the streamed response, the file downloads corrupted. ob_end_clean() before the callback helps; also make sure no middleware or profiler is appending to the body.
  • Extension points are limited but real. The engine abstraction is the extension point: if you need a writer the package doesn't support (e.g. ODS or a custom PDF renderer), implement whatever interface the two built-in adapters share and rebind the container key in a register() override in your own provider. Because the container key is just an entry, you can also decorate it — for example to inject a default filename or audit logging.
  • Debugging tip. When something fails deep inside the writer, dump $app['builder'] (or var_dump(get_class(...))) to confirm you got the adapter you expected and not a lazily-resolved stub. Nine out of ten "it does nothing" reports on this package trace back to a config key whose name doesn't match what the provider reads.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource