agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/audit/php/SKILL.md

php

Skill4 starsChanged 4 months agoMITView on GitHub

Scan a brownfield PHP codebase for version drift, missing strict_types, deprecated APIs, and ini/autoload smells, and emit evidence-backed AUD-PHP findings ranked by ROI with remediation cross-linked to migration skills. Use when the user needs to locate calls to deprecated or removed PHP APIs (for example `each()`, `create_function()`, `mysql_*`, curly-brace string offsets) across the codebase before an upgrade; the user wants a ranked report of what to modernize in a legacy PHP project — which files lack strict types, which call removed functions, which pin an old PHP version — with a ROI-ordered backlog; the user asks to audit or scan an existing PHP codebase for version drift, missing `declare(strict_types=1)`, deprecated APIs, or ini/autoload configuration smells. Keywords: audit, php, findings, roi, report, strict-types, deprecated, version-drift, autoload, brownfield.

11 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use react.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • VercelSkill

    react

    React renderer for json-render that turns JSON specs into React components. Use when working with @json-render/react, building React UIs from JSON, creating component catalogs, or rendering AI-generated specs.

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

10 rules. 0 are common, 8 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 10 edited versions we read keep these.

  • 8

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not run a version-drift audit on greenfield code that is already written for the current PHP version with strict types on.

    line 82
  2. Distinctive:

    Do not use this audit skill to actually rewrite code for a version bump.

    line 84
  3. Distinctive:

    Verify: The report has a header, a ROI-sorted table, and a quick-wins callout.

    line 142
  4. Distinctive:

    Verify: The top findings each name a remediation skill and any stated precondition.

    line 145
  5. Very specific:

    Read composer.json and CI to fix the target PHP version, then set the scan scope to application source only, excluding vendor and generated …

    line 159
  6. Distinctive:

    Verify: The target version and the scanned paths are recorded in the report header.

    line 161
  7. Distinctive:

    Verify: Each candidate hit is confirmed in the file and false positives are dropped.

    line 164
  8. Distinctive:

    Write each confirmed issue as an AUD-PHP finding with path:line evidence and 1-5 ratings, compute roi_score, sort descending, and …

    line 165
  9. Distinctive:

    Verify: The report lists AUD-PHP findings sorted by roi_score, each with evidence and a remediation link.

    line 167
  10. Very specific:

    Check the effective php.ini for legacy or risky directives — display_errors=On in production, error_reporting hiding deprecations, a low …

    line 174

“Common” is measured: kept by at least 6 in 10 of the 10 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/audit/php/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

PHP Codebase Audit

When to use

  • The user needs to locate calls to deprecated or removed PHP APIs (for example each(), create_function(), mysql_*, curly-brace string offsets) across the codebase before an upgrade.
  • The user wants a ranked report of what to modernize in a legacy PHP project — which files lack strict types, which call removed functions, which pin an old PHP version — with a ROI-ordered backlog.
  • The user asks to audit or scan an existing PHP codebase for version drift, missing declare(strict_types=1), deprecated APIs, or ini/autoload configuration smells.

When NOT to use

  • Do not run a version-drift audit on greenfield code that is already written for the current PHP version with strict types on; there is no drift to find.
  • Do not use this audit skill to actually rewrite code for a version bump; once findings are recorded, hand off to php/migrate-php74-to-php80 to do the migration.

Core guidance

  • Pin the target PHP version before judging drift — Read the required PHP from composer.json (require.php), the CI matrix, and the runtime php -v, then measure drift against that pinned target — a construct is only "deprecated" relative to a concrete version.
  • Grep for removed and deprecated symbols — Grep for a known-removed symbol set (each(, create_function(, mysql_, \bereg, ${...} string offsets, #[\ReturnTypeWillChange] gaps) and cite each hit as path:line; a static scanner or Rector dry-run corroborates the grep.
  • Score each AUD-PHP finding by ROI — Give every AUD-PHP finding a roi_score = (impact * severity * confidence) / effort; a removed-API call in a hot path outranks a cosmetic strict_types gap in a rarely-touched file even though both are real.
  • Measure strict_types coverage as a ratio — Count PHP files that begin with declare(strict_types=1) versus the total, and report the ratio plus the specific files that lack it as one grouped finding rather than one finding per file.

Decision Engine

Walk this section before choosing an implementation path.

What is the dominant source of PHP drift in the sampled files — the language
version, type safety, deprecated APIs, or configuration?

├── the smell is in php.ini or composer autoload, not source: → Raise an AUD-PHP configuration finding citing the directive or autoload block and
its observed value, and recommend the safe production setting.

├── code calls deprecated or removed functions: → Raise a high-severity AUD-PHP finding per removed symbol, cite each call site, and
mark it an upgrade blocker so it ranks above cosmetic drift.

├── files lack declare(strict_types=1) or type hints: → Raise a grouped AUD-PHP strict_types finding with the coverage ratio and the sample
files, rating effort against the module's test coverage.

└── composer pins an old PHP or removed syntax is present: → Raise an AUD-PHP version-drift finding, cite composer.json and the removed-syntax
call sites, and cross-link php/migrate-php74-to-php80 for remediation.

Full engine: references/decision-engine.md — Decision Tree, Priority Matrix, Decision Table.

Workflows

Workflow: Assemble Report

Progress:
- [ ] Assemble the AUD-PHP findings into a report with a header (target version, scope),
a ROI-sorted table, and a called-out quick-wins section for high-ROI, low-effort
items
- [ ] For the top findings, link php/migrate-php74-to-php80 (or the relevant skill) as the
remediation and note any preconditions such as test coverage the migration needs
  1. Assemble the AUD-PHP findings into a report with a header (target version, scope), a ROI-sorted table, and a called-out quick-wins section for high-ROI, low-effort items.
    • Verify: The report has a header, a ROI-sorted table, and a quick-wins callout.
  2. For the top findings, link php/migrate-php74-to-php80 (or the relevant skill) as the remediation and note any preconditions such as test coverage the migration needs.
    • Verify: The top findings each name a remediation skill and any stated precondition.

Workflow: Scan Drift

Progress:
- [ ] Read composer.json and CI to fix the target PHP version, then set the scan scope to
application source only, excluding vendor and generated directories
- [ ] Grep for removed symbols and missing strict_types, then corroborate hits with
PHPStan or a Rector dry-run, opening each file to reject comment and string matches
- [ ] Write each confirmed issue as an AUD-PHP finding with path:line evidence and 1-5
ratings, compute roi_score, sort descending, and cross-link the migration skill
  1. Read composer.json and CI to fix the target PHP version, then set the scan scope to application source only, excluding vendor and generated directories.
    • Verify: The target version and the scanned paths are recorded in the report header.
  2. Grep for removed symbols and missing strict_types, then corroborate hits with PHPStan or a Rector dry-run, opening each file to reject comment and string matches.
    • Verify: Each candidate hit is confirmed in the file and false positives are dropped.
  3. Write each confirmed issue as an AUD-PHP finding with path:line evidence and 1-5 ratings, compute roi_score, sort descending, and cross-link the migration skill.
    • Verify: The report lists AUD-PHP findings sorted by roi_score, each with evidence and a remediation link.

Best practices

  • Inspect composer.json autoload for files/classmap sprawl, require of PHP files, and namespace-to-path mismatches; flag them as findings and prefer PSR-4 with an optimized classmap for production
  • Check the effective php.ini for legacy or risky directives — display_errors=On in production, error_reporting hiding deprecations, a low memory_limit, or a short max_execution_time — and record each as a finding with the observed value

Anti-patterns

Anti-patternWhy it failsDo instead
Reporting version drift with no call siteAn unlocated claim cannot be verified or fixed and is indistinguishable from a guess.Attach evidence: path/File.php:line to every AUD-PHP finding and group repeated<br>hits under one finding with a representative sample of lines.
Rewriting code mid-auditFixing as you go skews the ROI ranking, leaves the survey incomplete, and mixes untested changes into a review pass.Record every issue as a finding first, then hand the ranked list to<br>php/migrate-php74-to-php80 for the actual edits.
Assuming the PHP version from the frameworkFramework support windows are wide, so guessing the PHP version mislabels which APIs are deprecated or removed.Read composer.json require.php, the CI matrix, and php -v, and record the<br>confirmed target version in the report header.

See references/anti-patterns.md.

Debugging

  1. Grep matches inside comments and strings — Reporting non-executable matches as findings wastes reviewer time and lowers confidence in the whole audit. Fix: Corroborate grep hits by opening the file, and prefer an AST-aware tool (PHPStan, Rector --dry-run) that ignores comments and strings; lower confidence when unverified.
  2. Recommending a blind strict_types sweep — strict_types changes coercion behavior, so a blind sweep introduces regressions the audit was meant to prevent. Fix: Rate strict_types findings with a realistic effort that accounts for test coverage, and recommend enabling it file-by-file behind tests, not repo-wide.
  3. Scanning vendor and generated code — Third-party debt is not actionable for this repo and drowns the findings that are. Fix: Exclude vendor/, node_modules/, caches, and generated directories from the scan and state the scoped paths in the report.

Production checklist

  • Deprecated-API grep hits are corroborated with PHPStan or Rector dry-run, and unverified hits carry lower confidence.
  • Each AUD-PHP finding has a path:line evidence string and no finding is a bare assertion.
  • Each finding's remediation names the fix and links php/migrate-php74-to-php80 or another implementation skill.
  • Every finding has a roi_score and the report is sorted descending by it.
  • The report header states the confirmed target PHP version from composer.json, CI, and php -v.
  • The scan excludes vendor, build output, and generated files, and the scoped paths are stated.

Version notes

  • Deprecations accumulating across PHP 8.1 to 8.4 (PHP >=8.1) — PHP 8.1-8.4 add deprecations such as implicitly-nullable parameters, dynamic properties, and utf8_encode/utf8_decode; an audit targeting 8.2+ should flag these as deprecation-warning findings ranked below outright removals.
  • Symbols removed between PHP 7.4 and 8.0 (PHP >=7.4) — each(), create_function(), curly-brace string/array offsets, and the real-type (unset) cast were removed in PHP 8.0; auditing a 7.4 codebase targeting 8.0 must flag every call site of these as upgrade blockers.

Security

  • Treat verbose error output as a security finding — When the audit finds display_errors=On, stack traces echoed to the response, or debug endpoints reachable in production, record it as a security-relevant AUD-PHP finding — leaked paths, versions, and SQL fragments aid attackers.

Testing

  • Activation and decision behavior are verified in eval/scenarios/audit/php.yaml.

Additional resources

  • references/anti-patterns.md
  • references/core.md
  • references/decision-engine.md
  • references/examples.md
  • references/pitfalls.md
  • references/recipes.md
  • references/version-differences.md

Knowledge graph

Related: audit/project-analysis, php/migrate-php74-to-php80

<!-- graph-fragment: graph/fragments/audit/php.yaml -->

Skill contract

Produces: audit.php-findings
Requires: repo.php-sources
Risk: low · Confidence: 0.9

<!-- contract-fragment: contracts/fragments/audit/php.yaml -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.