toolx / toolx-php-framework
PHP 应用程序轻松创建的框架
Requires
- php: >=7.4.0
- gumlet/php-image-resize: 2.0.*
- league/plates: 3.*
- phpmailer/phpmailer: ^6.8.0
- scssphp/scssphp: ^1.11.0
README
使用 composer 安装
composer create-project toolx/toolx-php-framework
启动服务器
在您的终端打开应用程序根目录,并运行
php cli serve
请注意,您必须从 app/Config/urls.php 提供 URLROOT
以这种方式启动服务器仅适用于开发目的!
路由器
创建路由
转到 app/Routes 目录。创建路由文件,并添加两行...
<?php
use App\Engine\Libraries\Router;
$router = Router::getInstance();
路由器 HTTP 动词
$router->get('/', function($req, $res) {});
$router->post('/', function($req, $res) {});
$router->put('/', function($req, $res) {});
$router->patch('/', function($req, $res) {});
$router->delete('/', function($req, $res) {});
$router->all('/', function($req, $res) {});
$router->match('get|post', '/', function($req, $res) {});
您也可以以不同的方式添加路由。
$router->post([
'route' => 'some/url',
'controller' => 'PagesController',
'method' => 'create',
'csrf' => false
]);
路由器动词方法接受两个参数 - $request 和 $response。
$router->get('/', function($req, $res) {
return $res->render('welcome');
});
从目录加载路由
有时,如果您需要太多的路由,将它们放在额外的目录中会更方便。为了加载这些额外的目录,您需要转到 app/Config/routes.php 文件并从那里加载单独的目录。
将 URL 段作为回调参数获取
$router->get('books/orange-fox/part-one', function($req, $res, $x, $y, $z) {
dd( $y ); // orange-fox
});
使用 CLI 创建路由
php cli make:routes optional/path/routerName
路由器占位符
路由器配置
配置文件可以在 app\Config\routes.php 文件中找到。添加路由路径时无需 app\Routes 目录
['Back', 'Front']
路由将在 app\Routes\Back 和 app\Routes\Front 中自动搜索。
用户
存在预定义的用户路由。要加载此路由文件,您需要转到 app/Config/routes.php 文件并从那里加载此路由目录。
UsersController.php 文件使用 php mailer 进行密码重置方法,并使用 php resizer。它们都位于 composer.json 文件中。
用户视图文件也预先定义在 app/Views/users 目录中。
模型
模型是放置验证和业务逻辑的地方。
创建模型
使用 CLI 创建模型
使用 CLI,您必须提供模型名称,它将在模型内部生成名为 Model_Modelname.php 的文件。查看以下示例。
php cli make:models modelname
模型位于 app/Models 目录中。命名模型文件时必须遵循 RedBeanPHP 模型命名约定 - Model_Pages.php。
在模型内部添加类,并使用 RedBeanPHP 的 RedBean_SimpleModel 类扩展它。
要初始化模型,在控制器或路由函数内部添加函数 - initModel('Pages')。
<?php namespace App\Controllers;
use \R as R;
class HomeController {
public function index($req, $res) {
// Initialize model
$pagesModel = initModel('Pages');
$res->render('welcome', [
'title' => 'APP Title'
]);
}
}
确保从 app/Config/database.php 文件中启用 SQL - define("DATABASE", TRUE);。
class Model_Pages extends RedBean_SimpleModel {
public function open() {
global $lifeCycle;
$lifeCycle .= "called open: ".$this->id;
}
public function dispense() {
global $lifeCycle;
$lifeCycle .= "called dispense() ".$this->bean;
}
public function update() {
global $lifeCycle;
$lifeCycle .= "called update() ".$this->bean;
}
public function after_update() {
global $lifeCycle;
$lifeCycle .= "called after_update() ".$this->bean;
}
public function delete() {
global $lifeCycle;
$lifeCycle .= "called delete() ".$this->bean;
}
public function after_delete() {
global $lifeCycle;
$lifeCycle .= "called after_delete() ".$this->bean;
}
}
可以向模型添加自定义方法。它们可以通过 initModel('Pages'); 函数访问;
// Initialize model
$pagesModel = initModel('Pages');
// Get custom method
$pagesModel->customMethod();
迁移
要创建迁移,在模型中创建名为 migrate() 的方法
此方法可以通过 CLI 调用。要调用它,在终端中键入 - php cli make:migration modelName
方法欺骗
在某些情况下,可能需要使用 put、patch 或其他请求。在这种情况下,可以将 post 请求欺骗为其他请求。
查看示例
<form action="" method="POST">
<input name="_method" type="hidden" value="PUT" />
</form>
或添加函数
<form action="" method="POST">
<?= setMethod("PUT") ?>
</form>
CSRF 保护
CSRF 隐藏字段
从 - app/Config/app.php 启用 CSRF 保护并将 CSRF_PROTECTION 设置为 TRUE
要将 CSRF 字段添加到您的表单中,请添加以下...
<form method="post">
<?= csrf_field(); ?>
</form>
检查 CSRF 值 / 哈希
<?= csrf_hash() ?>
表单助手
使用 getForm('field_name') 函数防止表单字段值丢失。
<form method="post">
<input name="fullname" value="<?= getForm('fullname') ?>" />
<input name="username" value="<?= getForm('username') ?>" />
<input name="email" value="<?= getForm('email') ?>" />
<input name="password" value="" />
<button type="submit">Submit form</button>
</form>
在使用 getForm 助手函数之前,您必须使用 setForm($requestBody) 函数将其从控制器或路由设置。它接受请求数据作为参数。
$router->post('users/register', function($req, $res) {
// Storing request body with setForm function
setForm($req->body());
// Redirect back to login view
return $res->redirect(baseUrl('users/login'));
});
请求 & 响应方法
您可以在路由回调或控制器方法回调中找到 $request 和 $response 变量。查看示例。
<?php namespace App\Controllers\Items;
use App\Engine\Libraries\Validation;
use \R as R;
class ItemsController {
public function new($req, $res) {
// Request variable method
return $res->redirectBack();
}
}
可用的请求方法
请求
可用的响应方法
响应
URL助手
获取基本URL
要获取项目基本URL,使用 baseUrl() 函数。它接受可选参数,您可以根据基本URL添加新URL。查看示例。
<?= baseUrl() ?> <!-- http://sitename.com -->
<?= baseUrl('users/login') ?> <!-- http://sitename.com/users/login -->
URL段
要使用 urlSegments() 函数获取不带站点基本URL的URL。它接受可选参数,您可以设置URL索引。
例如,您当前的URL是 http://sitename.com/users/login
<?= urlSegments() ?> <!-- returns - users/login -->
<?= urlSegments(2) ?> <!-- returns - login -->
<?= urlSegments('first') ?> <!-- returns - first part of url -->
<?= urlSegments('last') ?> <!-- returns - last part of url -->
获取查询字符串
<?= query() // Takes optional numeric argument ?>
中间件
中间件文件必须放在 app/Routes 目录中。它是 $router HTTP动词方法的第三个参数。
$router->get('url', 'callback or Controller@method', 'middleware')
$router->get('url', 'callback or Controller@method', 'middleware/dir1/dir2/fileFuncName')
中间件必须声明为字符串,并提供没有.php扩展名的中间件文件路径。
中间件文件名必须与内部函数名相同!
中间件函数内部接收两个参数,分别是 $request 和 $response。它们与 $router 动词方法(get、post等)中的参数相同。
自定义助手文件
助手文件位于 app/Helpers 目录中,所有自定义助手都必须放在那里。
要加载自定义助手,有两种方式 - 全局加载和针对单个路由加载。
全局加载助手
转到 app/Config/helpers.php 目录,并将助手文件名添加到数组中,不包含扩展名(.php)。
CONST CUSTOM_HELPERS = ['myCustomHelperOne', 'myCustomHelperTwo'];
局部加载助手
使用 library() 函数在路由文件中添加自定义助手。下面是示例。
use App\Engine\Libraries\Router;
$router = Router::getInstance();
$router->get('/', function($req, $res) {
// Loading custom helpers
helpers(['myCustomHelperOne', 'myCustomHelperTwo']);
$res->render('welcome', [
'title' => 'APP Title',
'description' => 'This is the APP description'
]);
});
库
要加载库,转到 app/Config/libraries.php 文件,取消注释要加载的库。
图像缩放库
作为图像缩放库,我们使用 - https://github.com/gumlet/php-image-resize
use \Gumlet\ImageResize;
$image = new ImageResize('image.jpg');
$image->scale(50);
$image->save('image2.jpg')
渲染视图
视图位于 app/Views 目录下。您可以从路由或控制器文件中渲染它们。渲染方法位于路由/控制器 $response 参数中。
$router->get('', function($request, $response) {
return $response->render('path/to/view'); // Without extension name
});
验证
验证位于 App\Engine\Libraries\Validation 命名空间下。
- 使用验证 -
use App\Engine\Libraries\Validation; - 初始化 -
$validation = new Validation(); - 查看下面的示例
$router->post('api/one', function($req, $res) {
// Get request data
$body = $req->body();
// Valdiate request data
$valiate = $validation
->with($body)
->rules([
'name|Name' => 'required|alpha',
'username|UserName' => 'required|min[4]|max[20]|alpha_num',
'email|eMail' => 'valid_email|min[5]',
'password|Password' => 'min[5]'
])
->validate();
});
可用的验证器
- alpha
- alpha_spaces
- alpha_num_spaces
- numeric
- alpha_num
- valid_email
- valid_url
- valid_slug
- min[]
- max[]
- ext[jpg,jpeg,gif,bmp]
- min_size[20000]
- max_size[200000]
- required
- valid_input
- string
字段错误信息
<form>
<div>
<input name="username" />
<?= show_error('errors', 'username') ?>
</div>
</form>
文件。
显示文件
public function method($req, $res) {
// Show file/s
$files = $req->files('input-name')->show(string $key);
});
上传文件
public function method($req, $res) {
// Upload file/s
$file = $req->files('input-name')->upload(string $filePath, string $fileName = null);
});
语言和多语言翻译
要激活多语言,请转到 app/Config/app.php 目录并将 MULTILINGUAL 设置为 true
使用CLI创建语言列表
创建语言列表
php cli language:set english en --primary
php cli language:set georgian ge
设置主语言
php cli language:primary ge
获取语言列表
php cli language:list show
删除语言
php cli language:delete en
删除列表
php cli language:refresh all
创建翻译文件
在 app/languages 目录中创建以语言代码命名的文件夹,例如 'en'。
然后创建名为例如 validation 的 .php 文件,并在其中返回键/值对的数组,包含您想要翻译的单词/句子。
return [
'err_name' => 'Name error'
];
为了显示这些翻译,使用命名空间 use App\Engine\Libraries\Languages;
然后 -
<?php
use App\Engine\Libraries\Languages;
Languages::translate('validation.err_name')
行内翻译
您也可以在 html / view 文件中进行翻译。
注意:数组中提供的语言代码必须通过 Engine 的 CLI 创建。请参阅上面的文档。
\App\Engine\Libraries\Languages::translate([
'en' => 'English language',
'de' => 'Englische Sprache'
]);
语言切换路由
$router->get('language/switch/(:alpha)', function($req, $res)
{
$languageCode = urlSegments('last', TRUE);
$languagesList = App\Engine\Libraries\Languages::list();
// Check if language code exists in languages list
if (!array_search_index($languagesList, 'code', $languageCode, false)) return $res->redirectBack();
// Switch language
App\Engine\Libraries\Languages::switch($languageCode);
// Building redirect URL
$prevUrl = explode('/', getFlashData('previous_url'));
array_shift($prevUrl);
array_unshift($prevUrl, $languageCode);
$newurl = join('/',$prevUrl);
if ($req->isAjax()) return $res->send(['url' => URLROOT . "/{$newurl}"]);
return $res->redirect(URLROOT . "/{$newurl}");
});
单例模式
使用CLI创建单例模式
php cli make:singleton className
将在 app/Singleton 目录下生成文件。此文件将从 app/Engine/bootstrap.php 文件中自动加载。
要使用此类,只需加载相应的命名空间
use app\Singleton\ClassName;
public function contorllerName() {
ClassName::getInstance();
}
分页
$totalPages = R::count('pages');
$currentPage = $_GET["page"] ?? 1;
if ($currentPage < 1 OR $currentPage > $totalPages) $currentPage = 1;
$limit = 12;
$offset = ($currentPage - 1) * $limit;
$pagingData = pager([
'total' => $totalPages,
'limit' => $limit,
'current' => $currentPage
]);
$pages = R::find("pages", "order by timestamp asc limit $limit offset $offset");
辅助函数
- str2url(string); // 将字符串作为参数
- urlSegments(int $index = null, bool $removeQuery = false);
- pager(array);
- rrmdir(string); // 将目录路径作为参数
- isJSON(string); // 检查是否为JSON
- toJSON(array); // 数组转换为JSON
- toArray(array); // 数组转换为对象
- array_search_index(array $arr, string $d1, string $d2, $index = true); // 在数组中搜索索引
- array_value_multisort(array $arr, string $key, string $nextArrayKey);
- set_cookie(array $data);
- get_cookie(string $name);
- delete_cookie(string $name);
- setFlashData(string $key, $data);
- hasFlashData(string $key);
- getFlashData(string $key);
- getUserIP();
命令行界面
可以使用命令行命令创建路由和控制器
- 创建路由 -
php cli make:routes filename httpVerb - 创建控制器 -
php cli make:controllers filename methodName - 创建模型 -
php cli make:models modelname - 通过模型方法进行迁移 -
php cli make:migration ModelName - 创建RESTful路由和控制器 -
php cli make:restful Blog/Articles - 创建单例 -
php cli make:singleton className