PHPackages                             phpswag/phpswag - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. phpswag/phpswag

ActiveLibrary[API Development](/categories/api)

phpswag/phpswag
===============

A framework-agnostic PHP Swagger/OpenAPI generator

v1.0.2(yesterday)28↑2900%MITPHPPHP &gt;=8.1CI passing

Since Jun 9Pushed todayCompare

[ Source](https://github.com/tolawho/phpswag)[ Packagist](https://packagist.org/packages/phpswag/phpswag)[ RSS](/packages/phpswag-phpswag/feed)WikiDiscussions dev Synced today

READMEChangelog (1)Dependencies (14)Versions (6)Used By (0)

PHP Swagger Generator
=====================

[](#php-swagger-generator)

[![CI Status](https://github.com/tolawho/phpswag/actions/workflows/ci.yml/badge.svg)](https://github.com/tolawho/phpswag/actions/workflows/ci.yml)[![Codecov Coverage](https://camo.githubusercontent.com/b2c9c6db7c9396b19485744d05342bdba0848e17ab626bebcd550a71b52592e6/68747470733a2f2f636f6465636f762e696f2f67682f746f6c6177686f2f706870737761672f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/tolawho/phpswag)[![PHP Version](https://camo.githubusercontent.com/29f23cb80f394c24fce6d356a21f581989c706a5885778f9227ba0343f54573d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253345253344253230382e302d626c75652e737667)](https://packagist.org/packages/phpswag/phpswag)[![PHPStan Level 7](https://camo.githubusercontent.com/aea6993733cd63f8c0509bd208548ef02a3a2459c5e5c25230c62866ad483b7f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230372d627269676874677265656e2e737667)](https://github.com/phpstan/phpstan)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)

> **PHP OpenAPI/Swagger generator using AST, PHPDoc and PHP 8 Attributes**

A framework-agnostic **PHP Swagger generator** that uses static analysis (AST) and PHPDoc. This **AST-based API documentation** library scans your source code and serves as a powerful **OpenAPI 3.1 generator** (as well as 3.0). It also features seamless **Laravel/Symfony integration** out-of-the-box.

Features
--------

[](#features)

- **AST-based Static Analysis**: No need to run your application.
- **Modern PHP Support**: Handles namespaces, use aliases, and complex types.
- **Global API Metadata Discovery**: Automatically extracts `@title`, `@version`, `@description`, `@contact.*`, `@license.*`, `@host`, and `@server` from any file.
- **Security &amp; Authentication**: Define global security schemes (ApiKey, JWT) and apply them to endpoints or globally.
- **Comprehensive Schema Validation**: Support for `minimum`, `maximum`, `minLength`, `maxLength`, `pattern`, `format`, and `example` directly in PHPDoc.
- **Auto-inference**: Automatically resolve route parameters and request bodies from method signatures.
- **Intelligent Schema Inference**: Automatically determines `required` fields for Model schemas based on PHP native type-hint nullability, PHPDoc types, and default values. Override with explicit `@required` tag.
- **Advanced Type Resolution**:
    - Primitives: `int`, `string`, `bool`, `float`.
    - Nullable types: `?string` or `string|null`.
    - Array types: `User[]` or `array`.
    - Map/Dictionary types: `array` (resolves to an object with `additionalProperties` mapping to `User`).
    - Class references: Automatically resolves FQCN and creates schemas.
- **Advanced OOP Support**:
    - **Inheritance**: Properties from parent classes are automatically merged into child schemas.
    - **Traits**: Supports `use Trait` with property merging.
    - **Overrides**: Child classes can override parent property types and descriptions.
- **Powerful Generics**:
    - Supports `@template` in class docblocks.
    - Handles nested generics like `ApiResponse`.
    - Supports generic inheritance (e.g., `class UserResponse extends ApiResponse`).
    - Uses clean schema naming: `ApiResponse.User`.
- **OpenAPI 3.0 &amp; 3.1**: Supports both versions, with automatic conversion of nullable types for 3.1.
- **Schema Registry**: Handles circular references and avoids duplicate definitions.
- **Native PHP Enum Support (PHP 8.1+)**: Automatically extracts enum cases and types for both `BackedEnum` (string/int) and `UnitEnum`.
- **PHP 8+ Attributes Support**: Declare routing, schema, and parameter metadata directly using native PHP 8 attributes (e.g., `#[Get]`, `#[Property]`, `#[QueryParam]`, `#[Response]`).
- **OpenAPI Linter &amp; Validator**: Detect specification integrity issues and unresolved model references with the `--validate` option.
- **Framework Integrations**: Seamless bridges for Laravel Service Providers and Symfony Bundle DI configurations.

Installation
------------

[](#installation)

```
composer require phpswag/phpswag
```

Usage
-----

[](#usage)

### Simple Execution

[](#simple-execution)

```
use PhpSwag\Core;

$core = new Core();
$core->setOpenApiVersion('3.1.0'); // Optional, defaults to 3.0.0

// Optional: Enable caching to speed up consecutive generations
$core->enableCache('./.phpswag-cache');

$yaml = $core->generate(['./src/App']);

file_put_contents('swagger.yaml', $yaml);
```

### Global Metadata Discovery

[](#global-metadata-discovery)

You can define your API information in a top-level PHPDoc block in any of your scanned files:

```
/**
 * @title My Awesome API
 * @version 2.1.0
 * @description This is a sample API for testing global metadata.
 * @contact.name John Doe
 * @contact.email john@example.com
 * @license.name MIT
 * @license.url https://opensource.org/licenses/MIT
 * @host https://api.example.com
 * @server https://api.production.com Production Server
 * @server https://api.staging.com Staging Server
 *
 * @tag.name Auth Authentication endpoints
 * @tag.name Users User management endpoints
 */
```

- **Multiple Servers**: You can define multiple servers using `@server [URL] [Description]`. If `@server` tags are defined, they will take precedence over `@host`.
- **Global Tag Ordering**: Explicitly define tags using `@tag.name [name] [description]` at the global level. The generated OpenAPI spec will preserve the order and descriptions of these tags. Any other tags found on endpoints that are not declared at the global level will be sorted alphabetically and appended to the end of the list.

### Controller-level Metadata &amp; Inheritance

[](#controller-level-metadata--inheritance)

You can declare `@tag`, `@security`, `@accept` (or `@consume`), and `@produce` at the Controller (class) level. These act as defaults for all methods in the class:

```
/**
 * @tag Users
 * @security BearerAuth
 * @accept json
 * @produce json
 */
class UserController {
    /**
     * @route POST /users
     * @body UserCreateRequest
     */
    public function create() {} // Inherits @tag Users, @security BearerAuth, @accept json, @produce json

    /**
     * @route GET /users/public
     * @security
     */
    public function listPublic() {} // Overrides security to "no security" (empty array)
}
```

- **Multiple/Comma-separated Tags**: You can specify multiple tags on a single line separated by commas, e.g., `@tag Auth, Users` (supported at both class and method level). Class-level and method-level tags are automatically merged.
- **Overrides**: Method-level `@security`, `@accept`/`@consume`, and `@produce` completely override the class-level defaults. An empty `@security` tag on a method overrides class security to disable authentication for that endpoint.

### Security &amp; Authentication

[](#security--authentication)

Define security schemes and requirements globally or per operation:

```
/**
 * @title Security API
 * @securityDefinitions.apikey MyApiKey header X-API-KEY
 * @securityDefinitions.jwt MyJwtAuth
 * @securityDefinitions.basic MyBasicAuth
 * @security MyJwtAuth
 */

class Controller {
    /**
     * @route GET /private
     * @security MyApiKey
     */
    public function secureAction() {}

    /**
     * @route GET /scoped
     * @security MyJwtAuth[read, write]
     */
    public function scopedAction() {}
}
```

- **OR logic**: Use multiple `@security` tags on a method.
- **AND logic**: Use a single tag with comma-separated schemes: `@security Key1, Key2`.

### Validation &amp; Schema Metadata

[](#validation--schema-metadata)

You can add validation constraints and metadata directly in the description of `@property`, `@var`, `@query`, `@path`, etc., using a simple function-like syntax.

```
/**
 * @query int $age User age minimum(18) maximum(100) default(20)
 * @query string $email User email format(email) example(user@example.com)
 * @query string $code Auth code pattern(^[A-Z0-9]{6}$) minLength(6) maxLength(6)
 */
```

Supported constraints:

- **Numeric**: `minimum(n)`, `maximum(n)`
- **String**: `minLength(n)`, `maxLength(n)`, `pattern(regex)`, `format(type)`
- **Common**: `enum(a,b,c)`, `default(value)`, `example(value)`

Values are automatically cast to their appropriate types (integers, floats, or strings) in the final OpenAPI output.

Validation constraints and formats are also fully supported on the `@body` tag description (e.g., `@body string file to upload format(binary)`).

### Intelligent Schema Inference

[](#intelligent-schema-inference)

The library automatically infers `required` fields for your component schemas based on properties' PHP type-hints, default values, and PHPDocs.

```
class User {
    /** @var string $id */
    public string $id; // Required (non-nullable native type, no default)

    /** @var string $name */
    public string $name = 'Anonymous'; // Optional (has default value)

    /** @var string $email */
    public ?string $email; // Optional (nullable native type)

    /** @var string $bio */
    public string|null $bio; // Optional (nullable union type)

    /** @var mixed $extra */
    public mixed $extra; // Optional (mixed type can be null)

    /** @var string $status */
    public $status; // Required (no native type, but @var type is non-nullable string)

    /** @var string|null $avatar */
    public $avatar; // Optional (no native type, but @var type is nullable string)
}
```

#### Explicit `@required` Tag

[](#explicit-required-tag)

You can override the automatic inference using the `@required` tag:

- **For member properties (class properties):**Use `@required` as a standalone tag or inline in the description: ```
    class User {
        /**
         * @var string $email
         * @required
         */
        public ?string $email; // Required because of explicit @required tag

        /** @var string $name Name @required */
        public ?string $name; // Required because of inline @required

        /**
         * @var string $status
         * @required false
         */
        public string $status; // Optional because of explicit @required false
    }
    ```
- **For class-level `@property` definitions:**Use `@required $propertyName` in the class docblock or inline `@required`: ```
    /**
     * @property string $name @required
     * @property string $email
     * @property string $status
     *
     * @required $email
     * @required $status false
     */
    class User {}
    ```

### Native PHP Enum Support (PHP 8.1+)

[](#native-php-enum-support-php-81)

The library fully supports PHP 8.1+ native Enums (both `BackedEnum` and `UnitEnum`). When an enum is referenced as a type in `@response`, `@property`, `@var`, etc., it is automatically detected and registered in the OpenAPI schemas.

- **BackedEnum (string/int)**: Automatically resolves the schema `type` to `string` or `integer` based on the backing type, and populates the `enum` array with the backing values of all cases.
- **UnitEnum**: Resolves the schema `type` to `string` and populates the `enum` array with the names of all cases.

#### Example

[](#example)

```
namespace App\Enums;

// Backed Enum (string)
enum UserStatus: string {
    case Pending = 'pending';
    case Active = 'active';
    case Suspended = 'suspended';
}

// Backed Enum (int)
enum UserRole: int {
    case Admin = 1;
    case Editor = 2;
    case User = 3;
}

// Pure Unit Enum
enum TicketPriority {
    case Low;
    case Medium;
    case High;
}
```

When you use these enums as property types or response types, they are generated in the OpenAPI specification as:

```
components:
  schemas:
    App_Enums_UserStatus:
      type: string
      enum:
        - pending
        - active
        - suspended
    App_Enums_UserRole:
      type: integer
      enum:
        - 1
        - 2
        - 3
    App_Enums_TicketPriority:
      type: string
      enum:
        - Low
        - Medium
        - High
```

### Smart Type Mapping &amp; Custom Registry

[](#smart-type-mapping--custom-registry)

The generator includes a built-in `TypeMappingRegistry` that automatically maps common PHP and library classes to their standard OpenAPI representations without requiring you to document them or triggering unresolved class errors:

- **DateTime / Date**:
    - `DateTime`, `DateTimeImmutable`, `DateTimeInterface` map to `string` with `format: date-time`.
- **File Uploads**:
    - `Symfony\Component\HttpFoundation\File\UploadedFile`, `Psr\Http\Message\UploadedFileInterface`, `Illuminate\Http\UploadedFile` map to `string` with `format: binary`.
- **UUIDs**:
    - `Ramsey\Uuid\Uuid`, `Ramsey\Uuid\UuidInterface`, `Symfony\Component\Uid\Uuid` map to `string` with `format: uuid` (only if the classes/interfaces exist in your runtime environment).

#### Custom Type Mapping

[](#custom-type-mapping)

You can register your own custom class-to-schema mappings programmatically using `getTypeMappingRegistry()`:

```
use PhpSwag\Core;

$core = new Core();
$core->getTypeMappingRegistry()->register(
    'App\ValueObjects\Money',
    [
        'type' => 'number',
        'format' => 'money'
    ]
);
```

### Route Parameters Handling

[](#route-parameters-handling)

The library supports explicit tags and auto-inference (inspired by swaggo).

```
/**
 * @route GET /users/{id}
 * @path int $id User unique ID
 * @query string $status Filter by status enum(active,inactive) default(active)
 */
public function show(int $id, string $status) {}
```

- **Explicit Tags**: `@path`, `@query`, `@header`, `@cookie`, `@body`.
- **Metadata**: Support `enum(a,b,c)` and `default(value)` in descriptions.
- **Auto-inference**: If no tags are provided, parameters are inferred from the method signature. Primitive types match path/query, and class types match the request body.

### PHP 8+ Attributes Support

[](#php-8-attributes-support)

You can document your endpoints and models using modern PHP 8+ Attributes instead of (or alongside) PHPDoc comments. Attributes offer IDE autocomplete, static checking, and clean syntax.

#### Available Attributes

[](#available-attributes)

All attributes are located under the `PhpSwag\Attributes` namespace:

- **Routing &amp; Tags**:
    - `#[Route(method: string, path: string)]` or method shortcuts: `#[Get(path)]`, `#[Post(path)]`, `#[Put(path)]`, `#[Delete(path)]`.
    - `#[Tag(name: string, description: ?string = null)]` (Repeatable, can be on class/method).
    - `#[OperationId(id: string)]` (On method).
    - `#[Deprecated]` (On method).
- **Parameters &amp; Body**:
    - `#[QueryParam]`, `#[PathParam]`, `#[HeaderParam]`, `#[CookieParam]`: Specify custom path, query, header, or cookie parameters.
    - `#[RequestBody(type: string, description: ?string = null, ...validation)]`: Define endpoint's request body schema.
- **Response &amp; Schema**:
    - `#[Response(code: int|string, type: string, description: ?string = null)]` (Repeatable, on method).
    - `#[Schema(title: ?string = null, description: ?string = null)]` (On class).
    - `#[Property(name: ?string = null, type: ?string = null, description: ?string = null, ...validation, required: ?bool = null)]` (Repeatable on class, or single on class property).

#### Example Usage

[](#example-usage)

```
use PhpSwag\Attributes\Get;
use PhpSwag\Attributes\Tag;
use PhpSwag\Attributes\QueryParam;
use PhpSwag\Attributes\Response;
use PhpSwag\Attributes\Property;
use PhpSwag\Attributes\Schema;

#[Schema(description: "User Response Model")]
class User {
    #[Property(description: "User unique ID", minimum: 1)]
    public int $id;

    #[Property(description: "User email", format: "email")]
    public string $email;
}

#[Tag("Users")]
class UserController {
    #[Get("/users/{id}")]
    #[QueryParam("status", type: "string", description: "Filter by status", enum: ["active", "inactive"])]
    #[Response(200, User::class, description: "Success response")]
    public function show(int $id) {}
}
```

#### Smart Merge Strategy (Parallel Usage)

[](#smart-merge-strategy-parallel-usage)

When both PHPDoc and PHP 8 Attributes are present:

1. **Single-value properties** (e.g., `summary`, `description`, `operationId`): Values in **Attributes** override PHPDoc. PHPDoc is used as a fallback if not declared in Attributes.
2. **Collections** (e.g., tags, security): Values from both sources are **merged** together.
3. **Keyed Collections** (e.g., query params with matching names, response codes): Attributes **override** PHPDoc for that specific key/parameter. Unmatched keys from both sources are merged.

Support Tags
------------

[](#support-tags)

- **Global Metadata**:
    - `@title [TEXT]`
    - `@version [TEXT]`
    - `@description [TEXT]`
    - `@contact.name [TEXT]`
    - `@contact.email [TEXT]`
    - `@contact.url [TEXT]`
    - `@license.name [TEXT]`
    - `@license.url [TEXT]`
    - `@host [URL]`
    - `@server [URL] [Description]`
- **Security**:
    - `@securityDefinitions.apikey [NAME] [IN: header|query|cookie] [KEY_NAME]`
    - `@securityDefinitions.jwt [NAME]`
    - `@securityDefinitions.basic [NAME]`
    - `@security [NAME]` or `@security [NAME[scopes]]` (supports OR/AND)
- **Endpoints**:
    - `@route [METHOD] [PATH]` (e.g., `@route POST /data`)
    - `@summary [TEXT]`
    - `@description [TEXT]`
    - `@tag [NAME]`
    - `@accept [MIME_TYPE]` or `@consume [MIME_TYPE]` (e.g. `json`, `xml`, or full MIME type)
    - `@produce [MIME_TYPE]` (e.g. `json, xml` or full MIME type)
    - `@path [TYPE] $[NAME] [DESC]`
    - `@query [TYPE] $[NAME] [DESC]`
    - `@header [TYPE] $[NAME] [DESC]`
    - `@cookie [TYPE] $[NAME] [DESC]`
    - `@body [TYPE] [DESC]`
    - `@response [CODE] [TYPE] [DESC]` (e.g., `@response 200 ApiResponse Success response`, supports `default` code)
    - `@success [CODE] [TYPE] [DESC]` (Alias of `@response`, e.g., `@success 200 User Success`, supports `default` code)
    - `@failure [CODE] [TYPE] [DESC]` (Alias of `@response`, e.g., `@failure 400 ErrorResponse Bad Request`, supports `default` code)
    - `@operationId [TEXT]` (Define explicit operationId)
    - `@deprecated` (Mark the operation as deprecated)
    - `@x-[EXTENSION_NAME] [VALUE]` (Custom OpenAPI extensions, e.g. `@x-code-samples [{"lang": "PHP"}]`)
- **Models**:
    - `@property [TYPE] $[NAME] [DESCRIPTION]` (Supports validation tags in description)
    - `@var [TYPE]` (Supports validation tags in description) (for class properties)
    - `@required` (for member properties) or `@required [PROPERTY_NAME] [true|false]` (for class-level properties or overrides)
    - `@template [NAME]` (for generics)
    - `@extends [TYPE]` or `@use [TYPE]` (for generic arguments)

Testing
-------

[](#testing)

To run the unit tests:

```
composer install
./vendor/bin/phpunit
```

To run the example generator:

```
php examples/generate.php
```

### CLI Usage

[](#cli-usage)

You can use the CLI to generate documentation without writing any PHP code.

#### 1. Configuration Initialization (Wizard)

[](#1-configuration-initialization-wizard)

To easily set up a configuration file for your project, run:

```
./vendor/bin/phpswag init
```

This starts an interactive wizard that asks for your project options and generates a `phpswag.yaml` file in your root folder.

#### 2. Generating Documentation

[](#2-generating-documentation)

If you have a `phpswag.yaml` file in your root directory, you can simply run:

```
./vendor/bin/phpswag generate
```

Or, specify options on the command line (which will override values in the configuration file):

```
./vendor/bin/phpswag generate --path src/Controllers --path src/Models --output swagger.yaml
```

**Options:**

- `--path`, `-p`: Path(s) to scan (can be used multiple times). Supports individual files or directories.
- `--output`, `-o`: Output file path (defaults to stdout).
- `--format`, `-f`: Output format (`yaml` or `json`). Default: `yaml`.
- `--openapi-version`: OpenAPI version (`3.0.0` or `3.1.0`). Default: `3.0.0`.
- `--filter-unused`: Filter out schemas that are not referenced by any route.
- `--title`: API Title override.
- `--api-version`: API Version override.
- `--description`: API Description override.
- `--host`: API Host/Server URL override.
- `--cache`: Enable caching to speed up generation.
- `--cache-file`: Cache file path. Default: `./.phpswag-cache`.
- `--validate`: Run validation and linter checks on the generated specification (checks for missing title/version, structural integrity, and unresolved `$ref` schemas).

#### 3. Live Preview &amp; Hot Reload (Watch Mode)

[](#3-live-preview--hot-reload-watch-mode)

You can launch a built-in preview server that hosts Swagger UI and hot-reloads instantly when you modify your PHP code:

```
./vendor/bin/phpswag watch
```

**Options:**

- `--path`, `-p`: Path(s) to scan.
- `--output`, `-o`: Output destination file path (default: `swagger.yaml`).
- `--format`, `-f`: Output format (`yaml` or `json`).
- `--host`: Server host (default: `localhost`).
- `--port`: Server port (default: `8080`).

#### 4. Configuration File (`phpswag.yaml`)

[](#4-configuration-file-phpswagyaml)

An example `phpswag.yaml` file:

```
paths:
  - src/Controllers
  - src/Models
openapi_version: 3.1.0
format: yaml
output: public/swagger.yaml
filter_unused: true
cache: true
cache_file: ./.phpswag-cache
```

---

PHP 8+ Attributes Support
-------------------------

[](#php-8-attributes-support-1)

In addition to PHPDoc annotations, `phpswag` fully supports native PHP 8 Attributes. Attributes can be used side-by-side with PHPDoc annotations and follow a **Smart Merge &amp; Override** strategy:

- Single-value metadata (e.g. `summary`, `description`, etc.) defined in Attributes will override PHPDoc definitions.
- Parameter definitions are matched by name; Attributes override PHPDoc definitions for the same parameter name.
- Collection tags (e.g. `@tag`, `@security`) defined in both places are merged.

### Example

[](#example-1)

```
use PhpSwag\Attributes\Get;
use PhpSwag\Attributes\Tag;
use PhpSwag\Attributes\QueryParam;
use PhpSwag\Attributes\Response;
use PhpSwag\Attributes\Schema;
use PhpSwag\Attributes\Property;

#[Tag("Users")]
class UserController {
    #[Get("/users/{id}")]
    #[QueryParam("status", type: "string", description: "Filter by user status", enum: ["active", "inactive"])]
    #[Response(200, User::class, description: "Returns the requested user")]
    public function show(int $id) {}
}

#[Schema(title: "User", description: "User representation")]
class User {
    #[Property(description: "Unique identifier")]
    public int $id; // Native type hint 'int' is automatically inferred as 'integer'!

    #[Property(description: "User email address", format: "email")]
    public string $email;
}
```

---

Framework Bridges
-----------------

[](#framework-bridges)

`phpswag` includes out-of-the-box integrations for Laravel and Symfony.

### Laravel Integration

[](#laravel-integration)

The Laravel bridge registers config, Artisan commands, and automatic Swagger UI route mappings.

#### 1. Registration

[](#1-registration)

Add the Service Provider in `config/app.php` (if not auto-discovered):

```
'providers' => [
    // ...
    PhpSwag\Bridges\Laravel\PhpSwagServiceProvider::class,
];
```

#### 2. Configuration

[](#2-configuration)

Publish the configuration file:

```
php artisan vendor:publish --tag=phpswag-config
```

This generates `config/phpswag.php` where you can customize directories to scan, output path, API metadata, and Swagger UI routes.

#### 3. Generation &amp; Validation

[](#3-generation--validation)

Run the Artisan command to generate the spec:

```
php artisan phpswag:generate
```

Pass the `--validate` flag to validate schema references and spec completeness:

```
php artisan phpswag:generate --validate
```

---

### Symfony Integration

[](#symfony-integration)

The Symfony bridge provides a Bundle to load parameters into the Dependency Injection container and registers Symfony console commands.

#### 1. Registration

[](#1-registration-1)

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    PhpSwag\Bridges\Symfony\PhpSwagBundle::class => ['all' => true],
];
```

#### 2. Configuration

[](#2-configuration-1)

Create a configuration file `config/packages/phpswag.yaml`:

```
phpswag:
    paths:
        - '%kernel.project_dir%/src/Controller'
        - '%kernel.project_dir%/src/Entity'
    output: '%kernel.project_dir%/public/swagger.yaml'
    title: 'My Symfony API'
    version: '1.0.0'
```

#### 3. Generation &amp; Validation

[](#3-generation--validation-1)

Run the console command:

```
php bin/console phpswag:generate
```

To validate the schema:

```
php bin/console phpswag:generate --validate
```

---

Contributing
------------

[](#contributing)

We welcome contributions from the community! If you'd like to help improve `phpswag`, please review our [Contributing Guidelines](CONTRIBUTING.md).

Please also adhere to our [Code of Conduct](CODE_OF_CONDUCT.md) to keep our community approachable and respectable.

For security vulnerabilities, please refer to our [Security Policy](SECURITY.md).

---

☕ Support / Donate
------------------

[](#-support--donate)

**⭐️ Star this repository**

If you find `phpswag` useful, please consider giving it a star on GitHub! It helps the project grow and reach more developers.

**☕ Buy me a coffee**

This project is developed and maintained entirely for free during my spare time. If you would like to financially support its development, you can buy me a coffee through the following channels:

- **PayPal:** [paypal.me/tolawho](https://paypal.me/tolawho)
- **Ko-fi:** [ko-fi.com/tolawho](https://ko-fi.com/tolawho)
- **Crypto (ETH/ERC20):** `0x730c98ef98c660862baedef292ae3a041a905cdd`
- **Crypto (BTC):** `bc1qv2cp6mcjcd3m2v6hvk09qjg47tljd6mkea6dmuevhxm3a6ps38jqxtwgex`

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance100

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

1d ago

PHP version history (2 changes)v1.0.0PHP &gt;=8.0

v1.0.1PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/3997a6d3d621a84c9139a7446b1fda45557baf3a50737f12c8afa52b4438486c?d=identicon)[tolawho](/maintainers/tolawho)

---

Top Contributors

[![tolawho](https://avatars.githubusercontent.com/u/12527881?v=4)](https://github.com/tolawho "tolawho (57 commits)")

---

Tags

api-documentationapi-generatorapi-toolsdev-toolsdeveloper-toolslaravellaravel-packageopen-api-v3openapiopenapi-3openapi-3-1openapi-documentationopenapi-generatoropenapi-specificationopenapi3phpswaggerswagger-uisymfonysymfony-bundle

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phpswag-phpswag/health.svg)

```
[![Health](https://phpackages.com/badges/phpswag-phpswag/health.svg)](https://phpackages.com/packages/phpswag-phpswag)
```

###  Alternatives

[jolicode/castor

A lightweight and modern task runner. Automate everything. In PHP.

54642.4k4](/packages/jolicode-castor)[zircote/swagger-php

Generate interactive documentation for your RESTful API using PHP attributes (preferred) or PHPDoc annotations

5.3k140.4M553](/packages/zircote-swagger-php)[phparkitect/phparkitect

Enforce architectural constraints in your PHP applications

9134.1M24](/packages/phparkitect-phparkitect)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

101466.4k44](/packages/friendsoftypo3-content-blocks)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[rector/rector-src

Instant Upgrade and Automated Refactoring of any PHP code

136400.8k14](/packages/rector-rector-src)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
