zircote/swagger-php
swagger-php generates OpenAPI 3.0/3.1/3.2 documentation from your PHP 8.2+ code using attributes (preferred) or optional Doctrine annotations. Use it via CLI or programmatically, with helpful error reporting and a full documentation site.
[@OA](https://github.com/OA)\Info() not foundWith adding support for PHP attributes in version 4, some architectural changes had to be made.
One of those changes is that placing annotations in your source files is now subject to the same limitations as attributes. These limits are dictated by the PHP reflection API, specifically where it provides access to attributes and doc comments.
This means stand-alone annotations are no longer supported and ignored as swagger-php cannot "see" them anymore.
Supported locations:
Most commonly this manifests with a warning about the required [@OA](https://github.com/OA)\Info not being found. While most annotations have specific
related code, the info annotation (and a few more) is kind of global.
The simplest solution to avoid this issue is to add a 'dummy' class to the docblock and add
all 'global' annotations (e.g. OA\Tag, OA\Server, OA\SecurityScheme, etc.) in a single docblock to that class.
<<< @/snippets/guide/faq/dummy_class_at.php
<<< @/snippets/guide/faq/dummy_class_an.php
As of version 4.8 the doctrine/annotations library is optional and might cause the same message.
If this is the case, doctrine annotations must be installed separately:
composer require doctrine/annotations
Another side effect of using reflection is that swagger-php "can't see" multiple consecutive docblocks anymore as the PHP reflection API only provides access to the docblock closest to a given structural element.
class Controller
{
/**
* [@OA](https://github.com/OA)\Delete(
* path="/api/v0.0.2/notifications/{id}",
* operationId="deleteNotificationById",
* summary="Delete notification by ID",
* [@OA](https://github.com/OA)\Parameter(name="id", in="path", [@OA](https://github.com/OA)\Schema(type="integer")),
* [@OA](https://github.com/OA)\Response(response=200, description="OK"),
* [@OA](https://github.com/OA)\Response(response=400, description="Bad Request")
* )
*/
/**
* Delete notification by ID.
*
* [@param](https://github.com/param) Request $request
* [@param](https://github.com/param) AppNotification $notification
*
* [@return](https://github.com/return) Response
* [@throws](https://github.com/throws) Exception
*/
public function destroy(Request $request, AppNotification $notification) {
//
}
}
In this case the simplest solution is to merge both docblocks. As an additional benefit, the duplication of the summary can be avoided.
In this improved version swagger-php will automatically use the docblock summary just as explicitly done above.
class Controller
{
/**
* Delete notification by ID.
*
* [@OA](https://github.com/OA)\Delete(
* path="/api/v0.0.2/notifications/{id}",
* operationId="deleteNotificationById",
* [@OA](https://github.com/OA)\Parameter(name="id", in="path", [@OA](https://github.com/OA)\Schema(type="integer")),
* [@OA](https://github.com/OA)\Response(response=200, description="OK"),
* [@OA](https://github.com/OA)\Response(response=400, description="Bad Request")
* )
*
* [@param](https://github.com/param) Request $request
* [@param](https://github.com/param) AppNotification $notification
*
* [@return](https://github.com/return) Response
* [@throws](https://github.com/throws) Exception
*/
public function destroy(Request $request, AppNotification $notification) {
//
}
}
Resulting spec:
openapi: 3.0.0
paths:
'/api/v0.0.2/notifications/{id}':
delete:
summary: 'XDelete notification by ID.'
operationId: deleteNotificationById
parameters:
-
name: id
in: path
schema:
type: integer
responses:
'200':
description: OK
'400':
description: 'Bad Request'
\SomeClassThis message means that swagger-php has tried to use reflection to inspect \SomeClass and that PHP could not find/load
that class. Effectively, this means that class_exists("\SomeClass") returns false.
-b --bootstrap optionThere are a number of reasons why this could happen. If you are using the openapi command line tool from a global
installation typically the application classloader (composer) is not active.
With you application root being myapp you could try:
openapi -b myapp/vendor/autoload.php myapp/src
The -b allows to execute some extra PHP code to load whatever is needed to register your apps classloader with PHP.
::: warning One common case for this type of error is when trying out annotations in a standalone single file. Typically, this means it will not use namespaces or confirm to any other autoloading standards.
In this case the -b option can also be used to autoload the actual file.
Please note that you still need to provide the file (or its folder) as the target.
openapi -b src/test.php src/test.php
:::
Another reason for this error could be that your class actually has the wrong namespace (or no namespace at all!).
Depending on your framework, this might still work in the context of your app, but the composer autoloader alone might not be able to load your class (assuming you are using composer).
openapi command line toolDepending on your PHP configuration, running the openapi command line tool might result in no output at all.
The reason for this is that openapi currently uses the error_log
function for all output.
So if this is configured to write to a file, then it will seem like the command is broken.
How can I help you explore Laravel packages today?