How To Add Swagger-UI to PHP Server Code

Tatiana Ensslin
Jul 26 · 5 min read

Swagger is a tool that allows you to use annotations to generate stellar API documentation from existing code or create manully. Recently, Swagger was renamed to OpenAPI. The documentation isn’t exactly as straightforward as I would have liked for PHP, and because of that I decided I would make a comprehensive walkthrough myself.

Here are the steps you can expect to follow in order to install swagger to your PHP server code.

  1. Download Swagger-Php Using Composer
  2. Add Annotations to Generate Documentation
  3. Generate Swagger JSON File
  4. Download Swagger-UI Package to your Project
  5. Connect Swagger-UI To Your Code

Great — let’s begin! (:

A Brief Introduction to the Process

Firstly, all Swagger UI’s require a .json file where the API specifications written in OpenAPI lie. This .json file’s path is configured inside the Swagger-UI’s index.html. The index.html file requires Swagger package code to be fetched from NPM in order for it to render. A browser will render the code together, creating your SwaggerUI!

Step 1: Installing Swagger Generator Tool

In order to use annotations to generate your OpenAPI specs, you need to install swagger.phar. Create a new repository in your file system to install swagger.phar to. The package includes example files — so if you install this package into your project directory than the examples will generate alongside your code — no bueno!

mkdir swagger-generator
cd swagger-generator
composer require zircote/swagger-php

These commands should generate the following file, along with a composer.lock:

"require": {
"zircote/swagger-php": "^3.0"

You can confirm the package is there by looking into your ./vendor folder!

Sweet! Now we can start using annotations to generate our swagger.json file!

Step 2: Add OpenAPI Annotations or Create the File By Hand

Generating a swagger.yaml file via the swagger.phar tool is convenient for object oriented code, however, not all code is object oriented! If your code is OO by design then generating documentation should be relatively painless. However, because PHP is a scripting language, it isn’t required to be OO, and it might be easier for you to write out the .yaml file by hand if your code base is small.

If you plan to use annotations, OpenAPI is based off of doctrine/annotations. If it’s not already installed, go ahead and use composer!

cd php-project
composer require doctrine/annotations

Next, add a title annotation to the top of your app.php file. This will be the top of the Swagger-UI. You can also set up your server base url’s here for wherever you want the test API commands to be sent:

* @OA\Info(title="Search API", version="1.0.0")

After giving your service a title for Swagger, you can start outfitting your services with annotations. I’ll show a simple POST example below:

* @OA\Post(
* path="/search",
* summary="Returns most accurate search result object",
* description="Search for an object, if found return it!",
* @OA\RequestBody(
* description="Client side search object",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/SearchObject")
* )
* ),
* @OA\Response(
* response=200,
* description="Success",
* @OA\Schema(ref="#/components/schemas/SearchResultObject)
* ),
* @OA\Response(
* response=404,
* description="Could Not Find Resource"
* )
* )

Make sure that you add the include statement on all pages with annotations!

use OpenApi\Annotations as OA;

Step 3: Generate your swagger.json (or swagger.yaml)!

Change directory’s back to your swagger-generator and cd into the bin:

cd /path/to/swagger-generator
cd ./vendor/zircote/swagger-php/bin

Run the following command to generate your .json file! The first path is your project path and the second path is wherever you want to generate the file.

./openapi path/to/project -o path/to/project/swagger.json

Thats it! You should have your generated swagger.json file!

If you didn’t us annotations, don’t fret. I’ve written a complete openapi spec here in yaml for you to see — you can always use a yaml to json converting tool and save the file to a location in your project.

swagger.yamlopenapi: 3.0.0
title: 'Search API'
version: 1.0.0
- url:
description: Stage server
- url:
description: Prod server
summary: 'Returns most accurate search result object'
description: 'Search for an object, if found return it!'
description: 'Client side search object'
required: true
$ref: '#/components/schemas/ClientSearchObject'
description: Success
description: Resource Not Found
type: object
- typeName
type: string
type: string

Step 4. Download SwaggerUI to your Project

Download the source code from Github here into its own project and move the dist directory into your project and create a web directory at the same level as your src:

git clone
cd swagger-ui
mv ./dist /path/to/your/project/public/web/

Since PHP doesn’t use NPM package manager, I struggled a lot to get the UI up and running. In order to ensure that your packages download correctly, I recommend using UNPKG .. Here’s an example. I’ve bolded the important script tag that installs the Swagger-UI-bundle code:

index.html<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="/web/swagger-ui.css" >
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
box-sizing: inherit;

background: #fafafa;

<div id="swagger-ui"></div>
<script src=""></script>
<script src=""></script>

window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: window.location.protocol + "//" + window.location.hostname + "/path-to-your-swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
layout: "StandaloneLayout"
// End Swagger UI call region
window.ui = ui

Once you have all these installed, you can set a path in your web server (In my case NGINX) to send all /swagger traffic to your index.html! This will in turn call the other files in the .dist folder to render statically.

If you don’t want to use NGINX or your web server, you can set up routes in your app that will render the content of the files when hit. You will need a path to render the /swagger.json, a path for all the /dist/ files, and a path to hit /swagger with!

Yay! That’s it! Good work!

Like What You’re Reading?

Awesome! Glad to hear that! Clap 1, 2, or 50 times for this article so that it can help reach others! While you’re at it, follow me on Twitter @tensslin, or here on medium to see my future posts. Thanks!

Tatiana Ensslin

Written by

Loves blockchain engineering, copious amounts of coffee, metacognitive conversations & dancing to Berlin techno. Software Engineer @Trulia

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade