承接 zvonchuk/phalcon-openapi 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

zvonchuk/phalcon-openapi

最新稳定版本:v1.0.0

Composer 安装命令:

composer require zvonchuk/phalcon-openapi

包简介

Automatic OpenAPI 3.1 spec generation for Phalcon PHP — zero annotations, convention-based inference

README 文档

README

Tests Latest Stable Version PHP Version License PHPStan

Automatic OpenAPI 3.1 spec generation for Phalcon PHP applications.

Generates a complete OpenAPI spec by reading your routes, controllers, models, and DTOs — no annotations, no YAML, no manual work. Just write your code and get Swagger UI for free.

Why This Package

Annotation-based approach phalcon-openapi
Routes Duplicated in annotations Read from Phalcon Router automatically
Schemas Separate schema definitions Built from your existing DTOs and Models
Validation Documentation only Same attributes for docs AND runtime
Status codes Manual per-endpoint Convention-based (201, 204, 422, 404)
Setup Custom controller + HTML Two lines of code

Requirements

  • PHP 8.1+
  • Phalcon 5.x

Installation

composer require zvonchuk/phalcon-openapi

Quick Start

use PhalconOpenApi\OpenApiModule;

$module = new OpenApiModule([
    'title'   => 'My API',
    'version' => '1.0.0',
]);
$module->registerServices($di);

Two endpoints are registered automatically:

  • GET /api/openapi.json — OpenAPI 3.1 JSON spec
  • GET /api/docs — Swagger UI

How It Works

The package automatically reads:

  • Router — all registered routes, HTTP methods, path patterns
  • Model MetaData — column types, nullable, primary keys
  • Reflection — controller action parameters, return types, docblocks
  • PHP 8 Attributes — optional tags, hidden endpoints, extra responses, security

Convention-Based Inference

Zero annotations needed for standard CRUD:

class UserController extends ApiController
{
    // GET /users → 200 with array of User, operationId: listUsers
    public function listAction(int $page = 1, int $limit = 20) { }

    // POST /users → 201 Created + 422 Validation Error, operationId: createUser
    public function createAction(CreateUserRequest $body) { }

    // GET /users/{id} → 200 + 404 Not Found, operationId: getUser
    public function getAction(int $id) { }

    // DELETE /users/{id} → 204 No Content + 404, operationId: deleteUser
    public function deleteAction(int $id) { }
}

The spec generator infers:

  • Status codes: create → 201, delete → 204, others → 200
  • 422 Validation Error: auto-added when endpoint has a DTO body parameter
  • 404 Not Found: auto-added when route has path parameters
  • operationId: generated from controller + action name
  • Tags: from controller name (UserControllerUsers)
  • Schemas: from Phalcon Model metadata or DTO class properties

Attributes Reference

All attributes are optional — use only when conventions aren't enough.

Endpoint Attributes

use PhalconOpenApi\Attribute\{ApiTag, ApiIgnore, ApiResponse, ApiDescription, ApiSecurity, ApiPaginated};

#[ApiTag('Users')]              // Group endpoints (class or method level)
#[ApiSecurity('bearerAuth')]    // Require auth (class or method level)
class UserController extends ApiController
{
    #[ApiDescription(
        summary: 'List all users',
        description: 'Returns a paginated list of users with optional filtering'
    )]
    #[ApiPaginated]             // Wraps response in {data, total, page, per_page}
    public function listAction(int $page = 1) { }

    #[ApiIgnore]                // Hide from spec
    public function internalAction() { }

    #[ApiResponse(409, ConflictResponse::class)]  // Extra response code
    public function createAction(CreateUserRequest $body) { }
}

Validation Attributes

Used for both runtime validation (via DtoValidator) and OpenAPI schema generation:

use PhalconOpenApi\Attribute\{Email, Min, Max, StringLength, Format, Pattern, Enum, Url, NotBlank};

class CreateUserRequest
{
    #[NotBlank]
    #[StringLength(min: 1, max: 255)]
    public string $name;

    #[Email]
    public string $email;

    public ?string $phone = null;       // nullable → type: ["string", "null"]

    #[Min(1), Max(150)]
    public int $age;

    #[Enum(['active', 'inactive'])]
    public string $status = 'active';   // → enum in OpenAPI schema

    #[Url]
    public ?string $website = null;     // → format: uri in schema

    #[Format('date')]
    public ?string $birthDate = null;   // → format: date in schema

    #[Pattern('/^\+\d{10,15}$/')]       // PCRE delimiters stripped for OpenAPI
    public ?string $mobile = null;
}
Attribute Validates OpenAPI Schema
#[Email] Valid email format format: email
#[StringLength(min: 1, max: 255)] String length bounds minLength, maxLength
#[Min(1)], #[Max(150)] Numeric range minimum, maximum
#[Enum(['a', 'b'])] Allowed values enum: ["a", "b"]
#[Url] Valid URL format: uri
#[NotBlank] Rejects whitespace-only minLength: 1
#[Format('date')] Date/datetime/uuid/uri format: date
#[Pattern('/regex/')] PCRE regex match pattern: regex

Nested DTOs and Typed Arrays

Nested objects are validated recursively with dot-notation error paths:

class CreateOrderRequest
{
    #[StringLength(min: 1)]
    public string $orderNumber;

    public AddressDto $shippingAddress;  // → $ref + recursive validation

    /** @var OrderItemDto[] */
    public array $items = [];            // → array with $ref + per-item validation
}

class AddressDto
{
    #[NotBlank]
    public string $street;

    #[NotBlank]
    public string $city;

    #[Pattern('/^\d{5}$/')]
    public string $zip;
}

Validation errors for nested objects use dot-notation:

{
    "code": 422,
    "message": "Validation failed",
    "errors": [
        "shippingAddress.city is required",
        "items[0].zip must match pattern /^\\d{5}$/"
    ]
}

Security Configuration

$module = new OpenApiModule([
    'title'   => 'My API',
    'version' => '1.0.0',
    'security' => [
        'bearerAuth' => [
            'type'         => 'http',
            'scheme'       => 'bearer',
            'bearerFormat' => 'JWT',
        ],
    ],
]);

Then annotate controllers or methods with #[ApiSecurity('bearerAuth')].

Base Controller

Extend ApiController for automatic JSON body parsing, DTO validation, and convenience helpers:

use PhalconOpenApi\ApiController;

class UserController extends ApiController
{
    public function getAction(int $id)
    {
        $user = User::findFirst($id);
        if (!$user) {
            return $this->notFound('User not found');
        }
        return $this->json($user);
    }

    public function createAction(CreateUserRequest $body)
    {
        // $body is already validated and hydrated automatically
        $user = new User();
        $user->assign((array) $body);
        $user->save();
        return $this->json($user, 201);
    }
}

Configuration Options

$module = new OpenApiModule([
    'title'          => 'My API',           // required
    'version'        => '1.0.0',            // required
    'description'    => 'API description',  // optional
    'modelNamespace' => 'App\\Models',      // enables convention-based model inference
    'servers'        => [                   // optional
        ['url' => 'https://api.example.com'],
    ],
    'security'       => [ /* ... */ ],      // optional, see Security section
]);

Demo Application

See phalcon-openapi-demo for a complete working example with Docker and CRUD controllers.

Running Tests

vendor/bin/phpunit

License

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 12
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 3
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-21