Signal: Generate PHP Docs From Native Attributes | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Composer Pacakge](https://www.msaied.com/public/articles?category=composer-pacakge)
6. /
7. Turn PHP Attributes Into Docs With Signal

   [Composer Pacakge](https://www.msaied.com/public/articles?category=composer-pacakge) [PHP](https://www.msaied.com/public/articles?category=php) 

 Turn PHP Attributes Into Docs With Signal
==========================================

 Signal is a PHP 8.5 library by Steve McDougall that reads native attributes on your classes and methods and generates Markdown and JSON documentation from them — keeping API references in sync with your code.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 26 Jun 2026 · Updated 26 Jun 2026 · 3 min read

ShareCopy linkCopied

 ![Turn PHP Attributes Into Docs With Signal](https://cdn.msaied.com/300/6d30cd7b1adb545febfc5d4050778760.png) 

  On this page +1. [What Is Signal?](#what-is-signal)
2. [Three Groups of Attributes](#three-groups-of-attributes)
3. [1. Labelling What a Class Is](#1-labelling-what-a-class-is)
4. [2. Recording Relationships and Status](#2-recording-relationships-and-status)
5. [3. Documenting Methods](#3-documenting-methods)
6. [Configuration and Output](#configuration-and-output)
7. [Installation](#installation)
8. [Key Takeaways](#key-takeaways)

 What Is Signal?
---------------

[Signal](https://github.com/JustSteveKing/signal) is an open-source PHP library by Steve McDougall that turns native PHP 8.x attributes into living documentation. Instead of maintaining a separate wiki or API reference that drifts out of date, you annotate your classes and methods directly, run one CLI command, and get back Markdown for humans and JSON for tooling. It requires **PHP 8.5** and Symfony Console, and is distributed under the MIT license.

Three Groups of Attributes
--------------------------

Signal ships **24 attributes** organised into three logical groups.

### 1. Labelling What a Class Is

Thirteen attributes describe the architectural role of a class: `#[Module]`, `#[Service]`, `#[Repository]`, `#[Action]`, `#[Controller]`, `#[Event]`, `#[Listener]`, `#[Middleware]`, `#[Job]`, `#[Command]`, `#[Query]`, `#[Aggregate]`, and `#[ValueObject]`. Each accepts an optional `description` and a `tags` array.

```php
use JustSteveKing\Signal\Attributes\Service;

#[Service(
    description: 'Issues and revokes API tokens for authenticated users',
    tags: ['auth', 'tokens'],
)]
final class TokenService
{
    // ...
}

```

The generator groups output by these types, so every controller lands in one section and every service in another.

### 2. Recording Relationships and Status

A second group documents how a class connects to the rest of the system. `#[DependsOn]` records a collaborator, `#[ListensTo]` ties a listener to an event, and `#[Deprecated]` / `#[Internal]` flag classes that callers should treat with care.

```php
#[Listener(description: 'Sends a welcome email after registration')]
#[ListensTo(event: UserRegistered::class)]
#[DependsOn(class: MailService::class)]
final class SendWelcomeEmail
{
    // ...
}

```

This is the kind of relationship detail that usually lives only in someone's head or in a diagram nobody updates.

### 3. Documenting Methods

The third group targets individual methods. `#[Route]` records an HTTP method and path, `#[Authorize]` notes the required ability, `#[Validates]` captures field-level rules, and `#[Cached]` records a TTL. Three more attributes surface behaviour invisible in a method signature: `#[Emits]` for dispatched events, `#[Throws]` for exceptions, and `#[SideEffect]` for observable work like charging a card or writing to a queue.

```php
#[Route(method: 'POST', path: '/api/subscriptions', description: 'Start a subscription')]
#[Authorize(ability: 'subscriptions.create')]
#[Validates(field: 'plan', rules: 'required|in:monthly,yearly')]
#[Emits(event: 'SubscriptionStarted')]
#[SideEffect(description: 'Charges the customer through the payment gateway', tags: ['billing'])]
#[Throws(exception: PaymentFailedException::class, description: 'If the gateway rejects the charge')]
public function store(Request $request): JsonResponse
{
    // ...
}

```

`#[SideEffect]` and `#[Throws]` are particularly valuable — they document facts a return type alone cannot convey.

Configuration and Output
------------------------

Signal reads a `signal.json` file at the project root:

```json
{
    "input": "src/",
    "output": {
        "format": ["markdown", "json"],
        "path": "docs/"
    },
    "exclude": [
        "src/Attributes/"
    ]
}

```

Then generate your docs with a single command:

```bash
php vendor/bin/signal generate

```

The Markdown output includes a table of contents organised by class type. The JSON output carries the same metadata in a machine-readable form, making it a useful starting point for generating OpenAPI descriptions or feeding an internal service catalogue.

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

```bash
composer require juststeveking/signal

```

Key Takeaways
-------------

- Signal uses **native PHP attributes** — no docblock parsing, no external annotation syntax.
- **24 attributes** cover class roles, inter-class relationships, and method-level behaviour.
- Outputs both **Markdown** (human-readable) and **JSON** (machine-readable) from one command.
- Keeping docs next to code means they update when the code updates, reducing documentation drift.
- Requires PHP 8.5 and Symfony Console; MIT licensed.
- The JSON output can seed OpenAPI specs or internal service catalogues.

---

Source: [Turn PHP Attributes Into Docs With Signal — Laravel News](https://laravel-news.com/turn-php-attributes-into-docs-with-signal)

- [PHP](https://www.msaied.com/public/articles?search=PHP)
- [PHP Attributes](https://www.msaied.com/public/articles?search=PHP%20Attributes)
- [Documentation](https://www.msaied.com/public/articles?search=Documentation)
- [Laravel Packages](https://www.msaied.com/public/articles?search=Laravel%20Packages)
- [Open Source](https://www.msaied.com/public/articles?search=Open%20Source)
- [Developer Tools](https://www.msaied.com/public/articles?search=Developer%20Tools)

 Frequently asked questions 
---------------------------

  What PHP version does Signal require?Signal requires PHP 8.5 and Symfony Console. It is distributed under the MIT license.

   What output formats does Signal produce?Signal generates both Markdown (organised by class type with a table of contents) and JSON (machine-readable metadata suitable for OpenAPI generation or service catalogues).

   How do you run Signal to generate documentation?After adding a signal.json configuration file to your project root, run `php vendor/bin/signal generate`. Signal scans the configured input directory and writes docs to the configured output path.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleUSAIGE: Track Token Usage and Costs for Laravel AI SDK Requests](https://www.msaied.com/public/articles/usaige-track-token-usage-and-costs-for-laravel-ai-sdk-requests) [Next articleRead/Write Splitting, Connection Pooling, and Sticky Reads in Laravel](https://www.msaied.com/public/articles/readwrite-splitting-connection-pooling-and-sticky-reads-in-laravel-2)  

   On this page
-------------

1. [What Is Signal?](#what-is-signal)
2. [Three Groups of Attributes](#three-groups-of-attributes)
3. [1. Labelling What a Class Is](#1-labelling-what-a-class-is)
4. [2. Recording Relationships and Status](#2-recording-relationships-and-status)
5. [3. Documenting Methods](#3-documenting-methods)
6. [Configuration and Output](#configuration-and-output)
7. [Installation](#installation)
8. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
