lumax / luma
一个Luma项目。
Requires
README
欢迎来到Luma,一个有态度的PHP框架。
composer create-project lumax/luma my-luma-project
以下信息可能已过时。本节将保留,直到完成更新文档。
安装
要开始使用Luma,您可以使用Composer轻松设置框架。只需在您的终端中执行以下命令即可
composer create-project lumax/luma
入门
当您的项目通过`create-project`命令安装时,Luma将运行设置后命令以清理您的项目结构,并帮助您尽可能快速地开始。这意味着您的所有PHP库和NPM依赖项都将安装到您的项目中,这意味着您的新Luma应用程序可以直接运行。
可选:使用PHPEnv + Docker
本节提供有关设置Luma应用程序开发环境的信息。如果您已经有了PHP开发环境或熟悉本地运行PHP应用程序,则可以跳过本节。
Luma和PHPEnv配合使用,以提供流畅的开发体验,使您能够尽可能快地开始构建和调试。
注意:PHPEnv需要在您的系统上安装Docker Desktop。
要下载和安装PHPEnv,请运行以下命令全局安装包
composer global require dannyxcii/phpenv
接下来,请确保Docker Desktop正在运行。
现在,在PHPEnv中创建和运行一个新的Luma应用程序就像运行以下命令一样简单
~> composer create-project lumax/luma luma-project ~> phpenv build luma-app ~/luma-project
`phpenv build`命令将显示您的应用程序的本地URL。点击或复制/粘贴URL到您的浏览器中,访问您的新Luma应用程序。设置完成。
有关库的更多详细信息,请参阅PHPEnv README。
配置
路由配置
在`config/routes.yaml`文件中定义您的应用程序的路由。以下是一个示例路由定义(默认包含在您的应用程序中)
routes: index: path: '/' handler: ['App\Controller\AppController', 'index']
在上面的示例中,我们定义了一个根路径的路由,将其指向`App\Controller\AppController`的`index`方法。查看您的应用程序的路由文件和控制台以了解这些是如何工作的。
此外,我们还可以定义动态路由
routes: user_profile: path: '/user/{id}' handler: 'App\Controller\UserController', 'profile'
public function profile(int $id): Response { return $this->respond(`User ${id}`); }
服务配置
服务定义存储在`config/services.yaml`中。以下是一个示例服务配置
services: test_service: class: App\Service\TestService arguments: ['arg1', '@another_service']
服务可以通过使用上述的`@service_id`参数注入到其他服务的构造函数中。服务也可以注入到控制器构造函数中。服务目前不能注入到控制器方法中。
`.env` 文件
Luma使用`vlucas/phpdotenv`包允许您处理环境变量。您的新的Luma应用程序将包括一些默认环境变量,但您可以使用此文件来定义应用程序可能需要的任何自定义环境变量。
此文件中的变量可以通过访问 $_ENV
数组在您的应用程序中进行访问。
目前,您的默认 .env
文件中包含一个已使用的变量: ENVIRONMENT=development
。可选的数据库凭证已提供,但默认情况下已注释。取消注释这些值并提供您的数据库凭证,以便您的应用程序可以连接到数据库并进行操作。
控制器
我们在 路由配置 部分简要介绍了控制器,我们学习了如何定义我们的路由。本节旨在在此基础上扩展,并提供 Luma 应用程序中控制器的概述。
LumaController
LumaController
是 Luma 应用程序中所有控制器的基类。一个简单的“Hello, world!” LumaController
可能看起来像这样
use Luma\Framework\Controller; use Luma\HttpComponent; class HelloWorldController extends LumaController { /** * @return Response */ public function sayHelloWorld(): Response { return $this->respond('Hello, world!'); } }
接下来,我们可以定义一个新的路由,使用这个方法。
# config/routes.yaml routes: say_hello_world: path: '/hello-world' handler: ['App\Controller\HelloWorldController', 'sayHelloWorld']
这将确保您的应用程序中对 /hello-world
的所有请求现在将由 HelloWorldController::sayHelloWorld
方法处理。当达到此端点时,respond
方法将回显文本(Hello, world!
)到页面。
LumaController
还允许我们返回 JSON 响应,非常适合构建 API。这允许我们序列化数组或对象。要从控制器方法返回 JSON 响应,请使用内置的 LumaController::json
方法
public function respondsWithJson(): Response { $dataArray = [ ... ]; return $this->json($dataArray); }
模板引擎
Luma 使用 Latte 模板引擎来渲染动态 HTML 内容。我们可以在 LumaController
中使用 render
方法来渲染视图。此方法接受两个参数:模板文件的名称(带有或没有 .latte
扩展名)以及传递给模板的参数数组。
以下是一个如何在控制器中使用它的示例
<?php use Luma\Framework\LumaController; use Luma\HttpComponent\Response; class ExampleController extends LumaController { public function index(): Response { $data = [ 'title' => 'Welcome to Luma', 'description' => 'A minimalist PHP framework', ]; return $this->render('index', $data); } }
在这个例子中,ExampleController
的 index
方法正在渲染 index.latte
模板,并传递一个数据数组。然后可以在 index.latte
模板文件中按如下方式访问这些数据
{layout 'layout.latte'} <h1>{$title}</h1> <p>{$description}</p>
在这个模板中,{$title}
和 {$description}
是占位符,它们会被传递给 render
方法的 $data
数组中对应的值所替换。
请记住将您的 .latte
文件放置在 Luma 项目的 views
目录中。默认情况下,render
方法会在这个目录中查找模板。
数据库组件
Luma 允许您轻松地将数据库连接到应用程序并进行交互,由 lumax/aurora-db
库提供支持。要开始使用数据库,请取消注释 .env
文件中的 DATABASE_
变量。
DATABASE_SCHEMA
和 DATABASE_DRIVER
变量是可选的 - 如果您希望访问数据库中的所有模式,则可以省略 SCHEMA
变量。如果您的应用程序使用 MySQL 数据库,则不需要包含 DRIVER
变量。
创建数据库表
首先,定义您的数据库表,然后在您首选的控制台中执行。让我们定义一个用于存储用户的表
CREATE SCHEMA User; USE User; CREATE TABLE tblUser ( intUserId INT(11) AUTO_INCREMENT NOT NULL PRIMARY KEY, strUsername VARCHAR(60) NOT NULL, strEmailAddress VARCHAR(255) NOT NULL UNIQUE );
这将在 User
模式下创建一个简单的测试 tblUser
表。
现在,让我们创建一个引用 User.tblUser
表的表
CREATE SCHEMA Core; USE Core; CREATE TABLE tblArticle ( intArticleId INT(11) AUTO_INCREMENT NOT NULL PRIMARY KEY, strTitle VARCHAR(255) NOT NULL, intAuthorId INT(11) NOT NULL, dtmCreatedAt DATETIME NOT NULL DEFAULT NOW(), FOREIGN KEY (intAuthorId) REFERENCES User.tblUser(intUserId) );
Aurora
模型
接下来,我们可以创建 Aurora
模型来与刚才创建的新数据库表进行交互。从用户开始
#[Schema('User')] #[Table('tblUser')] class User extends Aurora { #[Identifier] #[Column('intUserId')] protected int $id; #[Column('strUsername')] private string $username; #[Column('strEmailAddress')] private string $emailAddress; }
这个基本的 Aurora
模型已经非常强大,允许您直接对数据库表执行 CRUD 操作。
以下是我们可以为我们的 Article
表创建的 Aurora 模型的示例
#[Schema('Core')] #[Table('tblArticle')] class Article extends Aurora { #[Identifier] #[Column('intArticleId')] protected int $id; #[Column('strTitle')] private string $title; #[Column('intAuthorId')] private User $author; #[Column('dtmCreatedAt')] private \DateTimeInterface $created; /** * @param string $title * * @return void */ public function setTitle(string $title): void { $this->title = $title; } }
使用 Aurora
模型
如上例所示,一个 Aurora
模型很小,它简单地提供了 PHP 中数据库行的 表示。在我详细说明如何使用您的 Aurora
类与数据库交互的各种方法之前,理解一些重要的规则非常重要
- 所有扩展
Aurora
的类 必须 有一个主标识符,由#[Identifier]
属性指示。 - 所有主标识符 必须 被保护(或公开,但不建议)。
- 您希望映射到数据库列的所有属性 必须 包含一个
#[Column($name)]
属性。
创建
我们可以轻松地使用 create
方法在我们的数据库中创建新记录
// Create a new User instance. We can pass in property OR column names. $user = User::create([ 'username' => 'Danny', 'emailAddress' => 'test@test.com', ]); // Save the new User to the database. $user->save(); Article::create([ 'title' => 'First Post!', 'author' => $user, ])->save(); Article::create([ 'title' => 'Second Post!', 'author' => $user, ])->save();
读取
我们可以轻松地使用 find
和 findBy
方法检索记录
$user = User::find(1); // Danny $article = Article::findBy('title', 'Second Post!'); $articles = Article::all(); $article = Article::getLatest(); $articleCount = Article::count();
更新
save
方法还允许我们更新现有记录
$article = Article::findBy('title', 'First Post!'); $article->setTitle('First Post... Improved!'); $article->save();
删除
我们也可以非常容易地 delete
现有的记录
$article = Article::find(2); $article->delete();
查询构建器
除了上述方法外,Luma + Aurora DB 还允许您通过内置的查询构建器构建更复杂的查询。我们首先构建我们的查询
// Select all columns from the Article table $article = Article::select(); // Execute the query $article = $article->get();
上面的代码片段执行了 SELECT * FROM Core.tblArticle
。select
方法允许您指定您希望返回和映射的列。您可以使用属性或列的名称进行指定
$article = Article::select('title')->get();
注意:查询构建器将 始终 返回主标识符,因此您无需明确指定。
我们还可以使用 whereIs
、whereNot
、whereIn
和 whereNotIn
方法指定条件。这些可以链接,此时它们将自动转换为 AND
// Returns an Article instance as there is only one result $article = Article::select() ->whereIs('title', 'Second Post!') ->get(); // Returns an array (Article[]) as there is more than one result $articles = Article::select() ->whereNot('title', 'Does not exist!') ->get(); // Returns an array (Article[]) $articles = Article::select() ->whereIn('id', [1, 2]) ->get(); // Returns NULL as there are no results for this query $articles = Article::select() ->whereNotIn('id', [1,2]) ->get();
我们还可以添加 orderBy
和 limit
条件
$articles = Article::select() ->orderBy('id', 'DESC') ->get(); $article = Article::select() ->orderBy('id', 'DESC') ->limit(1) ->get();
附加功能
HTTP客户端
Luma提供了一个内置的 HttpClient
类来帮助简化PHP中的HTTP请求。使用它非常简单
$httpClient = new HttpClient(); // Methods also provided for POST, PUT, PATCH and DELETE $response = $httpClient->get('/endpoint', $headersArray, $bodyString);
缓存
Luma通过在 cache/views
目录中缓存视图来优化性能,提供了一种简单的方法来减少每次请求渲染模板的开销。
日志
Luma与 tracy/tracy
包集成,以实现简单的日志记录。日志存储在本地 logs/info.log
中,允许您跟踪有关应用程序行为的关键信息。以下是您可以在应用程序中使用它的方法
Debugger::log('Exception: ' . $exception->getMessage());