Download the PHP package migears/web without Composer

On this page you can find all versions of the php package migears/web. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package web

migears/web

Version

A minimalist REST framework with directory-as-routing. Zero magic, zero global variables, core code under 500 lines.

Background: miGears is the open-source successor of TinyGears, a self-developed PHP framework. It was renamed and open-sourced recently because the name TinyGears is already taken in the open-source community.

Features

Installation

Requires: PHP 8.1+, psr/container, psr/log.

Quick Start

1. Create Resource Directory

2. Write Resource Class

The class name and namespace have to match the path. The file below lives at resources/Users/___user_id___/Index.php and the bootstrap uses namespace: 'App\\Resources', so the class is App\Resources\Users\UserId\Index — a wildcard directory contributes its own name in StudlyCase as a namespace segment (___user_id___ → UserId).

3. Bootstrap

Container

MiRest is the container: register only what needs configuration (PDO, Redis, Logger, a DAO, a Manager); everything that merely needs new is constructed in place. It is a PSR-11 container — Psr\Container\ContainerInterface — so anything that speaks PSR-11 reaches it without a bespoke interface, and this package does not have to depend on the package that consumes it.

Design philosophy

The whole API: three methods

$id is either a class name (PDO::class) or any custom string ('config'), so interfaces and friendly aliases work naturally. has() and get() are PSR-11; set() is MiRest's own registration side.

Lazy-singleton flow:

get() throwing is PSR-11's requirement rather than a style choice: a typo or a forgotten registration must fail where it is asked for, instead of surfacing later as a null that "is not an object". Probing for something optional is what has() is for. NotFoundException is also a RuntimeException, and it is not ResourceNotFoundException — that one means "no resource matched this path" (a 404), this one means "the application was not wired correctly" (a 500).

Re-registering with set() replaces the factory and drops the cached instance, so the next get() builds a fresh object — handy for redeploy/rebuild or tests.

Using the container inside resources

Each resource receives the container (its MiRest instance) and resolves entries through $this->resolve():

The accessor is named resolve() rather than get() on purpose: PHP method names are case-insensitive, so a get() here would collide with the HTTP GET() verb.

Typical bootstrap wiring:

Rule of thumb: needs configuration → register via set(). Needs nothing → just new. Either way your code never depends on container magic.

Note on the namespace parameter: Each resource file declares a class (usually Index or CatchAllResource). If namespace is empty, all resource classes live in the global scope and will collide as soon as you have more than one resource — you will get a "Cannot redeclare class" fatal error. Always set a namespace for any project with more than one resource file.

Routing Rules

For a request path /foo/bar/baz, the locator descends level by level:

  1. Exact directory match — If a Foo/ directory exists, enter it and continue matching bar/baz
  2. Wildcard parameter — If a ___*___/ directory exists, use the first one, capture the current segment as a parameter, and continue
  3. CatchAll fallback — If the current directory has CatchAllResource.php, match all remaining paths
  4. 404 — If none of the above match, return 404

After the path is fully traversed, resource files are looked up in the following order:

Finally, the located resource serves the request through the template method handle() (before → HTTP method → after), so hooks run consistently whether or not extra path segments matched. A catch-all resource receives any unmatched remaining segments via $this->remaining.

Note on short-circuiting: If the resource-level before() returns a Response, the request short-circuits — neither the HTTP method nor the resource-level after() runs. The global after hooks registered on MiRest still execute, because they wrap the entire dispatch.

Once located, the HTTP verb decides what runs: the handler the resource declares, or 405 Method Not Allowed when it declares none — the 405 response always carries an Allow header listing the supported methods (RFC 9110). A request whose verb is not an HTTP method gets the same 405 without ever reaching the class, so the resource's own helpers can never be invoked as handlers. The default OPTIONS() reports what the resource supports through an Allow header.

URL segments are automatically converted to StudlyCase to match directory names (/users → Users, /blog_posts → BlogPosts). . / .. segments are ignored, so the locator can never escape the resource root; baseDir must be an existing directory or an InvalidArgumentException is thrown.

Wildcard vs exact directories on the same level: an exact directory (e.g. Users/) always takes priority over a wildcard directory (e.g. ___id___/). If both exist at the same path depth, the exact match wins — the wildcard is never reached. This is intentional: explicit routes should not be shadowed by parameter captures.

Route parameters keep their raw URL encoding: values captured from ___param___ directories are passed through as-is (e.g. hello%20world stays hello%20world). Use urldecode($this->param('name')) when you need the decoded value. This is intentional — keeping raw encoding provides an extra layer of protection against path-traversal variants like %2e%2e.

API Reference

MiRest

Main entry point, dispatches the request to the corresponding resource and returns a response.

Request

Response

AbstractResource

Method Description
GET() / POST() / PUT() / DELETE() / PATCH() HTTP method handlers (override in subclasses). A method you do not override answers 405 Method Not Allowed
OPTIONS() Answers 204 with an Allow header listing what the resource supports (always OPTIONS and HEAD, plus whichever of the five above the subclass declares — detected by reflection, so simply declaring POST() is enough)
HEAD() GET() without a body
before(Request): ?Response Before hook, short-circuits if a response is returned
after(Request, Response): Response After hook, modifies and returns the response
param(string $name, mixed $default = null): mixed Get a named route parameter
resolve(string $id): mixed Resolve a registered entry (PDO, Logger, a Manager, ...)
assertInt(mixed, string): int Validate as integer, throws 404 on failure
$this->params All named parameters array
$this->remaining Remaining path segments (only for catch-all resources)

License

MIT


migears/web

Version

极简 REST 框架,目录即路由。零魔法、零全局变量,核心代码不到 500 行。

背景:miGears 源自自研 PHP 框架 TinyGears,因 TinyGears 这一名字 已被开源社区占用,故近期更名并开源发布。

特性

安装

要求:PHP 8.1+,psr/container,psr/log。

快速开始

1. 创建资源目录

2. 编写资源类

类名与命名空间必须和路径对得上。下面的文件在 resources/Users/___user_id___/Index.php, bootstrap 里用的是 namespace: 'App\\Resources',所以类名是 App\Resources\Users\UserId\Index —— 通配目录会以自己的 StudlyCase 形式贡献一个命名空间段 (___user_id___ → UserId)。

3. 启动

容器

MiRest 本身就是容器:只注册需要配置的东西(PDO、Redis、Logger、DAO、Manager);只需要 new 的东西就地构造。 它是一个 PSR-11 容器 —— Psr\Container\ContainerInterface —— 所以任何会说 PSR-11 的代码都能取用它, 不必为它另立接口,本包也无需依赖使用它的那个包。

设计哲学

全部 API 只有三个方法

$id 可以是类名(PDO::class),也可以是任意字符串别名('config'),因此接口、友好别名都能自然使用。 has() 与 get() 是 PSR-11 的;set() 是 MiRest 自己的注册面。

懒加载单例的流程:

get() 会抛不是风格选择,而是 PSR-11 的要求:拼错或漏注册必须在要它的地方失败, 而不是过一阵子以「某个 null 不是对象」的形式冒出来。要探测可有可无的东西,用 has()。 NotFoundException 同时也是 RuntimeException;它不是 ResourceNotFoundException —— 后者是「没有资源匹配这个路径」(404),前者是「应用没装配对」(500)。

重新 set() 会替换工厂并丢弃已缓存的实例,下次 get() 会构建全新对象 —— 适合重新部署或测试场景。

在资源类内使用容器

每个资源都会拿到容器(其所属 MiRest 实例),通过 $this->resolve() 取条目:

访问器叫 resolve() 而不是 get(),是刻意的:PHP 方法名不区分大小写,叫 get() 会与 HTTP 的 GET() 冲突。

典型的启动装配:

经验法则:需要配置 → 用 set() 注册。不需要配置 → 直接 new。无论哪种方式,你的业务代码都不依赖容器的任何魔法。

关于 namespace 参数:每个资源文件都声明了一个类(通常是 Index 或 CatchAllResource)。如果 namespace 为空,所有资源类都在全局作用域,一旦有两个以上资源就会类名冲突,报 "Cannot redeclare class" 致命错误。任何有多个资源文件的项目都应设置 namespace。

路由规则

对于请求路径 /foo/bar/baz,定位器逐级下降:

  1. 精确目录匹配 — 如果存在 Foo/ 目录,进入并继续匹配 bar/baz
  2. 通配符参数 — 如果存在 ___*___/ 目录,使用第一个,捕获当前段为参数,继续
  3. CatchAll 兜底 — 如果当前目录有 CatchAllResource.php,匹配所有剩余路径
  4. 404 — 以上都不匹配,返回 404

路径走完后,按以下顺序查找资源文件:

最终,定位到的资源统一通过模板方法 handle()(before → HTTP 方法 → after)处理请求,因此无论是否有多余路径段,前置/后置钩子行为一致。兜底资源可通过 $this->remaining 拿到未匹配的剩余路径段。

短路说明:资源级 before() 返回 Response 时请求短路——HTTP 方法和资源级 after() 都不会执行。但注册在 MiRest 上的全局 after 钩子仍会执行(它们包裹整个分发过程)。

定位到资源之后,由 HTTP 动词决定执行什么:资源声明了就执行对应处理器,没声明则返回 405 Method Not Allowed——405 响应始终携带列出支持方法的 Allow 头(RFC 9110)。不是 HTTP 动词的请求同样得到 405,而且根本不会进入类内部,因此资源自己的辅助方法不可能被当成处理器调用;默认的 OPTIONS() 会通过 Allow 头报告该资源支持哪些方法。

URL 段会自动转 StudlyCase 匹配目录名(/users → Users,/blog_posts → BlogPosts)。路径中的 . / .. 段会被忽略,定位器永远不会逃出资源根目录;baseDir 必须是已存在的目录,否则抛出 InvalidArgumentException。

同级精确目录与通配目录的优先级:精确目录(如 Users/)始终优先于通配目录(如 ___id___/)。若同一深度两者都存在,精确匹配胜出——通配目录永远不会被命中。这是有意设计的:显式路由不应被参数捕获所遮蔽。

路由参数保留原始 URL 编码:从 ___param___ 目录捕获的值按原样传入(例如 hello%20world 保持 hello%20world)。需要解码时用 urldecode($this->param('name')) 即可。这是有意设计的——保留原始编码为 %2e%2e 这类路径穿越变体提供了额外的防护层。

API 参考

MiRest

主入口,将请求分发到对应的资源并返回响应。

Request

Response

AbstractResource

方法 说明
GET() / POST() / PUT() / DELETE() / PATCH() HTTP 方法处理器(子类重写)。未重写的方法一律返回 405 Method Not Allowed
OPTIONS() 返回 204 并带 Allow 头,列出该资源支持的方法(始终含 OPTIONS 与 HEAD,再加上子类声明的那几个 —— 通过反射探测,所以只要声明 POST() 就会出现)
HEAD() 与 GET() 相同但不返回响应体
before(Request): ?Response 前置钩子,返回响应则短路
after(Request, Response): Response 后置钩子,修改并返回响应
param(string $name, mixed $default = null): mixed 获取命名路由参数
resolve(string $id): mixed 解析已注册的条目(PDO、Logger、Manager 等)
assertInt(mixed, string): int 验证整数,失败抛 404
$this->params 所有命名参数数组
$this->remaining 剩余路径段(仅 catch-all 资源有值)

License

MIT


All versions of web with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
psr/container Version ^2.0
psr/log Version ^3.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package migears/web contains the following files

Loading the files please wait ...