inphinit/teeny

现成的路由系统

维护者

详细信息

github.com/inphinit/teeny

源代码

问题

安装: 323

依赖项: 0

建议者: 0

安全: 0

星标: 6

关注者: 2

分支: 1

开放问题: 0

类型:项目

0.3.1 2024-05-31 12:28 UTC

This package is auto-updated.

Last update: 2024-09-20 21:32:28 UTC


README

Teeny route system for PHP Teeny route system for JavaScript (Node.js) Teeny route system for Golang Teeny route system for Python

Teeny PHP 路由系统

Teeny 是一个非常小巧的路由系统,支持从 PHP 5.3PHP 8,极其简单且易于使用。

使用 composer 安装

创建项目时使用

composer create-project inphinit/teeny <project name>

<project name> 替换为您的项目名称,例如,如果想要创建一个名为 "blog" 的项目(文件夹名称),请使用

composer create-project inphinit/teeny blog

不使用 composer 下载

如果不使用 composer,请尝试直接从 https://github.com/inphinit/teeny/releases 下载

Apache (.htaccess)

如果是在子文件夹中使用 .htaccess,则需要做一些调整,您需要更改所有的 ErrorDocument。更多详情请参阅 https://httpd.apache.ac.cn/docs/2.4/custom-error.html

如果地址类似于 https://<domain>/,则执行以下操作

ErrorDocument 403 /index.php/RESERVED.TEENY-403.html
ErrorDocument 500 /index.php/RESERVED.TEENY-500.html
ErrorDocument 501 /index.php/RESERVED.TEENY-501.html

如果地址类似于 https://<domain>/foo/,则执行以下操作

ErrorDocument 403 /foo/index.php/RESERVED.TEENY-403.html
ErrorDocument 500 /foo/index.php/RESERVED.TEENY-500.html
ErrorDocument 501 /foo/index.php/RESERVED.TEENY-501.html

如果地址类似于 https://<domain>/foo/bar/,则执行以下操作

ErrorDocument 403 /foo/bar/index.php/RESERVED.TEENY-403.html
ErrorDocument 500 /foo/bar/index.php/RESERVED.TEENY-500.html
ErrorDocument 501 /foo/bar/index.php/RESERVED.TEENY-501.html

NGINX

对于 NGINX,您可以在 Nginx 中使用 try_files。请参见以下示例

location / {
    root /home/foo/bar/teeny;

    # Redirect page errors to route system
    error_page 403 /index.php/RESERVED.TEENY-403.html;
    error_page 500 /index.php/RESERVED.TEENY-500.html;
    error_page 501 /index.php/RESERVED.TEENY-501.html;

    try_files /public$uri /index.php?$query_string;

    location = / {
        try_files $uri /index.php?$query_string;
    }

    location ~ /\. {
        try_files /index.php$uri /index.php?$query_string;
    }

    location ~ \.php$ {
        # Replace by your FPM or FastCGI
        fastcgi_pass 127.0.0.1:9000;

        fastcgi_index index.php;
        include fastcgi_params;

        set $teeny_suffix "";

        if ($uri != "/index.php") {
            set $teeny_suffix "/public";
        }

        fastcgi_param SCRIPT_FILENAME $realpath_root$teeny_suffix$fastcgi_script_name;
    }
}

注意:对于 FPM,请使用 fastcgi_pass unix:/var/run/php/php<version>-fpm.sock(将 <version> 替换为您服务器上的 PHP 版本)

内置的 Web 服务器

您可以使用 内置服务器 来方便开发,Teeny 提供了相关的静态文件,这将有助于使用,使用示例(使用 cd 命令导航到项目文件夹)

php -S localhost:8080 index.php

您可以通过编辑 server.bat(Windows)或 server(Linux 或 macOS)文件来简化使用简单命令启动项目

Windows (server.bat 文件)

根据您的环境配置 server.bat 变量

set PHP_BIN=C:\php\php.exe
set PHP_INI=C:\php\php.ini

set HOST_HOST=localhost
set HOST_PORT=9000

配置完成后,您可以通过导航到项目文件夹并运行启动内置服务器的命令来启动项目,以下是一个示例

cd c:\projets\blog
server

Linux 和 macOS (server 文件)

根据您的环境配置 ./server 变量

PHP_BIN=/usr/bin/php
PHP_INI=/etc/php.ini

HOST_HOST=localhost
HOST_PORT=9000

配置完成后,您可以通过导航到项目文件夹并运行启动内置服务器的命令来启动项目,以下是一个示例

cd ~/projets/blog
./server

API

来自 Teeny 类的方法

添加和删除路由

index.php 中创建新路由时,请按照以下方式操作

$app->action('GET', '/myroute', function () {
    echo 'Test!';
});

您可以使用 return

$app->action('GET', '/myroute', function () {
    return 'Test!';
});

要删除路由,请使用 null 值,如下所示

$app->action('GET', '/myroute', null);

路由包含文件

要包含文件,请使用如下方式

$app->action('GET', '/myroute', 'foo/bar/test.php');

如果在项目中找不到 foo/bar/test.php,将显示以下错误

Warning: require(foo/bar/test.php): failed to open stream: No such file or directory in /home/user/blog/vendor/teeny.php on line 156

Fatal error: require(): Failed opening required 'foo/bar/test.php' (include_path='.') /home/user/blog/vendor/teeny.php on line 156

HTTP 状态

要获取来自 SAPI(Apache、Ngnix、IIS)或脚本中先前定义的 HTTP 状态,请使用如下方式

$var = $app->status();

要在路由中检索,请使用如下方式

$app->action('GET', '/myroute', function () use ($app) {
    echo 'HTTP status: ', $app->status();
});

要设置新的 HTTP 状态,请使用如下方式(例如:发出 404 Not Found)

$app->status(404);

要在路由中设置,请使用如下方式(条件/if 示例)

$app->action('GET', '/report', function () use ($app) {
    $file = 'data/foo.csv';

    if (is_file($file)) {
        header('Content-Type: text/csv');
        readfile($file);
        /**
         * Note: this is just an example, about sending a file,
         * if possible use "X-Sendfile" or equivalent
         */
    } else {
        $app->status(404);

        echo 'Report not found';
    }
});

路由中的命名参数

您可以使用如下方式使用参数

$app->action('GET', '/user/<user>', function ($params) {
    var_dump($params);
});

如果访问类似这样的 URL http://mywebsite/user/mary,则返回

array(2) {
  ["user"]=>
  string(3) "mary"
}

另一个示例

$app->action('GET', '/article/<name>-<id>', function ($params) use ($app) {
    // Only ID numerics are valids
    if (ctype_digit($params['id'])) {
        echo 'Article ID: ', $params['id'], '<br>';
        echo 'Article name: ', $params['name'];
    } else {
        $app->status(400);

        echo 'Invalid URL';
    }
});

如果访问类似这样的 URL http://mywebsite/article/mary-1000,则返回

Article ID: mary
Article name: 1000

路由中命名参数的支持类型

示例,只有数字 ID 是有效的

$app->action('GET', '/article/<name>-<id:num>', function ($params) {
    echo 'Article ID: ', $params['id'], '<br>';
    echo 'Article name: ', $params['name'];
});

要添加新模式,请使用如下方式 Teeny::setPattern(),示例

$app->setPattern('example', '[A-Z]\d+');

$app->action('GET', '/custom/<myexample:example>', function ($params) use ($app) {
    echo '<h1>custom pattern</h1>';
    echo '<pre>';
    print_r($params);
    echo '</pre>';
});

要访问此路由示例,请使用 http://mysite/test/A00001http://mysite/test/C02,以大写字母开头,后跟一个整数。

处理大文件

要处理大文件,您可以选择使用以下服务器模块

简单实现

$software = $_SERVER['SERVER_SOFTWARE'];
$send = null;

if (stripos($software, 'apache') !== false) {
    $send = 'X-Sendfile';
} else if (stripos($software, 'nginx') !== false) {
    $send = 'X-Accel-Redirect';
} else if (stripos($software, 'lighttpd') !== false) {
    $send = 'X-LIGHTTPD-send-file';
}

$app->action('GET', '/download', function () use ($sendHeader) {
    $file = '/protected/iso.img';

    if ($send) {
        header($send . ': ' . $file);
        return;
    }

    if ($handle = fopen($file, 'r')) {
        $app->status(500);
        return 'Failed to read file';
    }

    // fallback (this is just an example)
    $length = 2097152;

    header('Content-Disposition: attachment; filename="iso.img"');
    header('Content-Length: ' . filesize($file));

    while (!feof($handle)) {
        echo fgets($handle, $length);
        flush();
    }

    fclose($handle);
});

服务公共文件(和脚本)

要服务公共文件(或脚本),您必须将它们添加到公共文件夹中。前缀 /public/* 不会显示在 URL 中,例如,如果有名为 public/foobar.html 的文件,则用户将直接访问地址 https://<域名>/foobar.html

子文件夹也会生效,如果有一个名为 public/foo/bar/baz/video.webm 的文件,那么用户应访问 https://<域名>/foo/bar/baz/video.webm

您还可以添加 PHP 脚本,并且它们将正常执行,如果您有一个名为 public/sample/helloworld.php 的脚本,只需访问 https://<域名>/sample/helloworld.php 即可。

如果您想提供一个博客,例如 WordPress,您还必须将其放置在文件夹内,结构示例

├─── .htaccess
├─── index.php
├─── composer.json
├─── vendor/
└─── public/
     ├─── helloword.html
     └─── blog/
          ├─── .htaccess
          ├─── index.php
          ├─── wp-activate.php
          ├─── wp-blog-header.php
          ├─── wp-comments-post.php
          ├─── wp-config-sample.php
          ├─── wp-config.php
          ├─── wp-cron.php
          ├─── wp-links-opml.php
          ├─── wp-load.php
          ├─── wp-login.php
          ├─── wp-mail.php
          ├─── wp-settings.php
          ├─── wp-signup.php
          ├─── wp-trackback.php
          ├─── xmlrpc.php
          ├─── wp-admin/
          ├─── wp-content/
          └─── wp-includes/

然后只需访问 https://<域名>/blog/。其他示例

  • https://<域名>/blog/wp-admin/
  • https://<域名>/blog/2021/03/24/astronomy-messier-87-black-hole/
  • https://<域名>/blog/2023/04/17/researchers-discover-small-galaxy/

如果您需要更多功能,您可以体验 Inphinit PHP 框架https://inphinit.github.io