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

Php Method Runner Laravel Package

leovie/php-method-runner

A lightweight PHP utility that lets you run methods on objects by name, making it easy to invoke dynamic or configurable method calls without verbose reflection code. Ideal for small Laravel or standalone PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and inspect the source first. The package is tiny and low-traffic, so the most reliable documentation is the code itself:

    composer require leovie/php-method-runner:^3.0
    

    Then read README.md, src/, and tests/ before wiring anything into a Laravel app. The tests are effectively the spec.

  2. Locate the runner entry point. The package revolves around taking a method's source code as a string and executing it with supplied arguments. Look for the main runner class in src/ — everything else is likely value objects for arguments, results, or parsing exceptions.

  3. First use case: dynamic rule/formula evaluation. The natural fit is when you want to store small PHP method bodies somewhere (database, config, user-defined rules) and invoke them at runtime. A minimal flow looks like:

    // Conceptual — verify exact class/method names in src/
    $runner  = app(\LeoVie\PhpMethodRunner\MethodRunner::class);
    $result  = $runner->run($methodSource, ['order' => $order]);
    
  4. Bind it once. Register the runner as a singleton in your AppServiceProvider (or a package provider) so you're not instantiating it per call:

    $this->app->singleton(\LeoVie\PhpMethodRunner\MethodRunner::class);
    
  5. Build a thin wrapper immediately. Don't call the package directly from controllers or models. A MethodExecutor service in app/Services gives you one place to add validation, logging, and sandboxing later.

  6. Know what v3.0.1 changed before you debug. The runner now suppresses output produced by the executed method (echo, print, var_dump, etc.). Your only channel out of a method is its return value. Design your snippets around returning data, not printing it, from day one.

Implementation Patterns

Service wrapper + DTOs. Expose a single method like execute(string $source, array $args): mixed and wrap exceptions in your own domain exceptions. This decouples your app from the package's internals (important given the project's maturity).

Return values are the contract. Because v3.0.1 silences method output, every rule/formula must communicate by returning a value. If you need a method to return $x and surface diagnostics, return an array:

// Stored source
'$total = $args["order"]->total(); return ["total" => $total, "tier" => $total > 1000 ? "gold" : "silver"];'

Validate the shape of that array in your wrapper before handing it to the rest of the app.

Rules engine. Pair it with a rules table holding source, name, and version columns; cache the parsed/validated source in Redis and run on demand. This turns the package into a lightweight, self-hosted expression engine without a third-party rules library.

Validation via syntax check. Before executing, run php -l in a subprocess (or token_get_all) against a wrapped snippet:

$wrapped = "<?php class __Validate { {$source} }";
file_put_contents($tmp = tempnam(sys_get_temp_dir(), 'm'), $wrapped);
exec("php -l " . escapeshellarg($tmp), $out, $code);

Reject anything that fails — this prevents parse errors from bubbling into eval failures.

Artisan command for dry runs. A php artisan method:run {file} {--args=} command is invaluable for developers authoring rules locally before they hit production. Since output is suppressed, have your command print the returned value (and the caught exception, if any) rather than expecting var_dump from inside the snippet.

Queue isolation. Run untrusted methods in a queued job with a timeout. Pair with symfony/process to execute in a child PHP process when the code isn't fully trusted — this is the only robust "sandbox" in plain PHP.

Testing pattern. Use Pest/PHPUnit to snapshot the source snippets and assert results. Because the runner shares your process, RefreshDatabase etc. still apply — be careful that executed code doesn't mutate shared state. Assert on the returned value, not on captured stdout: expect($out)->toBe('') is now the baseline, and any assertion that previously relied on echo output will silently fail after upgrading.

Integration tip — form requests. A tiny ValidateMethodSource rule that calls the syntax checker runs at the HTTP boundary and keeps invalid code out of the DB.

Gotchas and Tips

  • Output is muted as of v3.0.1. echo, print, printf, var_dump, print_r and friends inside the executed method no longer reach your output buffer or response body. If you were using echo as a poor-man's debugger, or if a stored rule emitted markup you relied on, that behaviour is gone — and it will fail silently, not loudly. Rewrite those rules to return a value; for ad-hoc debugging, have the snippet write to a known log file instead.
  • The upside of that change. Stray output from a rule can no longer corrupt a JSON response, trigger headers already sent, or leak data into a Blade view. If you had defensive ob_start()/ob_get_clean() wrappers around calls to this package, you can probably remove them — but test first, since output buffering also affected other code in the same request.
  • It is eval-equivalent. Never accept method source from untrusted users and run it in-process. Prefer a hardened subprocess (disable_functions, open_basedir, memory/time limits) or a separate container. Treat this as the primary risk of the package.
  • Low-traffic, so pin and read the source. The project has moved from v3.0.0 to v3.0.1 (so it is being actively touched again), but it still has negligible dependent count and few eyes on it. Pin the exact version in composer.json, read src/, and be prepared to fork. Check PHP compatibility against your Laravel version — older-style packages often break on newer PHP notices.
  • Imports don't travel with the snippet. A bare method body has no use statements; any class it references must be fully qualified or already available via Composer. This is the #1 source of Class not found errors.
  • Static vs. instance context. Methods relying on $this, private properties, or constructor-injected dependencies won't work unless the runner is given a bound object — check whether it supports instance binding before designing around it.
  • Return-type and reference nuances. void returns come back as null; by-reference parameters may not be honored; type coercion follows normal PHP semantics, so declare(strict_types=1) in your caller does not apply to the eval'd code.
  • Line numbers in stack traces are shifted. Wrap execution in try/catch, log the full source alongside the exception, and map errors back to your own rule IDs.
  • OPcache. Long-running workers may serve cached compiled code after a rule is edited; clear the opcache (or restart queues) on rule change.
  • State leakage. Executed code shares memory with your process. Ensure the runner doesn't retain static state between calls; re-create the runner per request in Octane contexts if in doubt.
  • Extension point. If the package's API is too thin, wrap it — don't subclass internals. Your own MethodExecutor interface is the extension point you should offer the rest of the codebase.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment