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

Phpforge Laravel Package

infocyph/phpforge

PHPForge from infocyph is a lightweight PHP scaffolding and code generation toolkit for forging boilerplate classes, files, and project structures from simple commands or templates, helping streamline everyday development workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

PHPForge is a dev-only tooling bundle — treat it as a require-dev dependency, never something that ships in a production image. The pitch is that instead of hand-assembling PHPStan + Rector + a style fixer + a benchmark harness + release scripts in every repo, you pull one package that carries opinionated, pre-wired configs and binaries.

Minimal steps:

composer require --dev infocyph/phpforge

# 1. See what entry points it actually exposes
ls vendor/bin/
composer show infocyph/phpforge      # check deps + version constraints it drags in

# 2. Read the shipped config stubs before running anything
ls vendor/infocyph/phpforge

Then, in order, look at:

  1. vendor/bin/ — the binary names. This package's whole value proposition is invoked through these; if it only ships config files and no binaries, the integration story is "copy the configs," which changes everything below.
  2. The shipped config files (phpstan, rector, php-cs-fixer/CS, phpunit/bench). Read them for hardcoded path assumptions — src/, tests/, build/. A Laravel app uses app/, database/, routes/, config/.
  3. composer.json → scripts — whether the package expects to be driven via composer forge:*-style aliases or direct vendor/bin calls.

First use case: don't start with Rector on a live Laravel app. Start with the read-only, non-destructive leg of the toolchain — static analysis and a style check in dry-run mode — on app/ only, with a baseline. That gives you a number ("we have 340 existing PHPStan errors") before you change a single line, and it proves the configs load correctly under your Laravel version and PHP version. Refactoring and release tooling come after the gate is green and enforced in CI.

Implementation Patterns

Pattern 1: Composer scripts as the single interface

Don't let developers memorize vendor/bin paths plus long flag lists. Wrap each forge capability in a named script so local and CI runs are identical:

"scripts": {
    "qa": ["@qa:analyse", "@qa:style"],
    "qa:analyse": "phpstan analyse --memory-limit=1G",
    "qa:style": "php-cs-fixer fix --dry-run --diff",
    "qa:refactor": "rector process --dry-run",
    "qa:bench": "phpbench run --report=default"
},
"scripts-aliases": { "qa": [] }

This is the highest-leverage thing you do with a shared tooling package: the package owns the defaults, your composer.json owns the entry points, and CI just calls composer qa. If you later drop PHPForge for a hand-rolled setup, only the configs move — nobody's muscle memory breaks.

Pattern 2: Baseline-first adoption on a legacy Laravel codebase

Shared configs assume a clean project. Real Laravel apps are not clean. Generate baselines on the first run and commit them:

vendor/bin/phpstan analyse app --generate-baseline

Then ratchet: add new code without new baseline entries, and shrink the baseline file deliberately in dedicated PRs. Never let "regenerate the baseline" become a reflex — that's how a quality gate quietly becomes a no-op. For Rector, the equivalent discipline is --dry-run in CI and apply changes in small, reviewable batches per rule set (start with deadCode, codeQuality, only then typeDeclarations).

Pattern 3: Layered config instead of forking it

If the package ships a base config, use its include mechanism rather than copying it into your repo — otherwise you inherit the maintenance burden with none of the upstream fixes:

# phpstan.neon
includes:
    - vendor/infocyph/phpforge/config/phpstan-base.neon   # confirm real path
    - phpstan-baseline.neon

parameters:
    level: 6
    paths: [app, database, routes, config]
    excludePaths:
        - app/Console/Kernel.php        # legacy Laravel scaffolding
        - '*/Migrations/*'

The Laravel-specific wrinkle: Larastan vs. plain PHPStan. If the base config targets vanilla PHPStan, you'll get hundreds of false positives on Eloquent magic (Model::where, facades, container bindings). Either the package needs to compose with larastan/larastan, or you keep PHPForge's static-analysis leg off Laravel app code and use it only on framework-agnostic packages/micro-libraries inside the monorepo. Verify this in the first hour — it's the make-or-break integration point for a Laravel developer.

