html_first/atla-as

PHP 文件系统路由、文件服务、连接和 SQL 数据库查询库

dev-main 2024-06-26 13:09 UTC

This package is auto-updated.

Last update: 2024-09-26 13:36:39 UTC


README

  • php
  • 这个库是为了与我们的客户端 HATEOAS 兄弟库 https://github.com/hakimjazuli/atlaAS_client 一起使用而设计的;
  • 然而,您仍然可以将它作为后端正常使用,例如
    • 构建 REST JSON API 后端:使用我们的 "HtmlFirst\atlaAS\Middlewares_Middleware",在 /api/** 路由上设置默认头部;
    • 服务文件:使用我们的 "HtmlFirst\atlaAS\Router_MapResources;";
    • 构建 htmx/其他 HATEOAS 库/框架的 HATEOAS 后端;
      • 实际上,您可能会惊讶文件系统路由对于 htmx/其他 HATEOAS 库来说是多么的好,因为 atlaAS 代码拆分的一般性质;

        • 自动路由设置;
        • 不需要首先使用框架类实例注册它;
      • 在 htmx 用例中,您甚至可以选择不使用 hx-select 和/或 hx-target,因为返回的 HTML 可以很容易地按路由文件拆分;

      • 更不用说 PHP 是 HTML 的自然模板语言了 (好吧... 如果还有更自然的语言,PHP 仍然是设置起来最容易的,“没有设置”,只需使用 ?> 进入前端,使用 <?php 返回后端)

        • 只需确保清理您的输出,以免从用户生成的内容中受到 XSS 攻击;

假设

此库假设您熟悉

  • PHP psr-4 自动加载,使用 composer;
  • PHP OOP(用于扩展,以及在一般情况下使用我们的辅助类,此外 atlaAS 使用少量抽象,并不一定是一个 包含电池 的库,因此您必须具备良好的底层 PHP OOP);

如何安装

composer require html_first/atla-as

如何初始化

将您的静态公开文件夹中的 .htaccess 设置为如下所示

<IfModule mod_rewrite.c>
    SetEnvIf Origin "^http(s)?://(.+\.)?(127\.0\.0\.1:8000)$" ACAO=$0
    # SetEnvIf Origin "^http(s)?://(.+\.)?(127\.0\.0\.1:8000|172\.23\.224\.1:8000)$" ACAO=$0
    Header set Access-Control-Allow-Origin "%{ACAO}e" env=ACAO

    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

扩展我们的

  • "HtmlFirst\atlaAS\__atlaAS;"
  • "HtmlFirst\atlaAS\Vars\__Env;"
  • "HtmlFirst\atlaAS\Vars\__Settings;"

然后运行扩展的 __atlaAs 中的静态方法;您的 /public/index.php 应该看起来像这样

<?php

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

(new \Backend\__atlaAS(
    new \Backend\__Env,
    new \Backend\__Settings
))::run();

路由

  • 使用扩展的 __Settings 类,您可以更改
    • 文件夹: __Settings 类::$routes_path
    • 命名空间: __Settings 类::$routes_class
  • 路由命名
    • 必须与类名相同(区分大小写),最好是小写
    • 方法必须是公共函数 http-method(小写)带有动态 URI 的参数;
    • 以下是在 '/example/test/my_name/my_num' URL 上可用的,将输出 "my_name, my_num";
<?php

namespace Routes\example;

use HtmlFirst\atlaAS\Router\_Routes;

class test extends _Routes {
    public function get(string $name, string $num) {
        echo "$name, $num";
    }
}
  • 路由命名
    • 您必须从以下内容扩展它
      • "HtmlFirst\atlaAS\Router_Routes;"
      • "HtmlFirst\atlaAS\Router_RoutesWithMiddleware;"

特殊路由

  • 索引

    • //index,通常被称为 root URL,应扩展自 \HtmlFirst\atlaAS\Router_RouteWithMapResources\HtmlFirst\atlaAS\Router_RouteWithMapResourcesAndMiddleware
    • 由于网络爬虫的性质,大多数您的网络资源都假设位于根文件夹中;您可以按如下方式组织您的路由;
  • 路由

    • index.php
    • other_routes.php
    • 索引
      • ads.txt,可以使用 /ads.txt 访问
      • robot.txt,可以使用 /robot.txt 访问

服务文件

  1. 专门用于文件服务的路由
<?php

namespace Routes;

use HtmlFirst\atlaAS\Router\_MapResources;

class assets extends _MapResources {
}

您的文件夹应该看起来像这样

  • 路由

    • assets.php
    • assets
      • atlaAS.mjs
      • main.css

您可以重写map_resources方法,将其用作中间件以获取uri数组请求的列表;

  • 您的智能提示警告是您的朋友;
  • _MapResources路由的map_resources方法使用扩展参数;
  • 不用担心,它不会提供您的.php文件(或任何在扩展__Settings::$system_file中列出的文件扩展名);
  1. 具有文件提供的常规路由(使用_RouteWithMapResources|_RouteWithMapResourcesAndMiddleware
<?php

namespace Routes;

use HtmlFirst\atlaAS\Router\_RouteWithMapResources;

class assets extends _RouteWithMapResources {
}

<?php

namespace Routes;

use HtmlFirst\atlaAS\Router\_RouteWithMapResourcesAndMiddleware;

class assets extends _RouteWithMapResourcesAndMiddleware {
}

这些路由的脚本读取优先级(使用_RouteWithMapResources|_RouteWithMapResourcesAndMiddleware)是

  1. 路由方法mw,然后
  2. 如果方法==get,则
    1. 如果uri_input长度为0,则读取路由方法get并使用exit(0)退出;
    2. 如果uri_input长度为1或更多,则读取路由方法map_resources并使用exit(0)退出;
  3. 如果方法!=get,则读取路由方法$method

中间件

  • 命名

    • 使用扩展的__Settings::$middleware_name
    • 默认为mw.php
  • 中间件文件

<?php

namespace Routes\api;

use HtmlFirst\atlaAS\Middlewares\_Middleware;

class mw extends _Middleware {
    public function mw(string $method): bool {
        \header('Content-Type: application/json');
        }
        return true; /** return true to continue response */
}
  • 文件夹结构

    • 路由
      • index.php
      • api
        • mw.php <-- 这是中间件文件
  • 它将所有的/api/**路由转换为适合json api服务器的路由;

  • 路由也可以有自己的中间件

<?php

namespace Routes\example;

use HtmlFirst\atlaAS\Router\_RoutesWithMiddleware;

class test extends _RoutesWithMiddleware {
    public function mw(string $method): bool{
        /**
         * $method can be used for conditionals
         * to apply in only on specific method
         * return false to immediately stop response;
        */
    }
    public function get(string $name, string $num) {
        echo "$name, $num";
    }
}
  • 中间件优先级按以下顺序运行
    • 顶级父级mw.php
    • 然后是下面的父级,直到路由文件夹;
    • 然后是同一文件夹中的mw.php
    • 然后是路由的mw方法(在_MapResources的情况下,您也可以使用它的map_resources方法来获取uri数组列表);

