roco / nanoframe
一个极其简单的PHP框架
Requires
- php: >=7.4
- vlucas/phpdotenv: ^5.6
README
NanoFrame是一个极其简单的PHP框架。适用于需要动态性和速度的小型项目。
安装
克隆存储库或手动下载文件到您的目录
git clone https://github.com/your-username/nanoframe.git
使用composer
composer create-project roco/nanoframe meu-diretorio
将 meu-diretorio 替换为您希望项目运行的目录名。
上面的命令将创建一个名为 meu-diretorio 的文件夹。
如果您省略了“meu-diretorio”参数,则命令将创建一个名为“nanoframe”的文件夹,可以根据需要重命名。
使用
设置路由
在 app/Config
目录下的 route.php
文件中定义您的路由
// routes.php return [ 'index' => 'HomeController', 'sobre' => 'AboutController', 'contato[POST]' => 'ContactController', 'admin[GET]' => 'admin\AdminController', 'admin/dashboard[GET]' => 'admin\DashboardController', ];
在此示例中,路由 index
映射到 HomeController
。由于 index
是默认路由,应将其设置为入口路由。路由 about
映射到 AboutController
,路由 contact
(使用 [POST]
)指定只接受POST请求并映射到 ContactController
。此外,路由 admin
映射到 AdminController
,路由 admin/dashboard
映射到 DashboardController
。
您还可以通过在方括号中用逗号分隔每个方法来指定多个允许的方法。例如:[GET,POST]
(默认情况下,系统假定所有未指定方法的路由为 GET
)
路由中的子命名空间
您可以使用方括号在路由中定义子命名空间。例如:
// Routes.php return [ 'admin[GET]' => 'admin\[Admin\AdminController]', 'admin/dashboard[GET]' => 'admin\[Admin/DashboardController]', ];
在此示例中,路由 admin
指定 AdminController
,路由 admin/dashboard
指定 DashboardController
,两者都在 Admin
命名空间内。
默认情况下,您创建的每个控制器都必须位于根命名空间 App/Controller
内。在上面的示例中,控制器被分离到一个特定的子命名空间中,用于您的用例,命名空间定义如下:namespace App/Controller/Admin;
通配符
您可以使用一些通配符,它们是应用于路由的正则表达式的别名。
(:any)
// Routes.php return [ 'admin/dashboard/produtos/(:any)' => 'admin\ProductController', ];
上述路由接受“admin/dashboard/produtos/”之后URL的任何字母数字段。
(:num)
// Routes.php return [ 'admin/dashboard/produto/(:num)' => 'admin\ProductController', ];
上述路由接受“admin/dashboard/produtos”之后URL的任何数字段。
单词边界:\b(str1|str2)\b
// Routes.php return [ '/admin/\b(painel|dashboard)\b)' => 'admin\DashboardController', ];
在上面的示例中,目标是使路由有效,如果它以“admin/”开头并且下一个段是“painel”或“dashboard”。
控制器
在 controller
目录中创建您的控制器。控制器应遵循PSR-4命名约定。
您的控制器应扩展Nanoframe的基础控制器 BaseControler
。
// HomeController.php namespace App\Controller; use Nanoframe\Core\BaseController; class HomeController extends BaseController { public function index() { echo "Bem-vindo à página inicial!"; } } // admin/AdminController.php namespace App\Controller\Admin; use Nanoframe\Core\BaseController; class AdminController extends BaseController { public function index() { echo "Bem-vindo ao painel de administração!"; } } // admin\DashboardController.php namespace App\Controller\Admin; use Nanoframe\Core\BaseController; class DashboardController extends BaseController { public function index() { echo "Este é o painel!"; } }
模型
在 model
目录中创建您的模型。模型应遵循PSR-4命名约定。
您的模型应扩展Nanoframe的基础模型 BaseModel
。
BaseModel
类是用于与您的数据库 MYSQL
交互的抽象层。
<?php namespace App\Model; use Nanoframe\Core\BaseModel; class OrderModel extends BaseModel { public function getOrder($orderId) { return $this->db->table('orders')->where('id = ?', [ $orderId ])->get(); } public function register($data) { $this->db->table('orders')->insert($data); return $this->db->insertId(); } }
以下是一些使用示例
属性
host
:存储数据库的主机地址。dbname
:存储数据库名称。username
:存储数据库用户名。password
:存储数据库密码。conn
:存储PDO连接对象。table
:指定用于查询的表。select
:指定要检索的列。where
:指定WHERE子句以过滤结果。whereIn
: 指定WHERE IN子句以过滤具有值列表的结果。orderBy
: 指定ORDER BY子句以排序结果。limit
: 指定LIMIT子句以限制结果数量。params
: 存储准备指令的参数数组。
方法
查询构建器方法
table($tableName)
: 定义查询中使用的表名。select($columns)
: 定义要检索的列。where($condition, $params = [])
: 向查询添加WHERE子句。whereIn($indexColumn, $params = [])
: 向查询添加WHERE IN子句。orderBy($column, $direction = 'ASC')
: 向查询添加ORDER BY子句。limit($count, $offset = 0)
: 向查询添加LIMIT子句。
数据处理方法
insert($data)
: 在数据库中插入新行。insertBatch($data)
: 在数据库中插入多行。replace($data)
: 替换数据库中的现有行。replaceBatch($data)
: 替换数据库中的多行。update($data)
: 更新数据库中的现有行。updateBatch($data, $indexColumn)
: 基于索引列更新数据库中的多行。delete()
: 从数据库中删除行。
数据检索方法
getArray()
: 以关联数组的形式检索所有行。get()
: 以对象数组的形式检索所有行。getRow()
: 检索第一行作为对象。
其他方法
query($sql, $params = [])
: 允许直接执行自定义SQL查询。resetWrite()
: 重置所有写入属性到初始状态。
事务
管理数据库事务的方法也将通过QueryBuilder在您的模型中可用。您可以使用“beginTransaction”,“commit”,“rollBack”方法来启动、确认或撤销事务。以下是一个在模型中代码片段的示例
$this->db->beginTransaction(); try { // Primeira operação $this->db->table('table1')->insert([ 'column1' => 'value1', 'column2' => 'value2' ]); // Segunda operação $this->db->table('table2')->update([ 'column1' => 'new_value' ], ['id' => 1]); // Commit da transação $this->db->commit(); echo "Transação concluída com sucesso!"; } catch (\Exception $e) { // Rollback da transação em caso de erro $this->db->rollback(); echo "Erro: " . $e->getMessage(); }
您还可能需要在控制器中调用不同模型的 方法,并在数据库的不同表中执行多个操作。在这种情况下,您可以使用 Transactor 类来保持事务控制,当您按顺序使用多个模型时。
以下是一个可能的控制器方法中的代码片段
$transation = new Transactor; $userModel = new UserModel; $docModel = new DocModel; $addressModel = new AddressModel; try{ $transation->beginTransaction(); $userId = $userModel->create($dataUser); $docId = $docModel->create($dataDocs, $userId); $addressModel->create($dataAddress, $userId); $transation->commit(); } catch (\Exception $e) { // Rollback da transação em caso de erro $transation->rollback(); echo "Erro: " . $e->getMessage(); }
加载器
视图
视图文件应位于 app/Views
目录中,并使用NanoFrame核心的 Loader
加载。BaseController 已在 $this->load
中具有此Loader的实例。
// HomeController.php namespace App\Controller; use Nanoframe\Core\BaseController; class HomeController extends BaseController { public function index() { $data = [ 'valor' => 100, 'cor' => 'azul' ]; $this->load->view('contato', $data); } }
在上面的示例中,视图文件 contato.php
显示在屏幕上,并且还传递了两个变量,这些变量将在此视图文件中使用 $valor
和 $cor
。
方法view中还可用第三个参数,默认设置为FALSE。如果设置为true,则 "$html = Loader::view('contato', $data, TRUE)
",而不是在屏幕上打印数据,函数返回此视图编译后的HTML字符串。
Utils
工具文件应位于 app/Utils
目录中,它们应该是具有显式函数的PHP文件,而不是类文件。应使用NanoFrame核心的 Loader
加载它们。BaseController 已在 $this->load
中具有此Loader的实例。
可以传递一个文件名或文件名数组。
// HomeController.php namespace App\Controller; use Nanoframe\Core\BaseController; class HomeController extends BaseController { public function index() { $this->load->utils('meuUtil1'); minhaFuncao1(); } public function loremIpsum(){ $this->load->utils(['meuUtil1','meuUtil2']); minhaFuncao1(); minhaFuncao2(); } }
在上面的例子中,文件 meuUtil.php
被加载,并且该文件中的 minhaFuncao
函数被执行。
服务器请求(输入)
可以使用类 Input
来获取请求的数据。在 BaseController
中,已经有一个该类的实例在 $this->input
中。默认情况下,已经应用了基本的字符串清洗过滤器来保持数据的安全,如果要避免清洗,只需将第二个参数传递为 FALSE
。
// HomeController.php namespace App\Controller; use Nanoframe\Core\BaseController; class HomeController extends BaseController { public function index() { // obtem todos dados de $_GET com a limpeza da string já aplicada $var1 = $this->input->get(); // obtem todos dados sem aplicar a limpeza da string $var2 = $this->input->get(NULL, FALSE); // obtem o email de $_GET $var3 = $this->input->get('email'); // obtem o name e email de $_GET $var4 = $this->input->get(['name', 'email']); } }
可以按照上面的例子中的方式使用,例如对于 post
使用 $this->input->post()
,对于 get
或 post
使用 $this->input->getPost()
,对于 PUT
、DELETE
和 PATCH
方法应该使用 $this->input->inputStream()
。
迁移
一个专注于 MySQL 的迁移系统可以通过 CLI 使用。只需访问终端并使用以下命令:
php cli.php Command/Migrate parametro_desejado
可用的参数有
make:创建迁移文件的创建方法。
latest:迁移到最新的迁移版本。
rollback:迁移到指定的版本。
combine:创建一个包含所有可用迁移的合并文件。
info:一个表格,显示迁移的状态信息。
help:显示帮助部分。
迁移文件将保存在 app/Migrations
目录中(仅为此目的保留的目录)。
使用迁移系统时,将在数据库中自动创建一个名为 migrations
的表,用于控制数据库中的迁移版本。
使用 make 命令时,将被提示输入迁移名称(例如:create_user_table)和表名(例如:user)。将在迁移目录中创建一个带有时间戳后缀的迁移名称文件。在此文件中,您应使用 up() 和 down() 函数来设置对数据库的更改,创建更新或撤销更改。所有迁移文件都扩展了 DatabaseForge
类的功能,包括创建、删除表,创建外键、索引等。请使用该类提供的方法来开发您的迁移。
创建迁移后,可以使用以下命令将数据库迁移到最新版本:php cli.php Command/Migrate latest
要撤销更改并迁移到之前的版本,可以使用以下命令:php cli.php Command/Migrate last
请注意,down() 方法必须正确配置,以便能够撤销 up() 方法所做的更改。
使用 rollback 命令可以回滚到数据库的特定版本。将被提示输入版本号(文件的时间戳)。
在开发应用的过程中,您的 migrations
目录可能会变得非常“膨胀”,随着应用的增长,会有许多迁移文件。考虑到这一点,可能需要将所有这些文件合并到一个迁移文件中。这对于保持事物整洁非常有用。要执行此操作,请运行以下命令:php cli.php Command/Migrate combine
所有现有的迁移文件将被合并到一个文件中。在过程结束时,将询问您是否要删除原始文件。如果确认,所有原始文件将被删除,您将只有合并后的迁移文件。如果不确认,则不会执行删除。您可以分析生成的文件,而不删除原始文件,但在继续之前,您必须删除原始文件。保留文件并再次运行升级或降级迁移版本的命令将导致版本冲突,因为所有文件都已合并到一个文件中。
实体
您还可以使用Nanoframe的标准命令来简化创建数据库实体的过程。只需访问终端并使用以下命令:
php cli.php Command/Entity create
系统会询问您是否要为数据库中的所有表创建实体,或者直接指定某些实体。相关的类将被保存在app/Entity
目录下。这些类仅作为基本模型,请根据您的需求调整生成的文件。
贡献
请随时通过创建问题或发送拉取请求来贡献。
许可证
本项目采用MIT许可证 - 请参阅LICENSE文件以获取详细信息。