kachkaev/php-r-bundle
A Symfony bundle that brings R statistical computing into PHP applications, enabling you to run R scripts, pass data between PHP and R, and incorporate R-powered analysis into Symfony projects.
Architecture fit. kachkaev/php-r-bundle is a Symfony bundle, not a Laravel package, so the first architectural finding is a framework mismatch. Its only job is to register the framework-agnostic kachkaev/php-r library in the Symfony 2/3 DI container via a service definition, a Configuration tree, and (typically) a compiler pass or extension class. There is no Laravel service provider, facade, config publisher, or contract. In a Laravel codebase the bundle layer is dead weight — all usable value sits in the underlying php-r library, which itself is a thin wrapper that shells out to the Rscript binary via exec/proc_open and parses stdout. Architecturally this is "process-per-call RPC over stdout," not an embedded interpreter or a persistent connection. That is a legitimate pattern for batch/offline analytics, but it is a poor fit for anything request-path-critical in a PHP-FPM web tier.
Integration feasibility. Low. Consuming this in Laravel means: (1) ignoring the bundle entirely, (2) depending on the unmaintained php-r library or vendoring it, (3) hand-registering a singleton in a service provider, and (4) guaranteeing an R runtime plus the exact R package set is present in every environment. Once you have done (1)–(4), the bundle has contributed nothing you could not get from ~40 lines of Symfony\Component\Process or Laravel's Process facade. Feasibility is further reduced by the fact that the bundle's composer.json targets Symfony 2.x/3.x and PHP 5.5–7.x era constraints; it will not resolve cleanly against Symfony 4+/Laravel 9+ dependency graphs without --ignore-platform-reqs hacks or a fork.
Technical risk. High, and concentrated in abandonment rather than in the concept:
php-r is weak; failed R executions can surface as empty strings rather than exceptions.Key questions for the team.
Stack fit. Do not attempt a direct drop-in. There is no Laravel binding, and the Symfony binding targets EOL frameworks. Treat the repository as a design reference for how to wrap R invocation behind a service interface — nothing more.
Recommended path (in preference order).
plumber) or an Rserve instance, and call it from Laravel with the HTTP client or a socket client. This isolates the R runtime, allows independent scaling and deployment, gives you real timeouts/retries/circuit breaking, and keeps PHP containers free of R.Process invocation. If the workload is genuinely batch, implement a small internal package: an interface (RScriptRunner), a Process-based implementation with explicit timeout, exit-code checking, stderr capture, absolute script paths, and escapeshellarg-equivalent argument handling. Bind it as a singleton in a service provider and expose it via a facade. This reproduces the bundle's value with ~one day of work and a dependency you own.Compatibility notes. Verify the underlying php-r constraint against your PHP version before any spike; expect it to fail on PHP 8. Confirm proc_open/exec are not in disable_functions in your PHP image, and confirm Rscript resolves on PATH non-interactively (cron/queue workers often differ from CLI).
Sequencing. (a) Requirements spike: classify batch vs. interactive, quantify invocation volume and latency budget. (b) Runtime spike: build a throwaway Docker image with R + the exact package set, prove Rscript runs a representative script from a Laravel job. (c) Decide build-vs-service-boundary. (d) Implement the abstraction behind an interface so the transport (Process vs. HTTP vs. Rserve) is swappable. (e) Only then wire into business logic. Do not let business code depend on the transport.
What to explicitly avoid. Adding kachkaev/php-r-bundle to composer.json. It will not resolve against a modern Laravel/Symfony graph, and even if forced, it buys you nothing the interface-plus-Process approach doesn't.
Maintenance. Effectively zero upstream. Archived since 2017, 2 stars, 0 dependents, no release cadence. If adopted, you inherit the full maintenance burden for the bundle, the underlying php-r library, and the R runtime — three separate upgrade surfaces with no vendor support. The bundle is a liability on a dependency dashboard and will trigger archived-dependency policy flags in any mature supply-chain review.
Support. No maintainer, no issue triage, no security disclosure channel. Internal expertise must cover both PHP and R; realistically this lands on whichever team owns the data platform. Escalation path is "read the source" — which is small enough to be tractable, but only because you will end up forking it.
Scaling. The dominant cost is process spawn: each R invocation pays interpreter startup plus package-load time (often 100–500 ms before any work happens). There is no connection pooling, no warm interpreter, no concurrency primitive beyond spawning more processes. Under load this translates to CPU-bound fan-out on your PHP workers, unpredictable memory (R holds data frames in RAM), and potential process-table pressure. Mitigations: move to a job queue with dedicated workers and concurrency caps, or move to Rserve/plumber where the interpreter stays warm. Horizontal scaling requires baking R and the package set into every relevant image, inflating container size and cold-start time.
Failure modes to instrument and alert on.
Rscript absent, wrong version, or not on PATH in the worker context.Ramp-up. Non-trivial and cross-disciplinary. PHP engineers need enough R literacy to write and debug scripts and understand R's error semantics; platform engineers need to own an R base image, a package lockfile mechanism (e.g., renv), and the runtime lifecycle. Expect days rather than hours for a first production-grade integration, and treat the bundle itself as approximately a half-day of reading — it is small, and most of the effort is the R runtime, not the PHP glue.
How can I help you explore Laravel packages today?