memran/marwa-module
Composer 安装命令:
composer require memran/marwa-module
包简介
Framework-agnostic, PSR-11 friendly module management library for PHP apps (Marwa ecosystem compatible).
关键字:
README 文档
README
A framework-agnostic PHP package for discovering, validating, and bootstrapping application modules from the filesystem.
marwa-module helps you organize large applications into self-contained modules with their own manifests, routes, resources, migrations, and service providers. It gives you a predictable discovery process, typed lookup APIs, optional caching, and a simple way to register module providers into a PSR-11-friendly application bootstrap.
Features
- Discover modules from one or more directories with deterministic scan order
- Support both
manifest.phpandmanifest.jsonmodule definitions - Enforce required manifest structure with fail-fast validation and duplicate slug protection
- Preserve custom manifest keys (e.g.
menu,permissions) alongside validated fields - Access arbitrary manifest values via
$module->get('key', $default) - Serialize modules directly with
json_encode($module)— implementsJsonSerializable - Expose clean typed APIs through
Module,ModuleHandle,ModuleRegistry(implementsCountable), andModuleBuilder - Resolve routes, views, migrations, and other manifest-defined paths relative to the module root
- Prevent unsafe absolute-path and
..traversal escapes when resolving module paths - Cache discovered module metadata to a PHP file for faster repeated boots
- Register module service providers through
ModulesServiceProvider - Ship with PHPUnit, PHPStan, PHP-CS-Fixer, and GitHub Actions support for development workflows
Requirements
- PHP 8.2+
- Composer
- A PSR-11-compatible container if you use
ModulesServiceProvider
Installation
composer require memran/marwa-module
Quick Start
<?php declare(strict_types=1); use Marwa\Module\ModuleBuilder; use Marwa\Module\ModuleRegistry; use Marwa\Module\ModuleRepository; $modulesPath = __DIR__ . '/modules'; $cacheFile = __DIR__ . '/storage/cache/modules.php'; $repository = new ModuleRepository($modulesPath, $cacheFile); $registry = new ModuleRegistry($repository); $builder = new ModuleBuilder($registry); $user = $builder->current('user'); $user->slug(); $user->routes('http'); $user->path('views'); $user->migrations(); $user->get('menu'); // custom manifest key $user->get('permissions', []); count($registry); // Countable json_encode($user); // JsonSerializable
Full Example
A complete runnable example lives in examples/.
Run it with:
php examples/index.php
The example demonstrates:
- module discovery from both
manifest.phpandmanifest.json - route, view, and migration path resolution
- lookup by slug and by filesystem path
- cache file usage
- provider registration through
ModulesServiceProvider - provider boot execution inside a minimal PSR-11-compatible application container
- JSON output suitable for CLI or browser responses
Example output:
{
"modules": [
{
"slug": "auth",
"name": "Auth Module",
"version": "1.0.0",
"manifest": {
"name": "Auth Module",
"slug": "auth",
"version": "1.0.0",
"menu": "Authentication",
"permissions": ["auth.manage", "auth.login"],
"providers": ["Marwa\\Module\\Examples\\Modules\\Auth\\AuthServiceProvider"],
"paths": { "views": "resources/views" },
"routes": { "http": "routes/http.php" },
"migrations": ["database/migrations/2026_01_01_000000_create_auth_tables.php"]
},
"route": "/path/to/examples/modules/auth/routes/http.php",
"views": "/path/to/examples/modules/auth/resources/views",
"providers": [
"Marwa\\Module\\Examples\\Modules\\Auth\\AuthServiceProvider"
],
"migrations": [
"/path/to/examples/modules/auth/database/migrations/2026_01_01_000000_create_auth_tables.php"
]
}
],
"lookups": {
"current_auth_name": "Auth Module",
"resolved_by_path": "auth"
},
"bootstrap": {
"repository_registered": true,
"registry_registered": true,
"builder_registered": true,
"auth_provider_registered": true,
"auth_provider_booted": true,
"billing_provider_registered": true,
"billing_provider_booted": true
}
}
Module Layout
project-root/
modules/
User/
manifest.php
routes/
http.php
src/
resources/
Example manifest.php:
<?php declare(strict_types=1); return [ 'name' => 'User Module', 'slug' => 'user', 'version' => '1.0.0', 'providers' => [ App\Modules\User\UserServiceProvider::class, ], 'paths' => [ 'views' => 'resources/views', ], 'routes' => [ 'http' => 'routes/http.php', ], 'migrations' => [ 'database/migrations/2026_01_01_000000_create_users_table.php', ], ];
The library also accepts manifest.json with the same structure.
Manifest rules:
- A module directory must contain exactly one manifest file:
manifest.phpormanifest.json - Directories without a manifest are ignored during discovery
- A manifest must define a non-empty string
slug providersandmigrationsmust be arrays of non-empty stringspathsandroutesmust be maps with non-empty string keys and values- Duplicate module slugs across discovered modules are rejected
- Unknown keys (e.g.
menu,permissions,widgets) are validated for slug uniqueness but otherwise passed through unchanged - Access custom keys with
$module->get('menu')or$module->manifest()['menu']
Service Provider Bootstrap
If your application container supports add() or set() and addServiceProvider(), you can register the package in one step:
<?php declare(strict_types=1); use Marwa\Module\ModulesServiceProvider; $provider = new ModulesServiceProvider( __DIR__ . '/modules', __DIR__ . '/storage/cache/modules.php' ); $provider->register($app);
Public API Overview
ModuleRepository: scans module directories and optionally persists cache files. All manifest keys are preserved, not just the 7 validated fields.ModuleRegistry: keeps discovered modules in memory. ImplementsCountableforcount($registry). Resolves modules by slug or path.ModuleBuilder: high-level lookup API returningModuleHandleinstances.Module: immutable module metadata wrapper with typed accessors (name(),slug(),version(),path(),routeFile(),migrations(),providers()), a genericget(string $key, $default)for arbitrary manifest values,__debugInfo()for cleanvar_dumpoutput, andJsonSerializableforjson_encode($module).ModuleHandle: lightweight delegate that mirrorsModule's public API.ModulesServiceProvider: registers the repository, registry, builder, and module providers.
Configuration Notes
- Keep the cache file in an application-controlled writable directory.
- A directory is only discovered as a module when it contains a valid manifest.
- Module paths declared in manifests are treated as relative to the module root.
- Absolute paths and
..traversal segments are ignored when resolving module asset paths. - Provider classes declared in manifests must exist and implement
Marwa\Module\Contracts\ModuleServiceProviderInterface. - If both
manifest.phpandmanifest.jsonexist in the same module directory, discovery fails with an exception.
Development
Install dependencies:
composer install
Available scripts:
composer test
composer test:coverage
composer analyse
composer lint
composer fix
composer ci
Testing
- Test runner: PHPUnit
- Coverage command:
composer test:coverage - Test files live in
tests/ - Fixture-backed module examples live in
tests/Fixtures/
Static Analysis And Linting
- Static analysis: PHPStan via
phpstan.neon.dist - Coding style: PHP-CS-Fixer via
.php-cs-fixer.dist.php - CI workflow:
.github/workflows/ci.yml
Production Notes
- Treat manifest files and cache file locations as trusted application assets.
- Prefer writing cache files under
storage/or another private writable directory. - If a cache file is corrupted, the repository falls back to a fresh filesystem scan.
- Invalid, ambiguous, or duplicate manifests fail fast with descriptive runtime exceptions.
Contributing
- Keep changes small and focused.
- Add or update PHPUnit coverage for behavior changes.
- Run
composer cibefore opening a pull request. - Keep documentation aligned with actual behavior and scripts.
Release Checklist
- Run
composer ci - Review public API changes and backward compatibility
- Update README or examples if usage changed
- Tag and publish the package
License
MIT
memran/marwa-module 适用场景与选型建议
memran/marwa-module 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 919 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 01 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「php」 「modules」 「discovery」 「PSR-11」 「Marwa」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 memran/marwa-module 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 memran/marwa-module 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 memran/marwa-module 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
This is Paymorrow module for OXID eShop.
Laravel package to integrate the Httplug generic HTTP client into Laravel
Lightweight mock implementations of PSR-18, PSR-17 and PSR-7 tailored to simplify unit testing.
Analysis module for finding problematical shop data.
yii2 swiper slider
An interactive tour through the TYPO3 backend.
统计信息
- 总下载量: 919
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 11
- 依赖项目数: 1
- 推荐数: 1
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-01