Generate interactive OpenAPI documentation for your RESTful API using doctrine annotations

Last update: Jun 23, 2022

Build Status Total Downloads License


Generate interactive OpenAPI documentation for your RESTful API using doctrine annotations.

For a full list of supported annotations, please have look at the OpenApi\Annotations namespace or the documentation website.


  • Compatible with the OpenAPI 3.0 and 3.1 specification.
  • Extracts information from code & existing phpdoc annotations.
  • Command-line interface available.
  • Documentation site with a getting started guide.
  • Exceptional error reporting (with hints, context)
  • As of PHP 8.1 all annotations are also available as PHP attributes

OpenAPI version support

swagger-php allows to generate specs either for OpenAPI 3.0.0 or OpenAPI 3.1.0. By default the spec will be in version 3.0.0. The command line option --version may be used to change this to 3.1.0.

Programmatically, the method Generator::setVersion() can be used to change the version.

Installation (with Composer)

composer require zircote/swagger-php

For cli usage from anywhere install swagger-php globally and make sure to place the ~/.composer/vendor/bin directory in your PATH so the openapi executable can be located by your system.

composer global require zircote/swagger-php


Add annotations to your php files.

 * @OA\Info(title="My First API", version="0.1")

 * @OA\Get(
 *     path="/api/resource.json",
 *     @OA\Response(response="200", description="An example resource")
 * )

Visit the Documentation website for the Getting started guide or look at the Examples directory for more examples.

Usage from php

Generate always-up-to-date documentation.


$openapi = \OpenApi\Generator::scan(['/path/to/project']);
header('Content-Type: application/x-yaml');
echo $openapi->toYaml();

Documentation of how to use the Generator class can be found in the Generator Migration guide.

Usage from the Command Line Interface

The openapi command line interface can be used to generate the documentation to a static yaml/json file.

./vendor/bin/openapi --help

Starting with version 4 the default analyser used on the command line is the new ReflectionAnalyser.

Using the --legacy flag (-l) the legacy TokenAnalyser can still be used.

Usage from the Deserializer

Generate the OpenApi annotation object from a json string, which makes it easier to manipulate objects programmatically.

use OpenApi\Serializer;

$serializer = new Serializer();
$openapi = $serializer->deserialize($jsonString, 'OpenApi\Annotations\OpenApi');
echo $openapi->toJson();

Usage from docker

Generate the swagger documentation to a static json file.

docker run -v "$PWD":/app -it tico/swagger-php --help

More on OpenApi & Swagger


Feel free to submit Github Issues or pull requests.

The documentation website is build from the docs folder with vuepress.

Make sure pull requests pass PHPUnit and PHP-CS-Fixer (PSR-2) tests.

To run both unit tests and linting execute:

composer test

Running unit tests only:


Running linting only:

composer lint

To make php-cs-fixer fix linting errors:

composer cs

  • 1. Groups support for different model views

    I'm currently working for a company that uses Symfony 2 for its API. They also use the JMSSerializerBundle to serialize the response, but to also support different views for an entity:

    Let me explain this better with the following example for Doctrine entities. A entity Car has a OneToMany association with the enity Part. With the API "/cars/1.json" I want to ->find() Car entity with ID one that also fetched al its childs like the Part entity. The Car entity can be put in the serializer and it will be returned. The controller for "/cars/1.json" will set the groups "Car" and "CarDetails". Because the Car entity has properties with @SER\Groups("Car") annotation and the Part entity has properties with the @SER\Groups("CarDetails") annotation, they will be returned both in the response.

    But lets say we want to show a list of cars with the API call "/cars.json". Then we only want to display the car name and some other fields, but not all parts. So the controller action that handles that call with set only the group "Car" on the serializer, so only the entities and their properties that have this group will be returned.

    At the moment the discoverer of swagger-php doesn't support this. It would be awesome if besides the responseClass attribute a responseGroups attribute could be added that can contain multiple values. A groups attribute could be added to a model property, to include this property of this model only if the API controller action has this Model ID as responseClass but also corresponding responseGroups.

    Because models are reused in Swagger UI over mulitple APIs and we want to use the same model with different views, I'm not sure yet about how to implement this.

    I hope you understand the issue and have some genius input on this :) Let me know what you think!

    Reviewed by pietervogelaar at 2012-12-13 14:59
  • 2. allOf/anyOf/etc. in PHP Attributes

    Hey all! I've scoured the documentation and I really can't find out the recommended way of implementing something like this:

     * @OA\Parameter(
     *     parameter="station_id_required",
     *     name="station_id",
     *     description="The station ID",
     *     example=1,
     *     in="path",
     *     required=true,
     *     @OA\Schema(
     *         anyOf={@OA\Schema(type="integer", format="int64"), @OA\Schema(type="string", format="string")}
     *     )
     * )

    into PHP attributes.

    The closest I've been able to come so far is:

            name: "station_id_required",
            in: "path",
            required: true,
            schema: new OA\Schema(),
            // new OA\Schema(type: "integer", format: "int64"),
            // new OA\Schema(type: "string", format: "string"),

    But I'm not sure how to express the "anyOf" value for the parameter using the attributes. Nothing I'm trying is validating properly. Any ideas?

    Reviewed by SlvrEagle23 at 2021-12-12 15:46
  • 3. PHP 8.1 attributes

    Sneak preview on attributes (requires PHP 8.1).

    In fact, this is now the branch for swagger-php v4!

    Feedback welcome!

    So far:

    • bumps major version to 4.x
    • moved/renamed TokenAnalyserand Analyser
    • introduced a new ReflectionAnalyser and AnnotationFactoryInterface
    • introduced new AnalyserInterface implemented by both TokenAnalyser and ReflectionAnalyser
    • new annotation factories added: DocBlockAnnotationFactory and AttributeAnnotationFactory; ReflectionAnalyser can use either (or possibly both at the same time...)
    • updated all examples to pass with both token analyser and reflection analyser (using DocBlockAnnotationFactory)
      • this required adding classes to lots of stand-alone docblocks....
    • Updated some annotation classes to also work as \Attribute
    • Attribute based fixture intests/Fixtured/Apis/Attributes - this is on parity with the corresponding DocBlock example
    • Allow to mix attributes and annotations
    • Add PHP 8.1 to build matrix (latest deps only)


    • add all supported properties as named ctor parameters to PHP 8.1 constructors
    • add more attribute based tests
    • things I've missed to far :)
    Reviewed by DerManoMann at 2021-08-26 23:32
  • 4. Multiple @OA\Response() with the same response="200"

    That issue occurs only on server side. local.ERROR: ErrorException: Multiple @OA\Response() with the same response="200": \App\Http\Controllers\Student\EventsController->update() in /var/www/html/app/Http/Controllers/Student/EventsController.php on line 136 \App\Http\Controllers\Student\EventsController->store() in /var/www/html/app/Http/Controllers/Student/EventsController.php on line 51 in /var/www/html/vendor/zircote/swagger-php/src/Logger.php:39 I tried api-docs generated on local in and that works very well. How that can be resolved?

    Reviewed by DorelBesliu at 2020-07-08 13:28
  • 5. Add support for OpenAPI 3.0

    Hey there,

    I'm not sure if this is in the works already but after reading this post:

    I wanted to add an issue regarding support for OpenAPI / Swagger 3.0.

    Specifically, the HATEOAS implementation would be very helpful for my team.

    Please let me know if any work has started on this already, otherwise I'd be happy to fork and start contributing.

    Thanks in advance

    Reviewed by prodikl at 2017-03-21 20:52
  • 6. Attribute class "JetBrains\PhpStorm\ArrayShape" not found

    After updating to the new version when I try to generate the documentation I'm getting this:

    [2022-02-03 20:24:22] local.ERROR: Attribute class "JetBrains\PhpStorm\ArrayShape" not found {"exception":"[object] (Error(code: 0): Attribute class \"JetBrains\\PhpStorm\\ArrayShape\" not found at vendor/zircote/swagger-php/src/Analysers/AttributeAnnotationFactory.php:46)
    #0 vendor/zircote/swagger-php/src/Analysers/AttributeAnnotationFactory.php(46): ReflectionAttribute->newInstance()
    #1 vendor/zircote/swagger-php/src/Analysers/ReflectionAnalyser.php(128): OpenApi\\Analysers\\AttributeAnnotationFactory->build(Object(ReflectionMethod), Object(OpenApi\\Context))
    #2 vendor/zircote/swagger-php/src/Analysers/ReflectionAnalyser.php(55): OpenApi\\Analysers\\ReflectionAnalyser->analyzeFqdn('App\\\\Classes\\\\Fin...', Object(OpenApi\\Analysis), Array)
    #3 vendor/zircote/swagger-php/src/Generator.php(378): OpenApi\\Analysers\\ReflectionAnalyser->fromFile('...', Object(OpenApi\\Context))
    #4 vendor/zircote/swagger-php/src/Generator.php(342): OpenApi\\Generator->scanSources(Object(Symfony\\Component\\Finder\\Finder), Object(OpenApi\\Analysis), Object(OpenApi\\Context))
    #5 vendor/darkaonline/l5-swagger/src/Generator.php(181): OpenApi\\Generator->generate(Object(Symfony\\Component\\Finder\\Finder), Object(OpenApi\\Analysis))
    #6 vendor/darkaonline/l5-swagger/src/Generator.php(122): L5Swagger\\Generator->scanFilesForDocumentation()
    #7 vendor/darkaonline/l5-swagger/src/Http/Controllers/SwaggerController.php(60): L5Swagger\\Generator->generateDocs()
    #8 vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): L5Swagger\\Http\\Controllers\\SwaggerController->docs(Object(Illuminate\\Http\\Request), 'api-docs.json')
    #9 vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction('docs', Array)
    #10 vendor/laravel/framework/src/Illuminate/Routing/Route.php(262): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(L5Swagger\\Http\\Controllers\\SwaggerController), 'docs')
    #11 vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()
    #12 vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\\Routing\\Route->run()
    #13 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
    #14 vendor/darkaonline/l5-swagger/src/Http/Middleware/Config.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #15 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): L5Swagger\\Http\\Middleware\\Config->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #16 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #17 vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
    #18 vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
    #19 vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
    #20 vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
    #21 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
    #22 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
    #23 app/Http/Middleware/CorsMiddleware.php(30): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #24 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): App\\Http\\Middleware\\CorsMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #25 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #26 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #27 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #28 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #29 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #30 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #31 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #32 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #33 vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #34 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #35 vendor/fruitcake/laravel-cors/src/HandleCors.php(38): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #36 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #37 vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #38 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
    #39 vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
    #40 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
    #41 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
    #42 public/index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
    #43 server.php(21): require_once('...')
    #44 {main}
    Reviewed by Messhias at 2022-02-03 20:29
  • 7. Error generating JSON for optional security

    I've an endpoint that has optional security. So I need to generate a JSON like

         *     security={
         *          { },
         *          {"api-key": []},
         *     },

    I put this annotation in my code

         *     security={
         *          { },
         *          {"api-key": {}},
         *     },

    but this JSON is generated

         *     security={
         *          [ ],
         *          {"api-key": [ ] },
         *     },

    instead of

         *     security={
         *          { },
         *          {"api-key": [ ] },
         *     },

    This is because PHP json-serialize this structure

        array(2) {
          [0]=> array(0) {}
          [1]=> array(1) {
            ["api-key"]=> array(0) {}

    Any hint about where to start to fix it ?

    Reviewed by hpatoio at 2020-07-09 09:43
  • 8. swagger-php and doctrine annotation not playing nice.


    I currently have swagger-php generating JSON formatted documentation through the commandline util swagger.phar.

    I am trying to do the same now for the models/OM but I am having issues with this. Our project currently uses Doctrine's @ ORM annotation for DB mapping and the two seem to be clashing.

    My main question is (as I am not experienced with this) is @ ORM and @ SWG model annotations compatible? And if they are, do you have an example of them working in harmony?

    If I include both in my annotation, the @ ORM annotation fails, causing my application to error. E.g:

    I've tried swapping their order various other ways but to no avail, it usually results in a "message": "An exception was raised while creating "classnamehere"; no instance returned", error or the @ SWG model annotation above the class being ignored/ commandline error.

    Thanks for any assistance you can provide.

    Regards, Steven

    Reviewed by scoch at 2013-12-12 16:32
  • 9. User Notice: Required @OA\PathItem() not found

    Hi, I m using symfony 4.4 / nelmio api doc bundle 4.0 / swagger-php 3.0. When i try with a first example i get this error : User Notice: Required @OA\PathItem() not found

    ` namespace App\Controller;

    use OpenApi\Annotations as OA;


    • @OA\PathItem(
    • path="/products/{product_id}",
    • @OA\Parameter(ref="#/components/parameters/product_id_in_path_required")
    • ) */

    class ProductController {

     * @OA\Get(
     *   tags={"Products"},
     *   path="/products/{product_id}",
     *   @OA\Response(
     *       response="default",
     *       description="successful operation",
     *       @OA\JsonContent(ref="#/components/responses/product")
     *   )
     * )
    public function getProduct($id)
    Reviewed by mohamed-jebri at 2020-06-09 08:24
  • 10. add option to prefix public resource path

    since my api docs are not stored in the document-root, i needed to add kind of a prefix for the path-property which is used in the api-docs.json file

    any thoughts on this?

    Reviewed by steffkes at 2013-05-02 13:10
  • 11. Argument 2 passed to OpenApi\Analysis::addAnnotations() must be an instance of OpenApi\Context

    Since upgrading to 3.3.0 yesterday, I get the following error when creating the documentation:

    In Analysis.php line 128: Argument 2 passed to OpenApi\Analysis::addAnnotations() must be an instance of OpenApi\Context, null given, called in .../vendor/zircote/swagger-php/src/Analysis.php on line 85

    Works fine after downgrading again: Downgrading zircote/swagger-php (3.3.0 => 3.2.3)

    Reviewed by jochen-jung at 2021-11-09 06:15
  • 12. MediaType multipart/form-data problem with attribute

    zircote/swagger-php version : 4.4.5

    When I try to use MediaType in RequestBody — endpoint not visible in generated yaml, without error, what could be the problem?

        path: '...',
        summary: '...',
        requestBody: new OAT\RequestBody(required: true, content: new OAT\MediaType(
            mediaType: 'multipart/form-data',
            schema: new OAT\Schema(
                properties: [
                    new OAT\Property(property: 'file', description: 'User photo', type: 'string', format: 'binary')
                type: 'object'
        // ...
    Reviewed by igorbelikov at 2022-06-23 15:06
  • 13. Function return reference give error

    zircote/swagger-php version : 4.2.11

    When a function with a reference as output is present in a file, we receive :

    Warning: Uninitialized string offset 1

    My code :

        public function &all(): array
            return $this->texts;

    When I remove the &, the docs work.

    Full error message :

       "code":0,"message":"Warning: Uninitialized string offset 1",
       "stack":"#0 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Analysers\/TokenScanner.php(21): OpenApi\\Analysers\\TokenScanner-\u003EscanTokens(Array)\n#1 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Analysers\/ReflectionAnalyser.php(49): OpenApi\\Analysers\\TokenScanner-\u003EscanFile(\u0027\/var\/www\/html\/s...\u0027)\n#2 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Generator.php(378): OpenApi\\Analysers\\ReflectionAnalyser-\u003EfromFile(\u0027\/var\/www\/html\/s...\u0027, Object(OpenApi\\Context))\n#3 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Generator.php(376): OpenApi\\Generator-\u003EscanSources(Object(Symfony\\Component\\Finder\\Finder), Object(OpenApi\\Analysis), Object(OpenApi\\Context))\n#4 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Generator.php(342): OpenApi\\Generator-\u003EscanSources(Array, Object(OpenApi\\Analysis), Object(OpenApi\\Context))\n#5 \/var\/www\/html\/vendor\/zircote\/swagger-php\/src\/Generator.php(294): OpenApi\\Generator-\u003Egenerate(Array, Object(OpenApi\\Analysis), true)\n#6 \/var\/www\/html\/src\/Controller\/ApiController.php(189): OpenApi\\Generator::scan(Array)\n#7 \/var\/www\/html\/vendor\/symfony\/http-kernel\/HttpKernel.php(152): App\\Controller\\Controller-\u003EgetSwagger()\n#8 \/var\/www\/html\/vendor\/symfony\/http-kernel\/HttpKernel.php(74): Symfony\\Component\\HttpKernel\\HttpKernel-\u003EhandleRaw(Object(Symfony\\Component\\HttpFoundation\\Request), 1)\n#9 \/var\/www\/html\/vendor\/symfony\/http-kernel\/Kernel.php(202): Symfony\\Component\\HttpKernel\\HttpKernel-\u003Ehandle(Object(Symfony\\Component\\HttpFoundation\\Request), 1, true)\n#10 \/var\/www\/html\/vendor\/symfony\/runtime\/Runner\/Symfony\/HttpKernelRunner.php(35): Symfony\\Component\\HttpKernel\\Kernel-\u003Ehandle(Object(Symfony\\Component\\HttpFoundation\\Request))\n#11 \/var\/www\/html\/vendor\/autoload_runtime.php(35): Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner-\u003Erun()\n#12 \/var\/www\/html\/public\/index.php(5): require_once(\u0027\/var\/www\/html\/v...\u0027)\n#13 {main}"

    Thank you for your help :)

    Reviewed by crbast at 2022-06-23 11:26
  • 14. Hard to find out problem with invalid attribute

    Right now, invalid attribute is logged with DEBUG level. Default logger just ignores this level.

    So it is impossible to know if something whent wrong f.e.when instantiating OA\Get(...) attribute throws excpeption, it is silently dropped. Don't know how to improve, just point this issue.

    Reviewed by zim32 at 2022-06-22 18:01
  • 15. Validation on Windows vs Linux

    I'm using Lumen and this package to document an API. The routes are defined in the controllers, schema's in models, and I have a directory full of re-usable schema's and info files. One example being;

    namespace App\Specs;
    use OpenApi\Annotations as OA;
     * @OA\Info(
     *     title="My API",
     *     version="1.0",
     *     description="My cool API",
     * )
    class OpenApi

    I'm using an artisan command to generate docs:

    public function handle(Generator $openApiService): void
        $paths = [app()->basePath('app')];
        $options = ['validate' => !((PHP_OS_FAMILY === 'Linux'))]; // ???
        $docs = $openApiService::scan($paths, $options);
        Storage::disk('root')->put($this->file, $docs->toYaml());
        $this->info('./' . $this->file . ' was generated.');

    This works fine on Windows, but when Jenkins runs my unit test it fails with the following error:

    ErrorException: Required @OA\PathItem() not found

    I've narrowed this down to src/Annotations/AbstractAnnotation.php around line 469:

    if ($this instanceof OpenApi) {
        $message = 'Required ' . Util::shorten($class) . '() not found';

    If I print $this->_context it shows the placeholder files like the one above.

    Required @OA\PathItem() not found /root/Projects/app/Specs/OpenApiSpec.php on line 88

    The documentation gives an example of doing this, why does this work on Windows and not Linux? It seems it's validating per file instead of across the entire project as I do have paths defined in controllers. Setting validate to false does generate a valid openapi.yaml I've checked the schema in SwaggerHub. On Windows it runs fine via artisan or the CLI with validate=true.

    Reviewed by monsterlane at 2022-06-16 20:44
  • 16. Conflict between Symfony, `swagger-php`, and NelmioApiDocBundle?

    I'm not sure this is a bug, but I've been searching for hours and haven't found anything to resolve a conflict I'm seeing. In short: I can't seem to document multiple routes such that they are accepted by both Symfony and swagger-php, and viewable by NelmioApiDocBundle.

    Here's what I'm trying to do:

    public function myFunction(?int $var1, ?string $var2 = ""): Response

    $var2 is optional, so I have the following Symfony routing annotations:

     * @Route("/endpoint/{var1}/extra", name="var_1", methods={"POST"})
     * @Route("/endpoint/{var1}/extra/{var2}", name="var_2", methods={"POST"})

    And to document it for Swagger, I have (reduced to only the things that cause trouble):

     * @OA\Post(
     *     path="/endpoint/{var1}/extra",
     *     operationId="var_1",
     *     tags={"My Tag"}
     * ),
     * @OA\Post(
     *     path="/endpoint/{var1}/extra{var2}",
     *     operationId="var_2",
     *     tags={"My Tag"}
     * )

    The problem is this:

    • When I include both the @Route and the path, NelmioApiDocBundle ignores the tags, and combines the two endpoints into one. It also seems to take some combination of the values... for example if only one is deprecated, the single endpoint that's viewable will be deprecated, even if the actual path being shown is not the path that was deprecated. Regardless, the upshot is that the human-viewable docs are incorrect because instead of 2 endpoints, only one is visible... and it's in the "Default" tag group instead of where it should be.

    • When I remove the @Route and keep the path, as you would expect, Symfony no longer recognizes the route and calls fail. Nothing is visible in NelmioApiDocBundle's view.

    • When I remove the path and keep the @Route, the API calls work but I get a stack of warning from swagger-php:

      • User Warning: Multiple definitions for @OA\Post()->operationId
      • User Warning: Multiple definitions for @OA\Post()->parameters
      • User Warning: Multiple definitions for @OA\Post()->responses
      • User Warning: operationId must be unique. Duplicate value found: "var_1"

    Note that the warnings about the duplicate operationId values are seen even though the values are unique through the entire API.

    I've got to be missing something here... can anyone tell me what? Thanks!

    Reviewed by copiri-six at 2022-06-14 21:37 is an documentation generator that uses a simple folder structure and Markdown files to create custom documentation on the fly. It helps you create great looking documentation in a developer friendly way. is a documentation generator that uses a simple folder structure and Markdown files to create custom documentation on the fly. It help

Jun 29, 2022
Generates documentation for your REST API from annotations

NelmioApiDocBundle The NelmioApiDocBundle bundle allows you to generate a decent documentation for your APIs. Migrate from 3.x to 4.0 To migrate from

Jun 24, 2022
Yii2 Annotations Generate API Document Extension
 Yii2 Annotations Generate API Document Extension

Generate online api document by code annotation for yii2 easily

Dec 15, 2021
phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to generate a complete set of API Documentation

phpDocumentor What is phpDocumentor? phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to genera

Jul 3, 2022
Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and / or RESTful API

Luracast Restler ![Gitter]( Chat.svg) Version 3.0 Release Candidate 5 Restler is a simple and effective multi-format Web

Jun 28, 2022
Industrial-strength annotations for PHP

php-annotations Source-code annotations for PHP. Copyright (C) 2011-2015 Rasmus Schultz [email protected]

Mar 30, 2022
Documentation generator for PHP Code using standard technology (SRC, DOCBLOCK, XML and XSLT)

phpDox phpDox is a documentation generator for PHP projects. This includes, but is not limited to, API documentation. The main focus is on enriching t

Jun 20, 2022
An API documentation generator

Sami: an API documentation generator WARNING: Sami is not supported nor maintained anymore. Feel free to fork. Curious about what Sami generates? Have

Jun 20, 2022
A php API documentation generator, fork of Sami

Doctum, a PHP API documentation generator. Fork of Sami Curious about what Doctum generates? Have a look at the MariaDB MySQL Kbs or Laravel documenta

Jun 24, 2022
Sami: an API documentation generator

Sami: an API documentation generator WARNING: Sami is not supported nor maintained anymore. Feel free to fork. Curious about what Sami generates? Have

Jun 20, 2022
PHP 7.1 ready Smart and Simple Documentation for your PHP project
PHP 7.1 ready Smart and Simple Documentation for your PHP project

Smart and Readable Documentation for your PHP project ApiGen is the simplest, the easiest to use and the most modern api doc generator. It is all PHP

Jun 6, 2022
PHP 7.1 ready Smart and Simple Documentation for your PHP project
PHP 7.1 ready Smart and Simple Documentation for your PHP project

Smart and Readable Documentation for your PHP project ApiGen is the simplest, the easiest to use and the most modern api doc generator. It is all PHP

Apr 20, 2021
Documentation Generator for PHP

phpDocumentor What is phpDocumentor? phpDocumentor is an application that is capable of analyzing your PHP source code and DocBlock comments to genera

Jun 28, 2022
Documentation Generator for WordPress.

Pronamic WordPress Documentor is a tool to automatically extract data about the actions and filters of your WordPress theme or plugin.

May 2, 2022
A PHP framework foucs on API fast development.接口,从简单开始!PhalApi简称π框架,一个轻量级PHP开源接口框架,专注于接口服务开发。
A PHP framework foucs on API fast development.接口,从简单开始!PhalApi简称π框架,一个轻量级PHP开源接口框架,专注于接口服务开发。

PhalApi开源接口框架 / PhalApi API Framework 读音:派框架 Stargazers over time 开发文档 / Documents 专为PHPer准备的优雅而详细的开发文档,请看:PhalApi 2.x 开发文档。 PhalApi 2.x English Docs.

Jun 28, 2022
FluxBB is a fast, light, user-friendly forum application for your website.

FluxBB 1.5 Readme About FluxBB is an open source forum application released under the GNU General Public Licence. It is free to download and use and w

Jun 27, 2022
30 seconds of code Short PHP code snippets for all your development needs
30 seconds of code Short PHP code snippets for all your development needs

30 seconds of code Short PHP code snippets for all your development needs Visit our website to view our snippet collection. Use the Search page to fin

Jun 19, 2022
Ladumor Laravel Swagger help to setup swagger in your application easily
Ladumor Laravel Swagger  help to setup swagger in your application easily

Laravel Swagger Installation Install the package by the following command, composer require ladumor/laravel-swagger Add Provider Add the provider to

Jun 17, 2022
Learn how to implement the most important Design Patterns into your PHP application, uses PHP 8.1
Learn how to implement the most important Design Patterns into your PHP application, uses PHP 8.1

Learn how to implement the most important Design Patterns into your PHP application. This project uses PHP 8.1. it has examples for each Pattern and an Article explaining how to use them step by step, their advantages, and disadvantages.

Jun 24, 2022