steevedroz/ci4-base

提供了一组非常实用的组件,可以从中继承

1.5.1 2023-02-21 13:14 UTC

This package is auto-updated.

Last update: 2024-09-21 16:53:38 UTC


README

这个库提供了一个非常简单的方法来设置CodeIgniter项目的基架。

安装

为了安装此包,请在CodeIgniter根目录下调用 composer require steevedroz/ci4-base

然后,您必须从您的仓库运行 composer update

设置

自动脚本

通过运行 vendor/bin/ci4-generate,将自动生成下面提到的 template.htmlBaseController.php 文件。

最小配置

基控制器需要最小配置才能按预期工作。

首先,您必须创建一个模板文件在位置 app/Views/template.html。此文件的详细内容将在下面描述。

然后,您应该通过编辑 app/Config/App.php 添加一个新的属性 Config\App::siteName,如下所示

<?php namespace Config;

use CodeIgniter\Config\BaseConfig;

class App extends BaseConfig
{
	public $siteName = '<your site name>';

    // the rest of the class
}

应创建文件夹以包含CSS和JavaScript,它们是: public/csspublic/js。所有 .css 和 .js 文件必须放在这些文件夹中。

无需进一步设置。

template.html 的内容

模板文件必须包含一个有效的HTML,包括一个doctype和W3C指定的标准 <html> 基础画布。

在此文件中,可以放置一些占位符

  • {template_page_title} 将显示页面标题。 Config\App::siteName 将在那里使用,因此如果您选择使用该占位符,则必须创建它。
  • {template_css} 将显示所有所需的CSS <link> 代码。这应该放置在HTML页面的 <head> 部分。
  • {template_js} 将以相同的方式处理JavaScript <script> 代码。这应该放置在HTML页面的 <head> 部分。
  • {template_content} 将包含每次调用都不同的页面部分。

示例 template.html 文件可能如下所示

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
    <meta charset="utf-8">
    <title>{template_page_title}</title>
    {template_css}
    {template_js}
</head>

<body>
    <header></header>
    <main>{template_content}</main>
    <footer></footer>
</body>

</html>

BaseController

为了使用基控制器,首先创建一个扩展 SteeveDroz\CiBase\BaseController 的控制器。然后,该控制器有以下几个新选项,如下所述。

显示页面

BaseController 的基本用法如下

  1. 创建一个名为控制器方法的HTML页面。例如,对于 User::show 方法,创建文件 app/Views/user/show.html。在那里,只放置应插入模板中的页面片段。
  2. 从控制器中调用 $this->render(); 来显示模板文件,并带有给定的片段页面。

示例

<!-- app/Views/user/show.html -->
<h1>User page</h1>
<p>Welcome on the user page!</p>
<?php namespace App\Controllers;

use SteeveDroz\CiBase\BaseController;

class User extends BaseController
{
    public function show()
    {
        $this->render();
    }
}

特定模板

您可以通过从当前控制器或从 BaseController 中的 init() 调用 $this->setTemplate('some-template.html') 来指定不同的模板页面。

特定页面

而不是创建一个与名称匹配的页面,可以在 app/Views 中创建任何页面,并指定其名称作为参数: $this->render('some-page.html');。可以省略 .html 扩展名。

插入数据

BaseController 库使用CodeIgniter4解析器来显示页面。为了使用它,您可以在两步中插入数据

  1. 在您的页面片段中添加所需的占位符(例如,在 app/Views/user/show.html 中)。此占位符必须放在大括号中(例如: {username})。
  2. 在控制器中,使用 data 属性设置占位符的值,例如:$this->data['username'] = 'john-doe';

如果数据是数组,可以将大括号占位符替换为开闭大括号,详情请参考CodeIgniter 用户指南

原始数据

为了插入原始数据(即应被解释而非转义的包含 HTML 的数据),您可以从控制器中设置 $this->rawData 而不是 $this->data

示例:$this->rawData['description'] = '这是最好的描述!<em>best</em>';

注意:请谨慎使用,绝不要与用户内容一起使用!这可能是您代码中主要安全漏洞的来源。

添加 CSS

为此,需要在 app/Views/template.html<head> 标签中放置 {template_css}

从控制器中,您可以调用 $this->css() 方法并指定要包含的文件,以及可选的媒体类型。

这些选项都是兼容的

  1. 可以省略 .css 扩展名: $this->css('style')$this->css('style.css')
  2. 资源可以是本地资源(相对于 public/css)或远程资源(以 http(s):// 开头)。
  3. 第二个参数是精灵图(spritesheet)的媒体类型(screenprintspeech 等)。默认值为 all

添加 JavaScript

为此,需要在 app/Views/template.html<head> 标签中放置 {template_js}

从控制器中,您可以调用 $this->js() 方法并指定要包含的文件,以及可选地指定脚本是否需要在 DOM 准备完成之前调用。

这些选项都是兼容的

  1. 可以省略 .js 扩展名: $this->js('script')$this->js('script.js')
  2. 资源可以是本地资源(相对于 public/js)或远程资源(以 http(s):// 开头)。
  3. 第二个参数(可选)是指定资源是否必须在 DOM 准备完成后加载(默认为 true)。
  4. 第三个参数(可选)是一个包含附加参数的数组,例如 ['integrity' => 'sha256-yadaYadaYadaSha256IntegrityHash=', 'crossorigin' => 'anonymous']

示例控制器

<?php namespace App\Controllers;

use SteeveDroz\CiBase\BaseController;

class Article extends BaseController
{
    public function index()
    {
        // Set page title
        $this->data['page_title'] = 'Articles';

        // Set a normal placeholder
        $this->data['articles'] = $someModel->findAll();

        // Set a raw placeholder
        $this->rawData['hint'] = 'Press the <strong>?</strong> icon for help';

        // Set CSS files
        $this->css('menu'); // without .css
        $this->css('table.css'); // with .css
        $this->css('pages', 'print'); // with media type
        $this->css('https://example.com/layout.min.css'); // remote location

        // Set JS files
        $this->js('script'); //without .js
        $this->js('game.js'); // with .js (both work)
        $this->js('User', false); //without defer
        $this->js('https://code.jqueryjs.cn/jquery-3.5.1.min.js', false, ['integrity' => 'sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=', 'crossorigin' => 'anonymous']); // remote location

        // Display a page with the same name as the current controller
        // (app/Views/article/index.html)
        $this->render();

        // ALTERNATIVELY, display a specific page
        // (app/Views/example.html)
        $this->render('example');
    }
}

关于自动路由改进(自 CodeIgniter 4.2.0 起使用)

从 4.2.0 版本开始,已不再可能自动路由如 User::login 等方法。相反,必须定义 User::getLoginUser::postLogin 来通过 GETPOST 访问。

ci4-base 1.5.0 可以检测此类方法的名称,并可以在不使用前缀的情况下链接到具有相同名称的视图。

示例

class User extends BaseController
{
    public function getLogin()
    {
        // code
        $this->render();
    }

    public function postLogin()
    {
        // code
        $this->render();
    }
}

这两个方法都会显示 app/Views/user/login.html 中的内容。

警告:只有 GETPOST 方法以此种方式工作,因为这个库并不旨在用于处理 PUTDELETE 请求。

BaseModel

基础模型更简洁,尽管提供的选项将为您节省大量时间。

要使用它,只需让您的模型继承 SteeveDroz\CiBase\BaseModel 即可。

处理事件

当与 CodeIgniter 模型事件一起工作时,可能会对 afterFind 参数的内容感到有些困惑。通过使用 applyOnFind() 方法,基础模型将检测您是否正在处理单个或多个条目,并相应地执行所需的操作。

要利用此方法的功能,必须首先使用 afterFind 事件。

该方法接受两个参数:$data 属性和要应用于每个条目的回调函数。

回调函数接受一个参数,代表单个元素。如果数据通过find()first()从数据库中检索,则回调函数将被应用于找到的条目。如果通过findAll()检索,它将单独应用于每个找到的条目。

示例模型

<?php namespace App\Models;

use SteeveDroz\CiBase\BaseModel;

class User extends BaseModel {
	protected $table = 'users';
	protected $allowedFileds = ['first_name', 'last_name', 'email'];

	protected $afterFind = ['addFullName'];

	/* Adds a `full_name` field to each user.
	 * [
	 *   'first_name' => 'John',
	 *   'last_name' => 'Doe',
	 *   'email' => 'john.doe@example.com'
	 * ]
	 *
	 * becomes
	 *
	 * [
	 *   'first_name' => 'John',
	 *   'last_name' => 'Doe',
	 *   'email' => 'john.doe@example.com',
	 *   'full_name' => 'John Doe'
	 * ]
	 */
	public function addFullName($data)
	{
		return $this->applyOnFind($data, function($user)
		{
			$user['full_name'] = $user['first_name'].' '.$user['last_name'];
			return $user;
		});
	}
}

// ---

$user = $model->find(1); // $user will have a `full_name`
$user = $model->where('email', 'contact@example.com')->first(); // $user will have a `full_name`
$users = $model->findAll(); // each user in $users will have a `full_name`

贡献

以问题或合并请求的形式做出的贡献是非常受欢迎的!

如果你是编程新手,对CodeIgniter 4不熟悉,或者不确定自己是否有能力参与这个项目,请无论如何考虑做出贡献!作为一名计算机科学教师,我愿意查看你的代码并帮助你改进它。说真的,我是认真的!毕竟,是Git,你无法破坏任何东西...