SQL查询

  • 表助手
<?php

namespace Backend\Tables;

use HtmlFirst\atlaAS\Connection\_FieldType;
use HtmlFirst\atlaAS\Connection\_Table;
use PDO;

class Test extends _Table {
    public _FieldType $id;
    public _FieldType $name;
    public function __construct() {
        $this->id = $this->column(PDO::PARAM_INT);
        $this->name = $this->column(PDO::PARAM_STR, $this->regex_alphanumeric_loose(1, 255));
    }
}
  • 查询
<?php

namespace Backend\Queries;

use Backend\Tables\Test as TablesTest;
use HtmlFirst\atlaAS\Connection\_atlaASQuery;
use HtmlFirst\atlaAS\Connection\_Query;

class Test extends _Query {
    public static function test_name_like(string $test_name): _atlaASQuery {
        $test = new TablesTest;
        return self::sql_query('/sql/views/test.sql', bind: [
            'test_name' => [$test->name->type, "%$test_name%"]
        ]);
    }
}
  • 设置/sql/views/test.sql
SELECT
	`id`,
    test.test_name
FROM
    test
WHERE
    `test_name` LIKE :test_name;
  • 然后您可以在_Routes方法中的任何地方调用它
<?php

$results = \Backend\Queries\Test::test_name_like('a');
  • 是的...我知道...我们在这里做的是原始SQL,没有ORM...所以您需要使用SQL客户端软件编辑您的SQL文件来确保查询的安全性,例如(但不限于)DBeaver、HeidiSQL、SQLite Expert或许多其他软件;
  • 但基本上,您可以通过安装您首选的ORM来选择不使用原始SQL;

什么...没有.env吗?

  • 是的,这个库默认不支持.env
    • 这是为了类型安全;
  • 选项
    • 安装.env的依赖项,或者
    • 将您的扩展Env.php放在您的.gitignore中,并创建EnvExample.php,此外
    • 如果您不小心将.whatEverYourEnvFileIS放在./public/中,也许可以考虑just don't

库命名便利性

  • 以"__"开头的前缀类是全局的,无需在/public/index.php脚本后实例化;
  • 以"_"开头的前缀类或特质旨在在您的应用程序中使用;
  • 没有以任何"_"开头的前缀的类或特质旨在用于库内部;

致谢

这个库受到以下灵感的启发