|
| 1 | +# swagger-php |
| 2 | + |
| 3 | +A PHP library that generates OpenAPI specification documents from PHP source code |
| 4 | +by scanning annotations (attributes and docblocks) and processing them into a |
| 5 | +complete spec. |
| 6 | + |
| 7 | +## Language |
| 8 | + |
| 9 | +### Core Concepts |
| 10 | + |
| 11 | +**Annotation**: |
| 12 | +An OpenAPI specification element declared as a PHP 8+ attribute or legacy docblock comment on a class, method, or property. |
| 13 | +_Avoid_: Attribute (too narrow), decorator, metadata |
| 14 | + |
| 15 | +**Analysis**: |
| 16 | +The aggregate result of scanning source code — contains all discovered annotations and structural definitions, before processing. |
| 17 | +_Avoid_: Result, scan output |
| 18 | + |
| 19 | +**Context**: |
| 20 | +Nested metadata describing where an annotation was found in the source hierarchy (file, namespace, class, method, property). |
| 21 | +_Avoid_: Location, position |
| 22 | + |
| 23 | +**Generator**: |
| 24 | +The orchestrator that coordinates scanning, processing, and output — it generates an OpenAPI spec from annotations, not code from a spec. |
| 25 | +_Avoid_: Builder, compiler |
| 26 | + |
| 27 | +**Processor**: |
| 28 | +A single transformation step in an ordered pipeline that converts raw Analysis into a valid, complete OpenAPI specification. |
| 29 | +_Avoid_: Handler, middleware, transformer |
| 30 | + |
| 31 | +### Annotation Lifecycle |
| 32 | + |
| 33 | +**Unmerged**: |
| 34 | +An annotation that has been discovered but not yet incorporated into the target OpenAPI root object. |
| 35 | +_Avoid_: Pending, orphaned |
| 36 | + |
| 37 | +**Merge**: |
| 38 | +Incorporating an annotation into its correct position within the OpenAPI object tree, guided by the nesting map. |
| 39 | +_Avoid_: Combine, attach |
| 40 | + |
| 41 | +**Augment**: |
| 42 | +Filling in missing annotation fields with values inferred from code (e.g. deriving a schema type from a PHP type hint). |
| 43 | +_Avoid_: Enrich, hydrate |
| 44 | + |
| 45 | +**Expand**: |
| 46 | +Resolving PHP inheritance (classes, interfaces, traits, enums) by copying parent annotations into child schemas. |
| 47 | +_Avoid_: Inherit, flatten |
| 48 | + |
| 49 | +### Structural Concepts |
| 50 | + |
| 51 | +**Nesting**: |
| 52 | +The declarative parent-child mapping (`$_nested`) that defines which annotation types can belong inside other annotation types — distinct from PHP class inheritance. |
| 53 | +_Avoid_: Hierarchy (ambiguous with class hierarchy) |
| 54 | + |
| 55 | +**Component**: |
| 56 | +A reusable named definition stored in `#/components/` and referenced via `$ref` elsewhere in the spec. |
| 57 | +_Avoid_: Shared schema, template |
| 58 | + |
| 59 | +**Ref**: |
| 60 | +A JSON Pointer (`$ref`) linking to another part of the spec, resolved by processors into `#/components/...` paths. |
| 61 | +_Avoid_: Link (means something else in OpenAPI), pointer |
| 62 | + |
| 63 | +### Scanning |
| 64 | + |
| 65 | +**Analyser**: |
| 66 | +Reflects on PHP source files to discover annotations and produce an Analysis. |
| 67 | +_Avoid_: Scanner (too narrow — TokenScanner is a sub-component), parser |
| 68 | + |
| 69 | +**AnnotationFactory**: |
| 70 | +Creates annotation objects from discovered PHP attributes or docblock comments during analysis. |
| 71 | +_Avoid_: Builder, constructor |
| 72 | + |
| 73 | +## Relationships |
| 74 | + |
| 75 | +- A **Generator** uses an **Analyser** to produce an **Analysis** |
| 76 | +- An **Analysis** contains **Annotations**, each carrying a **Context** |
| 77 | +- **Processors** run sequentially on an **Analysis**, first **merging** unmerged annotations, then **expanding** inheritance, then **augmenting** missing fields |
| 78 | +- **Nesting** defines where an **Annotation** can be merged within the OpenAPI tree |
| 79 | +- A **Component** is an **Annotation** that has been merged into `#/components/` and is reachable by **Ref** |
| 80 | + |
| 81 | +## Example dialogue |
| 82 | + |
| 83 | +> **Dev:** "I added a `@OA\Schema` on a class but it's not appearing in the output." |
| 84 | +> **Domain expert:** "Is it still **unmerged**? Check that the **nesting** map allows it to be **merged** into Components, and that a **processor** hasn't filtered it out." |
| 85 | +
|
| 86 | +> **Dev:** "Why does the child class schema include the parent's properties?" |
| 87 | +> **Domain expert:** "That's **expansion** — the ExpandClasses **processor** copies parent **annotations** into the child during the pipeline." |
| 88 | +
|
| 89 | +## Flagged ambiguities |
| 90 | + |
| 91 | +- "generate" — resolved: reserve for the full end-to-end pipeline (`Generator::generate()`). Use **analyse** for the discovery phase and **serialize** for producing JSON/YAML output. |
| 92 | +- "merge" — resolved: reserve for tree-placement (moving an annotation into its correct position in the OpenAPI object). Combining multiple annotations' fields into one (e.g. Properties into a Schema) is part of **augment**. |
| 93 | +- "nested" — resolved: use **nesting map** when referring to the `$_nested` declaration. Use **enclosing** when talking about the physical source code structure (file, class, method) that Context tracks. |
0 commit comments