Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpdoc Md Laravel Package

ostico/phpdoc-md

Generate Markdown documentation from PHPDoc comments in your PHP project. phpdoc-md scans classes, methods, and annotations to build readable docs you can publish or include in repos. Useful for keeping API docs in sync with code.

Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require ostico/phpdoc-md
    

    Add to composer.json if not auto-discovered:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Ostico\\PhpdocMd\\": "vendor/ostico/phpdoc-md/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case Generate Markdown from a single class file:

    use Ostico\PhpdocMd\PhpdocMd;
    
    $phpdocMd = new PhpdocMd();
    $markdown = $phpdocMd->generateFromFile(__DIR__ . '/path/to/YourClass.php');
    file_put_contents('output.md', $markdown);
    
  3. Where to Look First

    • src/PhpdocMd.php: Core class with generateFromFile(), generateFromString(), and generateFromDocBlock() methods.
    • tests/: Example usage and edge cases (e.g., handling @property, @method).
    • README.md (if exists): Basic CLI usage (if provided).

Implementation Patterns

Workflows

  1. Documentation Generation Pipeline Integrate into Laravel’s post-update-cmd or a custom Artisan command:

    // app/Console/Commands/GenerateDocs.php
    use Ostico\PhpdocMd\PhpdocMd;
    
    class GenerateDocs extends Command {
        protected $signature = 'docs:generate';
        protected $description = 'Generate Markdown docs for all classes';
    
        public function handle() {
            $phpdocMd = new PhpdocMd();
            $classes = $this->getClassesToDocument(); // Implement logic to scan app/
            foreach ($classes as $class) {
                $markdown = $phpdocMd->generateFromFile($class);
                $this->saveMarkdown($markdown, $class);
            }
        }
    }
    
  2. Dynamic API Documentation Use middleware to inject Markdown docs into API responses:

    // app/Http/Middleware/DocumentationMiddleware.php
    public function handle($request, Closure $next) {
        if ($request->expectsJson() && $request->has('doc')) {
            $controller = $request->route()->getController();
            $phpdocMd = new PhpdocMd();
            $markdown = $phpdocMd->generateFromFile($controller);
            return response()->json(['doc' => $markdown]);
        }
        return $next($request);
    }
    
  3. Laravel IDE Helper Integration Generate Markdown for IDE helpers (e.g., app/Helpers.php) and embed in phpstorm.meta.php:

    $markdown = $phpdocMd->generateFromFile(app_path('Helpers.php'));
    // Parse Markdown into PHP array for IDE hints
    

Integration Tips

  • Custom Templates: Extend PhpdocMd to modify output structure (e.g., add Laravel-specific tags like @route):
    class LaravelPhpdocMd extends PhpdocMd {
        protected function parseTag(string $tag): string {
            if ($tag === '@route') return $this->formatRouteTag($tag);
            return parent::parseTag($tag);
        }
    }
    
  • Caching: Cache generated Markdown to avoid reprocessing:
    $cacheKey = 'docs_' . md5($filePath);
    $markdown = Cache::remember($cacheKey, now()->addHours(1), function() use ($phpdocMd, $filePath) {
        return $phpdocMd->generateFromFile($filePath);
    });
    
  • Git Hooks: Auto-generate docs on pre-commit for critical files:
    # .git/hooks/pre-commit
    php artisan docs:generate --files=app/Http/Controllers/
    

Gotchas and Tips

Pitfalls

  1. DocBlock Parsing Quirks

    • Nested DocBlocks: The parser may fail on malformed or nested docblocks (e.g., @property-read mixed $foo inside @method). Fix: Validate docblocks with phpDocumentor or roave/security-advisories before processing.
    • Unsupported Tags: Tags like @inheritDoc or @mixin may not render as expected. Workaround: Pre-process docblocks to expand @inheritDoc or map custom tags.
  2. Performance

    • Large Codebases: Generating docs for 1000+ files can be slow. Use parallel PHP extensions or queue jobs:
      foreach ($classes as $class) {
          GenerateDocJob::dispatch($class)->onQueue('docs');
      }
      
    • Memory Limits: Increase memory_limit if processing monolithic files (e.g., vendor/autoload.php).
  3. Edge Cases

    • Anonymous Classes: generateFromString() may fail on anonymous classes without proper docblocks. Tip: Skip or mock docblocks for anonymous classes.
    • PHP 8 Attributes: The package doesn’t parse [Attribute] syntax. Use @attribute tags manually or pre-process with nikic/php-parser.

Debugging

  • Enable Verbose Output:
    $phpdocMd = new PhpdocMd(['verbose' => true]);
    
  • Check Raw DocBlocks: Use ReflectionClass to inspect docblocks before processing:
    $reflection = new ReflectionClass($class);
    var_dump($reflection->getDocComment());
    
  • Test with Minimal Input: Start with a single, well-documented class to isolate issues:
    /**
     * @property string $name
     * @method void setName(string $name)
     */
    class Test {}
    

Extension Points

  1. Custom Tag Handlers Override parseTag() to handle Laravel-specific annotations:

    protected function parseTag(string $tag): string {
        if (str_starts_with($tag, '@route')) {
            return $this->formatLaravelRouteTag($tag);
        }
        return parent::parseTag($tag);
    }
    
  2. Output Formatting Extend render() to add Laravel-specific sections (e.g., @middleware, @route):

    protected function render(array $docBlock): string {
        $output = parent::render($docBlock);
        if (isset($docBlock['@route'])) {
            $output .= "\n\n## Routes\n```\n" . $docBlock['@route'] . "\n```";
        }
        return $output;
    }
    
  3. CLI Integration Add a custom Artisan command for ad-hoc generation:

    // app/Console/Commands/GenerateDocCommand.php
    protected $signature = 'docs:generate {--file= : Path to file} {--output= : Output path}';
    protected function handle() {
        $phpdocMd = new PhpdocMd();
        $markdown = $phpdocMd->generateFromFile($this->option('file'));
        file_put_contents($this->option('output'), $markdown);
    }
    

Config Quirks

  • Default Options: The constructor accepts an array of options:
    $phpdocMd = new PhpdocMd([
        'strip_comments' => true,  // Remove non-docblock comments
        'sort_tags' => true,       // Alphabetize tags
        'template' => 'custom.tpl' // Custom template path
    ]);
    
  • Template System: If using custom templates, ensure they follow the package’s expected structure (check tests/ for examples).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib