momentphp/文档

此软件包最新版本(dev-master)没有可用的许可信息。

MomentPHP | 框架文档

安装: 169

依赖项: 1

建议者: 0

安全: 0

星星: 1

关注者: 2

分支: 1

开放问题: 0

语言:HTML

dev-master 2016-05-11 22:26 UTC

This package is auto-updated.

Last update: 2024-09-16 06:56:14 UTC


README

MomentPHP是一个轻量级且直观的PHP迷你框架,它允许模块化应用程序设计。前缀迷你意味着它可以在微型和全栈框架之间使用。它提供了创建网站和Web应用程序所需的最基本功能。最重要的是,它为您的代码提供“结构”,并让您自由选择是否添加其他工具。它建立在PHP社区中知名的库和解决方案之上。

  • Slim微型框架
  • Twig / Smarty模板引擎(两者都支持即装即用)
  • 来自Laravel框架的数据库访问、配置和缓存组件
  • Composer依赖项管理器

该框架(以及其构建块)采用流行的Web软件设计模式,例如

安装

MomentPHP需要以下软件栈才能运行

  • 一个Web服务器,如Apache或Nginx(有关Slim文档中的Web服务器设置的更多信息)
  • PHP 5.5.9或更高版本(也支持PHP 7!)
  • 安装并使PHP可用的ionCube Loader模块(如果您需要非编码版本,请发送电子邮件 - 您可以在主页底部找到相关地址)
  • Composer依赖项管理器

还建议(但不是必需)启用以下PHP模块

本地设置

以下是在Windows上使用XAMPP设置框架的步骤指南

  • 创建项目文件夹:C:\xampp\htdocs\momentphp
  • 在项目文件夹中执行以下命令(这将安装应用程序骨架及其依赖项)
composer create-project momentphp/app . --stability=dev
  • 创建用于托管应用程序的域名(在此示例中为momentphp.local)。通过在以下文件中添加以下虚拟主机配置来完成此操作:C:\xampp\apache\conf\extra\httpd-vhosts.conf
<VirtualHost *:80>
    DocumentRoot "C:\xampp\htdocs\momentphp\web"
    ServerName momentphp.local
    <Directory "C:\xampp\htdocs\momentphp\web">
        Options All
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
  • 将新的域名定义添加到操作系统的hosts文件中(C:\WINDOWS\system32\drivers\etc\hosts
127.0.0.1 momentphp.local
  • 重新启动Apache Web服务器

完成上述步骤后,将浏览器指向http://momentphp.local,您应该会看到带有一些调试信息的框架欢迎页面。

服务

简单来说,一个 服务 通常是一个执行某些任务(如发送电子邮件、渲染模板或持久化信息到数据库)的PHP对象。一个 服务容器(或依赖注入容器)是一个管理服务实例化(及其依赖关系)的PHP对象。MomentPHP使用Slim提供的默认服务容器——Pimple。您可以通过$app对象(作为框架类中的一个属性可用)注册和检索服务,这是一个momentphp\App类的实例。

以下是通过$app实例从容器中检索config服务的示例方法

$app->get('/', function () { // inside route callable
    $config = $this->app->config;
});
$this->app->config // inside controller, model etc.
{{ this.app.config }} // inside Twig template
{$this->app->config} // inside Smarty template

您还可以直接使用服务容器检索服务

$config = $app->getContainer()->get('config');
// or
$app->get('/', function () {
    $config = $this->get('config');
});

还有一个全局辅助函数app(),它允许访问容器中的服务。它几乎可以在任何地方使用(例如在配置文件中)

return [
    'compile' => path([app('pathStorage'), 'templates', 'smarty', app()->fingerprint()]),
]

请注意,如果您不提供服务名称,app()函数将返回应用程序实例。

注册服务

为了注册一个新服务,必须给它一个 名称。服务名称应该是唯一的,并且采用 camelCase 格式。您可以使用方便的 momentphp\App::service() 辅助方法注册服务,该方法返回对象的 相同共享实例 以供所有调用

$app->service('someService', function ($container) {
    $otherService = $container->get('otherService'); // you may access other services in the container
    return new Object($otherService);
});

您可能需要直接使用服务容器来注册非共享服务。例如,如果您希望所有调用都返回不同的 实例

$app->service('someService', $app->getContainer()->factory(function ($container) {
    return new Object;
}));

您还可以注册 匿名函数作为服务。该函数将被返回而不会被调用

$app->service('someService', $app->getContainer()->protect(function ($name) {
    return 'Hello ' . $name;
}));

在某些情况下,您可能想在服务定义后 修改服务

$app->getContainer()->extend('someService', function ($service, $container) {
    $service->setParam();
    return $service;
});

服务提供者

服务提供者负责注册服务,并位于包内的 /providers 文件夹中。服务提供者类应扩展 momentphp\Provider 并实现 __invoke() 方法

namespace bundles\welcome\providers;

class TestProvider extends \momentphp\Provider
{
    public function __invoke()
    {
        $this->app->service('test', function() {
            return 'Test Service';
        });
    }
}

服务提供者通过配置加载。为了加载上述服务提供者,您必须在 /config/app.php 中放置以下行

'providers' => [
    'test' => 'TestProvider',
],

您还可以卸载由先前包加载的服务提供者(见 包继承

'providers' => [
    'test' => false
]

请注意,您可以将默认服务提供者选项放在 /config/providers.php 中,然后通过 $this->options() 在类中访问这些选项——见 实例配置

您还可以实现 Provider::boot() 方法。此方法在所有其他服务提供者都已注册后调用,这意味着您可以访问已注册的所有其他服务。

重要的框架服务

大多数框架功能都是作为服务构建的。以下表格列出了重要服务及其名称和简要说明

MomentPHP最强大的功能之一是其包系统。包是提供一定功能的微型应用程序。在您的应用程序中有一个功能强大的用户管理模块、简单的博客或网络服务模块吗?将其打包成包,以便在应用程序之间重复使用并与社区共享。您的应用程序可以使用多个包。

创建新的包

默认情况下,包放置在 /bundles 文件夹中(假设您正在使用 app骨架)。每个包都应该有自己的 唯一命名空间。如果我们想创建 helloWorld 包,我们首先应该创建包类文件 /bundles/helloWorld/Bundle.php,内容如下

namespace bundles\helloWorld;

class Bundle extends \momentphp\Bundle
{
}

包类文件的位置决定了包根目录。在这个目录中,您可以放置各种包资源(配置、路由、模板)和类(模型、控制器等)。理论上,只要Composer的自动加载器能够定位到包类文件,包就可以放在文件系统的任何位置。

每个包都有一个别名,它是包命名空间的小写版本,其中命名空间分隔符(\)被点替换。

别名被用于框架的各个部分 - 例如,从特定包加载模板。您可以通过$app->bundles('bundles.helloworld')方法获取包对象。同时,您可以在加载包时更改默认别名。

$app = new momentphp\App([
    bundles\helloWorld\Bundle::class => ['alias' => 'hello'],
]);

momentphp\Bundle::boot()回调(如果实现)在响应发送到客户端之前被调用。它可以用来执行一些逻辑(例如,设置一些全局PHP设置)。

namespace bundles\helloWorld;

class Bundle extends \momentphp\Bundle
{
    public function boot()
    {
        ini_set('memory_limit', '2048M');
    }
}

包文件夹结构

加载包

应用程序在主index.php文件中加载包,该文件作为响应所有传入请求的前端控制器。

$app = new momentphp\App([
    bundles\helloWorld\Bundle::class,
    ...
]);

在加载包时,除了定义自定义别名外,您还可以选择禁用加载某些资源或类。

/**
 * Do not load configuration, routes and models from helloWorld bundle
 */
$app = new momentphp\App([
    bundles\helloWorld\Bundle::class => [
        'skipResource' => ['config', 'routes'],
        'skipClass' => ['models'],
    ],
]);

包继承

包继承是MomentPHP最强大的功能之一。如前所述,应用程序可以使用多个包。加载包的顺序很重要。链中的下一个包可以覆盖上一个包的资源。为了说明这个过程,让我们假设应用程序加载了两个包。

$app = new momentphp\App([
    bundles\first\Bundle::class,
    bundles\second\Bundle::class
]);

配置

为了覆盖来自第一个包的配置,您需要在第二个包中创建具有相同名称的配置文件,但仅包含您希望覆盖的选项(参见配置)。

路由

为了覆盖来自第一个包的路由,您需要在第二个包中创建具有相同URL模式但不同处理器的路由(参见路由)。

模板

为了覆盖来自第一个包的特定模板

/bundles/first/templates/partials/post.tpl

第二个包中创建具有相同名称的模板文件

/bundles/second/templates/partials/post.tpl

有关更多信息,请参见模板

为了覆盖基于类的资源(如控制器模型等),创建具有相同名称的相应类文件并扩展合适的父类

namespace bundles\second\models;

class PostModel extends \bundles\first\models\PostModel
{
    public function index()
    {
        return parent::index();
    }
}

配置

配置存储在每个包的/config文件夹中的纯PHP文件中。每个文件应返回一个选项数组。建议为每个配置选项类别创建单独的文件。如果我们想存储我们应用程序的API密钥,我们可以在/config/api.php文件中创建以下内容

return [
    'Google' => [
        'Recaptcha' => [
            'publicKey' => 'fc2baa1a20b4d5190b122b383d7449fd',
            'privateKey' => '4f14fbe4af13860085e563210782da88'
        ]
    ],
    'Twitter' => 'f561aaf6ef0bf14d4208bb46a4ccb3ad'
];

配置服务允许您在任何地方访问上述配置值

$app->config->get('api.Google.Recaptcha.publicKey'); // returns single key
$app->config->get('api'); // returns whole array

您还可以指定默认值,如果配置选项不存在则返回

$app->config->get('api.Instagram', 'bf083d4ab960620b645557217dd59a49');

配置值也可以在运行时设置

$app->config->set('api.Yahoo', '241fe8af1e038118cd817048a65f803e');

还有一个方便的方法可以检查给定配置键的存在性

$app->config->has('api.Github'); // false

环境特定的配置

根据应用程序运行的环境有不同的配置值通常很有帮助。默认情况下,应用程序环境设置为production。您可以在主index.php文件中更改环境设置

$app = new momentphp\App([...], [
    'env' => 'development',
    'pathBase' => $pathBase,
    'pathWeb' => __DIR__,
]);

要覆盖开发环境(如上所述)的配置,只需在/config目录下创建一个与环境名称匹配的文件夹。接下来,创建要覆盖的配置文件并指定该环境的选项。例如,要覆盖开发环境的调试标志,您需要创建一个包含以下内容的/config/development/app.php文件

return [
    'displayErrorDetails' => true
]

默认配置文件名

框架将其配置存储在一系列预定义的文件中

实例配置

许多框架类使用momentphp\traits\OptionsTrait提供的配置能力。它提供了一个无需创建不必要的类属性的简洁解决方案。首先,您可以在类内部硬编码配置

class PostModel extends Model
{
    protected $defaults = [
        'listing' => [
            'perPage' => 10
        ]
    ];
}

硬编码的选项将与在对象初始化期间传递给构造函数的选项合并。对于控制器、模型、助手、服务提供者和中间件,您可以通过创建适当的配置文件来定义传递给构造函数的配置选项。例如,对于上面的PostModel,我们可以创建一个包含以下内容的/config/models.php文件

return [
    'Post' => [
        'listing' => [
            'perPage' => 20,
            'more' => true,
        ]
    ]
];

您可以通过options()方法在实例创建后获取和设置模型配置

$this->Post->options('listing.perPage'); // get
$this->Post->options('listing.perPage', 5); // set

模型

在MVC模式中,模型类负责向控制器提供来自各种来源的数据:数据库、磁盘上的文件,甚至是外部Web服务。MomentPHP模型类位于包内的/models文件夹中。

以下是一个来自假设的blog包的模型定义的简单示例

namespace bundles\blog\models;

class PostModel extends \momentphp\Model
{
    public function findAll()
    {
        return $this->db()->table('posts')->get();
    }

    public function findById($id)
    {
        return $this->db()->table('posts')->where('id', $id)->first();
    }
}

在模型方法中,您可以通过momentphp\Model::db()方法访问数据库连接对象。请参阅Laravel的文档了解如何使用此对象创建简单和高级查询

请注意,当需要时才会懒加载连接,因此模型可能根本不使用数据库 - 例如,可以与Web服务通信。

连接

默认情况下,所有模型类都将使用默认数据库连接。在包内的/config/database.php文件中,您可以定义所有数据库连接,并指定默认应使用哪个连接。

您可以通过指定$connection属性来告诉模型类使用不同的连接

class PostModel extends \momentphp\Model
{
    protected $connection = 'connection2';
}

此外,您可以通过将连接名称传递给$this->db()方法来访问几乎任何已定义的连接

$this->db('connection5')->table('posts')->where('id', $id)->first();

您还可以通过以下方式访问原始的、底层的PDO实例

$pdo = $this->db()->getPdo(); // inside model class
$pdo = $this->app->database->connection()->getPdo(); // via $app object elsewhere

访问模型

您可以通过$app->registry服务访问模型实例

$this->app->registry->models->Post->findAll();

如上所述,这创建了一个“全局”模型实例,它使用来自/config/models.php的配置进行初始化

return [
    'Post' => [
        'perPage' => 25
    ]
]

如果需要,您可以通过momentphp\Registry::factory()方法手动创建任意数量的模型实例。使用这种方式,您必须在第二个参数中传递配置

$Post = $this->app->registry->factory('PostModel', ['perPage' => 25]);

在控制器和模型类中,您可以以更简洁的语法访问其他模型

$this->Post->findAll();

模型回调

momentphp\Model::initialize()回调允许您在模型创建后执行一些逻辑

class PostModel extends \momentphp\Model
{
    public function initialize()
    {
        // extecuted after model creation
    }
}

缓存模型方法

模型层中内置了方便的缓存机制。通过在模型配置中指定cache键,您可以控制其行为

return [
    'Post' => [
        'cache' => [
            'ttl' => 60 // cache all methods calls for 60 minutes
        ]
    ]
];

以下表格显示了所有支持选项的列表

控制器

控制器类位于一个包内的 /controllers 文件夹中。在典型场景中,控制器负责解析请求数据,确保调用正确的模型,并渲染正确的响应或模板。通常,控制器用于管理单个模型周围的逻辑。

控制器操作

控制器类中的方法称为 操作。您通过创建相应的 路由 来将传入的 URL 映射到给定的控制器操作。让我们创建一个简单的路由

$app->get('/hello/{name}', 'HelloController:say');

以及相应的控制器类

namespace bundles\helloWorld\controllers;

class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return 'Hello ' . $name;
    }
}

控制器操作必须是 protected 的,并且可以返回

  • 一个字符串(作为 text/html 发送到浏览器)
  • 一个响应对象
  • 什么也不返回

如果没有从操作中返回任何内容,则默认操作模板将被渲染: /templates/controllers/Hello/say.twig。您可以通过与控制器的视图对象交互来指定应渲染哪个模板

$this->view->template('say2'); // will render: /templates/controllers/Hello/say2.twig
// or
$this->view->template('/say2'); // will render: /templates/say2.twig

您还可以强制控制器使用特定包(通过别名引用)的模板

// following will render: /templates/controllers/Hello/say2.twig from "hello" bundle
$this->view->template('say2')->bundle('hello');

如果客户端请求 JSON(或 XML)并且您的应用程序使用 NegotiationMiddleware,则模板将按以下方式渲染

// client asks for JSON
$this->view->template('say2'); // will render: /templates/controllers/Hello/json/say2.twig
// client asks for XML
$this->view->template('say2'); // will render: /templates/controllers/Hello/xml/say2.twig

momentphp\Controller::set() 方法是将数据从您的控制器发送到您的模板的主要方式

// send variable to the template inside controller action:
$this->set('color', 'pink');
// or
$this->view->set('color', 'pink');

// access variable inside a template
You have choosen {{ color }} color. // Twig
You have choosen {$color} color. // Smarty

set() 方法也接受一个关联数组作为其第一个参数

控制器回调

如果您需要在控制器操作被调用之前或之后执行某些逻辑,您可以使用以下回调

class HelloController extends \momentphp\Controller
{
    public function beforeAction($action)
    {
        if ($action === 'say') {
            // extecuted before say() action
        }
    }

    public function afterAction($action)
    {
        if ($action === 'say') {
            // extecuted after say() action
        }
    }

    protected function say($name)
    {
        return 'Hello ' . $name;
    }
}

还有一个 momentphp\Controller::initialize() 回调,它在控制器创建后立即触发

请求对象

您可以在操作中使用 $this->request 属性访问当前请求对象。您可以使用 getQueryParams() 方法获取查询字符串参数的关联数组。如果没有查询字符串,则此方法返回空数组

$queryParams = $this->request->getQueryParams();

从正文或查询字符串中获取请求参数值(按此顺序)

$foo = $this->request->getParam('foo'); // $_POST['foo'] or $_GET['foo']
$bar = $this->request->getParam('bar', 'default'); // setting default value if param not set

您可以在 Slim 的 文档中找到有关请求对象的更多信息

响应对象

您可以在操作中使用 $this->response 属性访问当前响应对象。响应对象可以从操作中返回。要返回重定向响应

class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return $this->response->withRedirect('/login');
    }
}

要返回 JSON 响应

class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        return $this->response->withJson(['name' => $name]);
    }
}

要渲染 404 - 页面未找到

class HelloController extends \momentphp\Controller
{
    protected function say($name)
    {
        $this->abort();
    }
}

您可以在 Slim 的 文档中找到有关响应对象的更多信息

单元格

单元格是小型迷你控制器,可以调用视图逻辑并渲染模板。单元格非常适合构建需要与模型、视图逻辑和渲染逻辑交互的可重用页面组件。一个简单的例子是在线商店中的购物车,或 CMS 中的数据驱动导航菜单。单元格不派发子请求。单元格类放置在包内的 /controllers/cells 文件夹中。

让我们创建一个示例 ShoppingCart 单元格。创建单元格类文件 bundles/helloWorld/controllers/cells/ShoppingCartController.php,内容如下

namespace bundles\helloWorld\controllers\cells;

class ShoppingCartController extends \momentphp\Controller
{
    protected function display($items = 5)
    {
        // grab some data and set it to the template
    }
}

我们新创建的单元格可以在任何模板中调用

{{ this.cell('ShoppingCart') }} // Twig
{$this->cell('ShoppingCart')} // Smarty

您还可以调用任何单元格操作并传递额外的参数

{{ this.cell('ShoppingCart:display', 10) }} // Twig
{$this->cell('ShoppingCart:display', 10)} // Smarty

单元格模板放置在 /templates/controllers/cells 子文件夹中。在调用单元格时如果没有指定操作,将调用 display 操作,渲染以下模板: bundles/helloWorld/templates/controllers/cells/ShoppingCart/display.twig

闪存消息

闪存消息是在处理表单或确认数据后显示的一次性通知。

class ContactController extends \momentphp\Controller
{
    protected function form()
    {
        if ($this->request->isPost()) {
            if ($formIsOk) {
                // will be rendered using /templates/partials/flash/success.tpl
                $this->app->flash->success('Your message has been sent');
                return $this->response->withRedirect('/');
            } else {
                // will be rendered using /templates/partials/flash/error.tpl
                $this->app->flash->error('Please correct form errors');
            }
        }
    }
}

消息以以下方式在模板中渲染

{$this->app->flash->render()} // Smarty
{{ this.app.flash.render() }} // Twig

模板

开箱即用的框架支持 SmartyTwig 模板引擎。模板引擎作为服务(分别命名为 smartytwig)暴露出来,并实现了一个通用接口,配置在 /config/providers.php 文件中。您可以通过在 /config/app.php 文件中设置适当的值来选择默认使用哪个服务。

[
    'viewEngine' => 'smarty'
]

模板文件应放置在包内的 /templates 文件夹中。模板应属于以下预定义的文件夹。

模板内的 this 变量代表 \momentphp\Template 实例,并允许您访问模板文件内的各种对象。

您可以通过以下语法从特定的包(以下示例中的别名为 hello)中包含模板:

{include file='[hello]partials/debugTable.tpl'} // Smarty
{% include '@hello/partials/debugTable.twig' %} // Twig

辅助工具

辅助工具是应用程序表示层的类。它们包含在许多模板、部分或布局之间共享的表示逻辑。辅助工具可以帮助创建良好格式的标记,帮助格式化文本、时间和数字等。辅助类放在包内的 /helpers 文件夹下。让我们创建一个示例 TextHelper。在 bundles/helloWorld/helpers/TextHelper.php 下创建一个类文件,内容如下:

namespace bundles\helloWorld\helpers;

class TextHelper extends \momentphp\Helper
{
    public function uppercase($text)
    {
        return strtoupper($text);
    }
}

现在,辅助工具已准备好在模板中使用。

Here is uppercase post title: {$this->Text->uppercase($post.title)} // Smarty
Here is uppercase post title: {{ this.Text.uppercase(post.title) }} // Twig

在辅助工具方法中,您可以访问:

$this->app // app object
$this->template // Template object
$this->template->request // request object
$this->template->vars // template variables
$this->options() // helper configuration set in "/config/helpers.php"

路由

路由是一种将 URL 映射到仅在服务器接收到特定请求时执行代码的方法。路由定义在包内的 /routes.php 文件中。每个路由由三个元素组成:

  • HTTP 方法
  • URL 模式
  • 路由处理程序

以下是一个示例路由定义:

$app->any('/docs', 'DocsController:index');

根据以上定义,任何对 /docs URL 的 HTTP 请求(GETPOST 等)都会调用处理程序——即 DocsController::index() 方法。处理程序也可以定义为匿名函数,该函数接受 $request$response$args 参数。

$app->any('/docs', function ($request, $response, $args) {
    $debugFlag = $this->debug; // accessing $app->debug service
    return $response->write('Hello world');
});

注意,您可以通过 $this 关键字在闭包中访问服务容器实例。

您可以在 Slim 的文档中找到有关路由和路由的更多信息。

中间件

中间件是在应用程序请求/响应生命周期中调用的可调用对象。请参阅 Slim 的文档以获取有关中间件的更多详细信息。

为了创建简单的 Auth 中间件,在 /middlewares/AuthMiddleware.php 下创建一个类文件,内容如下:

namespace bundles\helloWorld\middlewares;

class AuthMiddleware extends \momentphp\Middleware
{
    public function __invoke($request, $response, $next)
    {
        $cookies = $request->getCookieParams();
        if (!isset($cookies['auth'])) {
            return $response->withRedirect('/login');
        }
        return $next($request, $response);
    }
}

您可以通过 app.middlewares.app 配置键将中间件附加到应用程序级别。

'middlewares' => [
    'app' => [
        'auth' => 'AuthMiddleware',
    ],
]

您也可以通过 app.middlewares.route 配置键将中间件仅附加到某些路由。

'middlewares' => [
    'route' => [
        'auth' => 'AuthMiddleware',
    ],
]
$app->any('/pages/{page:.+}', 'PagesController:display')->add('auth');

默认中间件

默认情况下,MomentPHP 随附以下中间件:

事件

事件允许对象通知其他对象和匿名监听器有关更改。例如,您可以为您的应用程序定义一个自定义的 user.create 事件,当新用户注册时将触发该事件。

class UserModel extends \momentphp\Model
{
    public function create($data)
    {
        $id = $this->db()->table('users')->insertGetId($data);
        $this->app->eventsDispatcher()->fire('user.create', [$id]);
        return $id;
    }
}

