1. php
  2. /packages
  3. /documentation

Package Documentation

Introduction to Package Documentation

Good documentation is crucial for package adoption and user success. This guide covers creating comprehensive documentation including API reference, user guides, tutorials, and maintaining documentation consistency.

Documentation Types

API Documentation

Auto-generated reference documentation from code comments using tools like phpDocumentor.

User Guides

Step-by-step instructions for common use cases and getting started.

Tutorials

In-depth examples and walkthroughs for complex scenarios.

Reference Material

Quick lookup guides for functions, classes, and configuration options.

PHPDoc Standards

Basic DocBlock Structure

<?php
/**
 * Brief description of the class
 *
 * Longer description that provides more details about the purpose
 * and usage of this class. Can span multiple lines.
 *
 * @package Vendor\PackageName
 * @version 1.2.0
 * @author Your Name <[email protected]>
 * @copyright 2023 Your Company
 * @license MIT
 * @since 1.0.0
 */
class Calculator
{
    /**
     * Adds two numbers together
     *
     * This method performs basic addition of two numeric values.
     * It supports both integers and floating-point numbers.
     *
     * @param float $a The first number
     * @param float $b The second number
     * @return float The sum of the two numbers
     * @throws InvalidArgumentException When either parameter is not numeric
     * @since 1.0.0
     * @example
     * ```php
     * $calculator = new Calculator();
     * $result = $calculator->add(2.5, 3.7);
     * echo $result; // 6.2
     * ```
     */
    public function add(float $a, float $b): float
    {
        return $a + $b;
    }

    /**
     * Divides one number by another
     *
     * @param float $dividend The number to be divided
     * @param float $divisor The number to divide by
     * @return float The quotient
     * @throws InvalidArgumentException When divisor is zero
     * @throws DivisionByZeroException When attempting division by zero
     * @see Calculator::multiply() For the inverse operation
     * @link https://example.com/docs/calculator For more examples
     * @todo Add support for integer division
     * @deprecated 2.0.0 Use MathCalculator::divide() instead
     */
    public function divide(float $dividend, float $divisor): float
    {
        if ($divisor === 0.0) {
            throw new InvalidArgumentException('Division by zero is not allowed');
        }
        
        return $dividend / $divisor;
    }
}
?>

Advanced DocBlock Features

<?php
/**
 * Configuration manager for the calculator package
 *
 * @package Vendor\PackageName\Config
 */
class Configuration
{
    /**
     * Configuration values
     *
     * @var array<string, mixed>
     */
    private array $config;

    /**
     * Default configuration values
     *
     * @var array{
     *     precision: int,
     *     rounding_mode: int,
     *     cache_enabled: bool,
     *     cache_ttl: int
     * }
     */
    private const DEFAULTS = [
        'precision' => 2,
        'rounding_mode' => PHP_ROUND_HALF_UP,
        'cache_enabled' => true,
        'cache_ttl' => 3600
    ];

    /**
     * Creates a new configuration instance
     *
     * @param array<string, mixed> $config Initial configuration values
     */
    public function __construct(array $config = [])
    {
        $this->config = array_merge(self::DEFAULTS, $config);
    }

    /**
     * Gets a configuration value
     *
     * @template T
     * @param string $key The configuration key
     * @param T $default Default value if key doesn't exist
     * @return T|mixed The configuration value or default
     */
    public function get(string $key, $default = null)
    {
        return $this->config[$key] ?? $default;
    }

    /**
     * Batch update multiple configuration values
     *
     * @param array<string, mixed> $values Key-value pairs to update
     * @return self Returns self for method chaining
     * @fluent
     */
    public function update(array $values): self
    {
        foreach ($values as $key => $value) {
            $this->config[$key] = $value;
        }
        
        return $this;
    }
}

/**
 * Factory for creating calculators
 */
class CalculatorFactory
{
    /**
     * Creates calculator instances
     *
     * @param string $type Calculator type ('basic'|'scientific'|'financial')
     * @param Configuration|null $config Optional configuration
     * @return Calculator|ScientificCalculator|FinancialCalculator
     * @throws InvalidArgumentException For unknown calculator types
     * @psalm-return Calculator
     */
    public static function create(string $type, ?Configuration $config = null)
    {
        switch ($type) {
            case 'basic':
                return new Calculator($config);
            case 'scientific':
                return new ScientificCalculator($config);
            case 'financial':
                return new FinancialCalculator($config);
            default:
                throw new InvalidArgumentException("Unknown calculator type: {$type}");
        }
    }
}
?>

Documentation Generation Tools

phpDocumentor Setup

# Install phpDocumentor
composer require --dev phpdocumentor/phpdocumentor

# Create configuration file
touch phpdoc.xml

phpDocumentor Configuration

<?xml version="1.0" encoding="UTF-8" ?>
<phpdocumentor
    configVersion="3"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://www.phpdoc.org"
    xsi:schemaLocation="https://www.phpdoc.org https://raw.githubusercontent.com/phpDocumentor/phpDocumentor/master/data/xsd/phpdoc.xsd"
>
    <title>Package Name API Documentation</title>
    <description>Comprehensive API documentation for the Package Name library</description>
    
    <paths>
        <output>docs/api</output>
        <cache>build/phpdoc-cache</cache>
    </paths>
    
    <version number="latest">
        <folder>latest</folder>
        <api>
            <source dsn=".">
                <path>src</path>
            </source>
            <output>api</output>
            <ignore>
                <path>src/deprecated</path>
            </ignore>
            <extensions>
                <extension>php</extension>
            </extensions>
            <visibility>public</visibility>
            <default-package-name>Vendor\PackageName</default-package-name>
        </api>
        
        <guide>
            <source dsn=".">
                <path>docs/guides</path>
            </source>
            <output>guides</output>
        </guide>
    </version>
    
    <setting name="graphs.enabled" value="true" />
    <setting name="guides.enabled" value="true" />
</phpdocumentor>

Generate Documentation

# Generate API documentation
vendor/bin/phpdoc run

# Generate with custom template
vendor/bin/phpdoc run --template=responsive-twig

# Watch for changes and regenerate
vendor/bin/phpdoc run --watch

User Guide Structure

README.md Template

# Package Name

[![Latest Version on Packagist](https://img.shields.io/packagist/v/vendor/package-name.svg?style=flat-square)](https://packagist.org/packages/vendor/package-name)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
[![Build Status](https://img.shields.io/github/workflow/status/vendor/package-name/tests/main.svg?style=flat-square)](https://github.com/vendor/package-name/actions)
[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/vendor/package-name.svg?style=flat-square)](https://scrutinizer-ci.com/g/vendor/package-name/code-structure)
[![Quality Score](https://img.shields.io/scrutinizer/g/vendor/package-name.svg?style=flat-square)](https://scrutinizer-ci.com/g/vendor/package-name)
[![Total Downloads](https://img.shields.io/packagist/dt/vendor/package-name.svg?style=flat-square)](https://packagist.org/packages/vendor/package-name)

Brief description of what your package does and why it's useful.

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage](#usage)
- [API Documentation](#api-documentation)
- [Examples](#examples)
- [Testing](#testing)
- [Contributing](#contributing)
- [Security](#security)
- [Changelog](#changelog)
- [License](#license)

## Installation

Install the package via Composer:

```bash
composer require vendor/package-name

Requirements

  • PHP 8.0 or higher
  • ext-json
  • ext-mbstring

Optional Dependencies

  • ext-gd (for image processing features)
  • ext-curl (for HTTP client functionality)

Quick Start

Get up and running in under 5 minutes:

<?php
require_once 'vendor/autoload.php';

use Vendor\PackageName\Calculator;

$calculator = new Calculator();
$result = $calculator->add(2, 3);
echo $result; // 5

Usage

Basic Operations

use Vendor\PackageName\Calculator;

$calculator = new Calculator();

// Basic arithmetic
$sum = $calculator->add(10, 5);        // 15
$difference = $calculator->subtract(10, 5); // 5
$product = $calculator->multiply(10, 5);    // 50
$quotient = $calculator->divide(10, 5);     // 2

Configuration

use Vendor\PackageName\Calculator;
use Vendor\PackageName\Config\Configuration;

$config = new Configuration([
    'precision' => 4,
    'rounding_mode' => PHP_ROUND_HALF_UP
]);

$calculator = new Calculator($config);
$result = $calculator->divide(10, 3); // 3.3333

Advanced Features

use Vendor\PackageName\Math\Operations;

// Mathematical operations
$factorial = Operations::factorial(5);    // 120
$fibonacci = Operations::fibonacci(10);   // 55
$power = Operations::power(2, 8);        // 256

API Documentation

Complete API documentation is available at https://vendor.github.io/package-name.

Core Classes

Examples

Example 1: Simple Calculator

<?php
require_once 'vendor/autoload.php';

use Vendor\PackageName\Calculator;

$calculator = new Calculator();

echo "Addition: " . $calculator->add(5, 3) . "\n";
echo "Subtraction: " . $calculator->subtract(5, 3) . "\n";
echo "Multiplication: " . $calculator->multiply(5, 3) . "\n";
echo "Division: " . $calculator->divide(6, 3) . "\n";

Example 2: Scientific Calculator

<?php
use Vendor\PackageName\CalculatorFactory;
use Vendor\PackageName\Config\Configuration;

$config = new Configuration(['precision' => 6]);
$calculator = CalculatorFactory::create('scientific', $config);

$result = $calculator->logarithm(100, 10); // 2.000000
echo "log₁₀(100) = " . $result . "\n";

Example 3: Error Handling

<?php
use Vendor\PackageName\Calculator;
use Vendor\PackageName\Exceptions\CalculatorException;

$calculator = new Calculator();

try {
    $result = $calculator->divide(10, 0);
} catch (CalculatorException $e) {
    echo "Error: " . $e->getMessage();
}

Testing

Run the test suite:

composer test

Run tests with coverage:

composer test-coverage

Contributing

Please see CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Changelog

Please see CHANGELOG.md for more information about recent changes.

License

The MIT License (MIT). Please see LICENSE.md for more information.


### Comprehensive User Guide

```markdown
# User Guide

This guide provides detailed information on using the Package Name library.

## Table of Contents

1. [Getting Started](#getting-started)
2. [Basic Concepts](#basic-concepts)
3. [Configuration](#configuration)
4. [Common Use Cases](#common-use-cases)
5. [Advanced Topics](#advanced-topics)
6. [Best Practices](#best-practices)
7. [Troubleshooting](#troubleshooting)

## Getting Started

### Installation

Before you begin, ensure you have:
- PHP 8.0 or later
- Composer installed

Install the package:

```bash
composer require vendor/package-name

Your First Calculation

<?php
require 'vendor/autoload.php';

use Vendor\PackageName\Calculator;

// Create a calculator instance
$calculator = new Calculator();

// Perform a simple calculation
$result = $calculator->add(10, 5);
echo "10 + 5 = " . $result; // 10 + 5 = 15

Basic Concepts

Calculator Class

The Calculator class is the main entry point for performing calculations:

$calculator = new Calculator();

Operations

All basic arithmetic operations are supported:

  • Addition: add($a, $b)
  • Subtraction: subtract($a, $b)
  • Multiplication: multiply($a, $b)
  • Division: divide($a, $b)

Error Handling

The library uses exceptions for error handling:

try {
    $result = $calculator->divide(10, 0);
} catch (CalculatorException $e) {
    echo "Error: " . $e->getMessage();
}

Configuration

Basic Configuration

use Vendor\PackageName\Config\Configuration;

$config = new Configuration([
    'precision' => 2,
    'cache_enabled' => true
]);

$calculator = new Calculator($config);

Configuration Options

OptionTypeDefaultDescription
precisionint2Number of decimal places
rounding_modeintPHP_ROUND_HALF_UPRounding mode
cache_enabledbooltrueEnable result caching
cache_ttlint3600Cache time-to-live in seconds

Environment Configuration

Create a .env file for environment-specific settings:

CALCULATOR_PRECISION=4
CALCULATOR_CACHE_ENABLED=true
CALCULATOR_DEBUG=false

Load environment configuration:

$config = Configuration::fromEnvironment();
$calculator = new Calculator($config);

Common Use Cases

Financial Calculations

use Vendor\PackageName\CalculatorFactory;

$calculator = CalculatorFactory::create('financial');

// Calculate compound interest
$principal = 1000;
$rate = 0.05;
$time = 10;
$compoundInterest = $calculator->compoundInterest($principal, $rate, $time);

Scientific Calculations

$scientific = CalculatorFactory::create('scientific');

// Trigonometric functions
$sine = $scientific->sin(M_PI / 2);    // 1
$cosine = $scientific->cos(0);         // 1
$tangent = $scientific->tan(M_PI / 4); // 1

// Logarithmic functions
$naturalLog = $scientific->ln(M_E);    // 1
$log10 = $scientific->log10(100);     // 2

Batch Processing

$numbers = [1, 2, 3, 4, 5];
$results = [];

foreach ($numbers as $number) {
    $results[] = $calculator->multiply($number, 2);
}

// Or use array functions
$doubled = array_map(fn($n) => $calculator->multiply($n, 2), $numbers);

Advanced Topics

Custom Operations

Extend the calculator with custom operations:

class CustomCalculator extends Calculator
{
    public function percentage(float $value, float $percentage): float
    {
        return $this->multiply($value, $this->divide($percentage, 100));
    }
    
    public function average(array $numbers): float
    {
        $sum = array_reduce($numbers, fn($carry, $item) => $this->add($carry, $item), 0);
        return $this->divide($sum, count($numbers));
    }
}

Plugins and Extensions

Load additional functionality through plugins:

use Vendor\PackageName\Plugin\StatisticsPlugin;

$calculator = new Calculator();
$calculator->loadPlugin(new StatisticsPlugin());

// Now statistical functions are available
$mean = $calculator->mean([1, 2, 3, 4, 5]);
$median = $calculator->median([1, 2, 3, 4, 5]);

Caching Results

Enable caching for expensive operations:

$config = new Configuration(['cache_enabled' => true, 'cache_ttl' => 1800]);
$calculator = new Calculator($config);

// First call calculates and caches
$result1 = $calculator->complexOperation($data);

// Second call retrieves from cache
$result2 = $calculator->complexOperation($data); // Much faster

Best Practices

Input Validation

Always validate inputs before performing calculations:

public function safeDivide(float $a, float $b): float
{
    if (!is_finite($a) || !is_finite($b)) {
        throw new InvalidArgumentException('Arguments must be finite numbers');
    }
    
    if ($b === 0.0) {
        throw new DivisionByZeroException('Cannot divide by zero');
    }
    
    return $this->divide($a, $b);
}

Error Handling Strategy

Implement comprehensive error handling:

try {
    $result = $calculator->complexCalculation($data);
} catch (CalculatorException $e) {
    // Log the error
    error_log("Calculation error: " . $e->getMessage());
    
    // Provide fallback value or re-throw
    return 0; // or throw $e;
} catch (Exception $e) {
    // Handle unexpected errors
    error_log("Unexpected error: " . $e->getMessage());
    throw new CalculatorException("Calculation failed", 0, $e);
}

Performance Optimization

Optimize for performance in high-throughput scenarios:

// Reuse calculator instances
$calculator = new Calculator($config);

// Batch operations when possible
$results = $calculator->batchAdd($numbers1, $numbers2);

// Use appropriate precision
$config = new Configuration(['precision' => 2]); // Instead of 10

Troubleshooting

Common Issues

"Class not found" errors

Ensure Composer autoloader is included:

require_once 'vendor/autoload.php';

Precision issues with floating-point numbers

Use the bcmath extension for high-precision calculations:

$config = new Configuration([
    'precision' => 10,
    'use_bcmath' => true
]);

Memory issues with large datasets

Process data in chunks:

$chunks = array_chunk($largeDataset, 1000);
foreach ($chunks as $chunk) {
    $results[] = $calculator->processChunk($chunk);
}

Debug Mode

Enable debug mode for detailed error information:

$config = new Configuration(['debug' => true]);
$calculator = new Calculator($config);

Getting Help


## Code Examples Documentation

### Organized Examples

```php
<?php
// examples/basic-usage.php
/**
 * Basic Usage Examples
 * 
 * This file demonstrates the basic functionality of the Calculator package.
 * Run with: php examples/basic-usage.php
 */

require_once __DIR__ . '/../vendor/autoload.php';

use Vendor\PackageName\Calculator;
use Vendor\PackageName\Config\Configuration;

echo "=== Basic Calculator Examples ===\n\n";

// Example 1: Simple arithmetic
echo "1. Simple Arithmetic\n";
$calculator = new Calculator();

$a = 10;
$b = 5;

echo "Adding {$a} + {$b} = " . $calculator->add($a, $b) . "\n";
echo "Subtracting {$a} - {$b} = " . $calculator->subtract($a, $b) . "\n";
echo "Multiplying {$a} * {$b} = " . $calculator->multiply($a, $b) . "\n";
echo "Dividing {$a} / {$b} = " . $calculator->divide($a, $b) . "\n\n";

// Example 2: Configuration
echo "2. Using Configuration\n";
$config = new Configuration([
    'precision' => 4,
    'rounding_mode' => PHP_ROUND_HALF_UP
]);

$preciseCalculator = new Calculator($config);
$result = $preciseCalculator->divide(22, 7);
echo "π approximation (22/7) with 4 decimal places: {$result}\n\n";

// Example 3: Error handling
echo "3. Error Handling\n";
try {
    $calculator->divide(10, 0);
} catch (Exception $e) {
    echo "Caught exception: " . $e->getMessage() . "\n";
}

echo "\nExample completed successfully!\n";
?>

Interactive Examples

<?php
// examples/interactive-calculator.php
/**
 * Interactive Calculator Example
 * 
 * A simple command-line calculator interface.
 * Run with: php examples/interactive-calculator.php
 */

require_once __DIR__ . '/../vendor/autoload.php';

use Vendor\PackageName\Calculator;
use Vendor\PackageName\Exceptions\CalculatorException;

class InteractiveCalculator
{
    private Calculator $calculator;
    
    public function __construct()
    {
        $this->calculator = new Calculator();
    }
    
    public function run(): void
    {
        echo "Welcome to the Interactive Calculator!\n";
        echo "Type 'help' for commands or 'quit' to exit.\n\n";
        
        while (true) {
            $input = $this->prompt("> ");
            
            if (trim($input) === 'quit') {
                echo "Goodbye!\n";
                break;
            }
            
            if (trim($input) === 'help') {
                $this->showHelp();
                continue;
            }
            
            $this->processInput($input);
        }
    }
    
    private function prompt(string $message): string
    {
        echo $message;
        return trim(fgets(STDIN));
    }
    
    private function showHelp(): void
    {
        echo "Available commands:\n";
        echo "  add <a> <b>      - Add two numbers\n";
        echo "  sub <a> <b>      - Subtract two numbers\n";
        echo "  mul <a> <b>      - Multiply two numbers\n";
        echo "  div <a> <b>      - Divide two numbers\n";
        echo "  help             - Show this help\n";
        echo "  quit             - Exit calculator\n\n";
    }
    
    private function processInput(string $input): void
    {
        $parts = explode(' ', trim($input));
        
        if (count($parts) < 3) {
            echo "Error: Invalid input. Type 'help' for usage.\n";
            return;
        }
        
        [$operation, $a, $b] = $parts;
        
        if (!is_numeric($a) || !is_numeric($b)) {
            echo "Error: Arguments must be numeric.\n";
            return;
        }
        
        $a = (float) $a;
        $b = (float) $b;
        
        try {
            $result = match ($operation) {
                'add' => $this->calculator->add($a, $b),
                'sub' => $this->calculator->subtract($a, $b),
                'mul' => $this->calculator->multiply($a, $b),
                'div' => $this->calculator->divide($a, $b),
                default => throw new InvalidArgumentException("Unknown operation: {$operation}")
            };
            
            echo "Result: {$result}\n";
        } catch (CalculatorException $e) {
            echo "Calculator Error: " . $e->getMessage() . "\n";
        } catch (Exception $e) {
            echo "Error: " . $e->getMessage() . "\n";
        }
    }
}

$calculator = new InteractiveCalculator();
$calculator->run();
?>

Documentation Automation

GitHub Actions for Documentation

# .github/workflows/docs.yml
name: Documentation

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  generate-docs:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v3
      
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: 8.1
        extensions: dom, curl, libxml, mbstring, zip
        
    - name: Install dependencies
      run: composer install --no-dev --optimize-autoloader
      
    - name: Generate API documentation
      run: vendor/bin/phpdoc run
      
    - name: Deploy to GitHub Pages
      if: github.ref == 'refs/heads/main'
      uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./docs/api
        publish_branch: gh-pages

Documentation Validation

<?php
// scripts/validate-docs.php
/**
 * Documentation validation script
 * Ensures all public methods have proper documentation
 */

class DocumentationValidator
{
    private array $errors = [];
    
    public function validateDirectory(string $path): bool
    {
        $files = glob($path . '/*.php');
        
        foreach ($files as $file) {
            $this->validateFile($file);
        }
        
        return empty($this->errors);
    }
    
    private function validateFile(string $file): void
    {
        $content = file_get_contents($file);
        $tokens = token_get_all($content);
        
        for ($i = 0; $i < count($tokens); $i++) {
            if ($this->isPublicMethod($tokens, $i)) {
                $methodName = $this->getMethodName($tokens, $i);
                
                if (!$this->hasDocBlock($tokens, $i)) {
                    $this->errors[] = "Missing DocBlock for method {$methodName} in {$file}";
                }
            }
        }
    }
    
    private function isPublicMethod(array $tokens, int $index): bool
    {
        // Look for 'public function' pattern
        return isset($tokens[$index]) && 
               is_array($tokens[$index]) && 
               $tokens[$index][0] === T_PUBLIC &&
               isset($tokens[$index + 2]) &&
               is_array($tokens[$index + 2]) &&
               $tokens[$index + 2][0] === T_FUNCTION;
    }
    
    private function getMethodName(array $tokens, int $index): string
    {
        // Find method name after 'function' keyword
        for ($i = $index; $i < count($tokens); $i++) {
            if (is_array($tokens[$i]) && $tokens[$i][0] === T_STRING) {
                return $tokens[$i][1];
            }
        }
        
        return 'unknown';
    }
    
    private function hasDocBlock(array $tokens, int $index): bool
    {
        // Look backwards for DocBlock comment
        for ($i = $index - 1; $i >= 0; $i--) {
            if (is_array($tokens[$i]) && $tokens[$i][0] === T_DOC_COMMENT) {
                return true;
            }
            
            // Stop at previous method or class
            if (is_array($tokens[$i]) && 
                in_array($tokens[$i][0], [T_FUNCTION, T_CLASS, T_INTERFACE, T_TRAIT])) {
                break;
            }
        }
        
        return false;
    }
    
    public function getErrors(): array
    {
        return $this->errors;
    }
}

$validator = new DocumentationValidator();
$isValid = $validator->validateDirectory('src');

if (!$isValid) {
    echo "Documentation validation failed:\n";
    foreach ($validator->getErrors() as $error) {
        echo "- {$error}\n";
    }
    exit(1);
}

echo "Documentation validation passed!\n";
?>

Comprehensive documentation is essential for package adoption and maintainability. It serves as both a reference for users and a guide for contributors, ensuring your package can be effectively used and maintained over time.