Pattern 4: CI as the enforcement layer

- run: composer install --no-interaction --prefer-dist
- run: composer qa          # style + static analysis, dry-run
- run: composer qa:refactor # rector --dry-run, must produce zero diffs

Cache vendor/ and the analysis result cache keyed on the composer lock hash. Keep the refactor job advisory (non-blocking, artifact diff) for the first few sprints — a blocking Rector job on day one will make everyone hate the tool.

Pattern 5: Benchmarking hot paths, not the whole app

The benchmark leg is where most teams get no value, because they benchmark nothing in particular. Use it narrowly: a query-builder hot path, a serialization routine, a pricing/eligibility calculation. In Laravel terms, benchmark the service layer with container booted once, not full HTTP round-trips (that's what artisan serve + a load tester is for). Commit results and compare across PRs — relative regression, not absolute numbers, is the signal.

Pattern 6: Release tooling for internal packages

If you have a packages/* monorepo of shared Laravel libraries, PHPForge's release leg (version bump, changelog, tag) is genuinely useful — it's the repetitive part nobody automates until it bites. Keep it out of the application repo entirely; apps deploy from a commit, packages get tagged.

Gotchas and Tips

Dependency collision is the number-one risk. A tooling bundle pins PHPStan/PHPUnit/CS-fixer/Rector versions transitively. Laravel projects usually also want larastan and laravel/pint. Expect composer update conflicts where Larastan requires phpstan/phpstan ^1.11 and PHPForge pulls ^2.0 (or vice versa). Diagnose with composer why phpstan/phpstan and composer why-not phpstan/phpstan 2.x before you fight the config — the config is usually innocent. If it collides, install PHPForge in a separate Composer context (its own directory, run against your codebase by path) rather than forcing a resolution.

The package is a single-maintainer, single-star project. That's not disqualifying for dev tooling — it can't take down production — but it is a reason to: pin an exact version ("infocyph/phpforge": "1.2.3"), never rely on it transitively, and make sure composer qa degrades gracefully if the package is removed. Budget an hour to read the shipped configs so you can fork them into your repo if upstream goes quiet.

Path assumptions break silently. Shared configs reference src/ and tests/. In Laravel, analysis silently covers nothing if paths doesn't exist — PHPStan will happily report "no errors" on an empty path list in some configurations. Always confirm coverage: introduce a deliberate error in app/ and verify it's caught. Do this once per config change.

Pint and php-cs-fixer will fight. If the bundle ships a CS fixer and you also run Pint, you get conflicting rules and a ping-pong diff. Pick one as authoritative — usually Pint in a Laravel app — and disable or exclude the package's style leg.

Exclude what isn't yours. vendor/, storage/, bootstrap/cache/, public/build/, generated IDE-helper files, and *.blade.php from static analysis. Analysis time on a mid-size Laravel app jumps from seconds to minutes the moment storage/framework/views gets scanned.

Baselines rot. A committed baseline is a debt ledger, not a fix. Review baseline diffs in PRs the same way you review migrations — if a PR grows the baseline, ask why.

--memory-limit is not optional. PHPStan on a Laravel app hits the default memory ceiling routinely. Bake --memory-limit=1G (or -1 in CI) into the composer script so nobody debugs a spurious fatal error.

Never install it in production. composer install --no-dev --optimize-autoloader in the deploy image; ideally also a composer check-platform-reqs step. Tooling packages that slip into a release image bloat it and occasionally expose console entry points you don't want.

Extension points to check first: whether the configs are include-able (good) or meant to be copied (fragile), whether binaries accept a --config override (essential for monorepos with per-package rules), and whether the benchmark/release legs are decoupled from the analysis legs — so you can adopt one without the other. If everything is a single monolithic "run the forge" binary with no per-leg opt-out, that's a real integration cost for a Laravel team and worth knowing before you build CI around it.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console