稍后,您的代码的其他部分可以监听并针对定义的事件进行操作。

namespace bundles\mailer;

class Bundle extends \momentphp\Bundle
{
    public function boot()
    {
        $this->app->eventsDispatcher()->listen('user.create', function ($userId) {
            // do something (send welcome email, etc.)
        });
    }
}

当您有多个事件监听器时,有时您可能希望停止剩余的监听器运行。为此,您可以从当前监听器返回 false

框架事件

一些核心事件已经由框架定义。您可以用与订阅自定义事件相同的方式订阅它们。

请注意,MomentPHP 使用的 Laravel 的组件(数据库和缓存)也发出一些事件。请参阅 Laravel 的文档以获取更多信息。

缓存

MomentPHP 使用了 Laravel 框架的缓存组件。缓存管理器实例作为 cache 服务提供。缓存配置位于 /config/cache.php 文件中。在这个文件中,您可以指定在整个应用程序中默认使用的缓存驱动程序。默认情况下,框架配置为使用文件缓存驱动程序,该驱动程序将序列化后的缓存对象存储在文件系统中。

存储缓存项

$app->cache->put('key', 'value', $minutes);

从缓存中检索项

$app->cache->get('key', 'default'); // retrieving an item or returning a default value

检查缓存中是否存在

if ($app->cache->has('key'))
{
    //
}

有时您可能希望从缓存中检索项,但如果请求的项不存在,则存储默认值。您可以使用 remember() 方法完成此操作

$value = $app->cache->remember('users', $minutes, function () use ($app) {
    return $app->registry->models->User->findAll();
});

当使用多个缓存存储时,您可以通过 store() 方法访问它们

$value = $app->cache->store('foo')->get('key');

有关缓存管理器功能的更多信息,请参阅 Laravel 的文档

日志记录

默认情况下,log 服务将使用默认的日志记录器。在包内的 /config/loggers.php 文件中,您可以定义所有日志记录器,以及指定默认使用的日志记录器。框架使用流行的 Monolog 库,因此底层每个日志记录器都是一个 Monolog\Logger 类的实例。

向日志添加记录

$app->log->addDebug('Foo', ['some' => 'data']);
// or
$app->log->log(\Psr\Log\LogLevel::DEBUG, 'Foo', ['some' => 'data']);

您可以通过 logger() 方法访问任何配置的日志记录器

$app->log->logger('error')->addDebug('Foo', ['some' => 'data']);

错误日志

您可能想要记录 PHP 错误。为此,请将适当的日志记录器名称设置为 /config/app.php

'error' => [
    'log' => 'error' // set to `false` to disable PHP errors logging
]

错误处理

MomentPHP 将所有 PHP 错误转换为异常。您可以通过设置配置键 app.error.level 的适当值来设置 PHP 错误报告级别

'error' => [
    'level' => -1 // report all errors
]

默认情况下,如果 app.displayErrorDetails 开关开启,框架将使用 Whoops! 包将所有错误显示为异常;如果开关关闭,则隐藏它们并使用 ErrorController 渲染客户端友好的消息。

app.displayErrorDetails 配置设置的值作为 $app->debug 服务提供。

总结一下,将 app.displayErrorDetails 设置为 false 会改变以下内容

  • PHP 错误不会显示
  • 未捕获的异常和致命错误将渲染默认的内部服务器错误页面 - 使用 ErrorController::error()
  • 未捕获的 \Slim\Exception\NotFoundException 将渲染默认的未找到页面 - 使用 ErrorController::notFound()
  • 当模板更改时,不会重新编译模板

命令行

MomentPHP 应用程序也可以在命令行模式下调用。这在您需要设置一些由 cron 守护进程调用的后台处理任务时非常有用。

首先,在 /routes.php 中设置一个 GET 路由

if ($app->console) {
    $app->get('/background/task', function($request, $response, $args) {
        // perform some tasks using models etc.
        ...
    });
}

然后,执行以下命令(其中 index.php 是应用程序的前端控制器)

php index.php background/task