elie29/core

简单清晰的框架

v1.0.1 2019-03-19 08:57 UTC

This package is auto-updated.

Last update: 2024-08-27 20:39:42 UTC


README

Build Status Coverage Status

介绍

PHP 库,使用 PSR-11 容器创建轻量级直接的项目。

安装

运行以下命令通过 Composer 安装

composer require elie29/core

入门

Core 框架不需要特定的结构。只需提供一些配置即可。

准备项目结构

为了配置框架,我们需要一个项目结构。让我们假设我们有以下标准结构

  • MY_PROJECT
    • data
      • cache: 如果启用了缓存,则为缓存文件夹
      • config
        • config.php: 项目配置
        • container.php: 容器配置
    • public
      • index.php: 前端控制器
    • src
      • Controllers
        • HomeIndexController: 默认 Core 控制器,继承自 AbstractController
      • views
        • layouts/layout.html: 当渲染为 html 时,Core 框架使用的布局
        • home/index.phtml: 如果 HomeIndexController 使用 fetchTemplate,则不必要
    • composer.json

准备配置文件

关于上述定义的结构,config.php 看起来如下

// point out to MY_PROJECT
$base = dirname(dirname(__DIR__));

// should return an array
return [
    // zend-phpdi-config
    'dependencies' => [
        'aliases' => [
            RouterInterface::class => Router::class,
            RenderInterface::class => Render::class,
        ],
        'autowires' => [
            Router::class,
            Render::class,
            HomeIndexController::class
        ],
    ],

    // Core configuration
    'core' => [
        // Router configuration: Query Protocol by default
        'router' => [
            RouterConst::NAMESPACE => 'Controllers\\'
        ],
        // Render configuration
        'render' => [
            RenderConst::VIEWS_PATH => $base . '/src/views',
            RenderConst::CACHE_PATH => $base . '/data/cache',
            RenderConst::CLEAN_OUTPUT => true,
        ],
    ],
];

准备容器

container.php 依赖于安装的容器。对于 zend-phpdi-config,它看起来如下

// Protect variables from global scope
return call_user_func(function () {

    $config = require __DIR__ . '/config.php';

    $factory = new ContainerFactory();

    // Container
    return $factory(new Config($config));
});

创建 index.php

除了 autoload.php 和创建 Core 类的实例之外,不需要其他内容

chdir(dirname(__DIR__));

require 'vendor/autoload.php';

$container = require 'data/config/container.php';

$core = new Core($container);
$core->run();

创建布局

layout.phtml 是一个包含在控制器中分配的 php 变量或由 preRunrunpostRun 方法返回的值的 html 文件。

layout.phtml 的示例

<html lang="en">
<head>
   <meta charset="utf-8">
   <meta name="description" content="<?php echo htmlentities($description, ENT_QUOTES, 'UTF-8') ?>">
</head>
<body>
   <!-- tplContent should display tags -->
   <div><?php echo $tplContent ?></div>
</body>
</html>

创建第一个控制器

在配置文件中,我们指定了 Controllers\\ 作为默认命名空间,但没有指定默认控制器和默认操作。在这种情况下,控制器将是 home,操作将是 index。因此,控制器类应命名为 HomeIndexController,命名空间为 Controllers。每个控制器都应该实现 Elie\Core\Controller 或继承自 Elie\Core\AbstractController

namespace Controllers;

class HomeIndexController extends AbstractController
{

   public function doRun(): bool
   {
      $render = $this->container->get(RenderInterface::class);
      // true because cache_time is not defined in config.php
      return $render->hasLayoutExpired();
   }

   public function run(array $params = []): array
   {
      $render = $this->container->get(RenderInterface::class);

      // global data for layout/templates
      $render->assign([
         'description' => 'first description',
      ]);

      // layout specific data
      return ['tplContent' => '<span>my content</span>'];
   }
}

创建模板

模板不是必需的,但为了有一个具有多个内容的动态布局,我们可以使用 RenderInterface::fetchTemplate。phtml 模板应位于 views_path 下。

让我们更改 run 方法以获取模板

public function run(array $params = []): array
{
   $render = $this->container->get(RenderInterface::class);

   // global data for layout/templates
   $render->assign([
      'description' => 'displayed description',
   ]);

   // layout specific data
   return ['tplContent' => $this->getMyTemplate()];
}

protected function getMyTemplate(): string
{
   $cacheID = sha1(__FILE__ . 'product/detail');
   $cacheTime = 5; // 5 seconds in cache

   $render = $this->container->get(RenderInterface::class);

   // data is not needed when file is read from cache
   $data = [];

   // overrides keys assigned in run
   $render->assign([
      'description' => __METHOD__,
   ]);

   if ($render->hasTemplateExpired($cacheID, $cacheTime)) {
      $data = [
         'item' => time(),
         'description' => 'overriden by assign method'
      ];
   }

   // specific product/detail template under views_path
   return $render->fetchTemplate($data, 'product/detail', $cacheID, $cacheTime);
}

位于 src/views/product 文件夹下的 detail.phtml 文件可能如下所示

<h1>Product detail Template</h1>

<div><?php echo htmlentities($item, ENT_QUOTES, 'UTF-8') ?></div>

开发先决条件

文本文件编码

  • UTF-8

代码样式格式化工具

  • Zend 框架编码标准

Composer 命令

  • clean: 清理所有生成的文件
  • test: 启动单元测试
  • test-coverage: 启动单元测试并生成 clover.xml 文件
  • cs-check: 用于代码嗅探检查
  • cs-fix: 用于代码嗅探修复
  • phpstan: 启动 PHP 静态分析工具
  • check: 启动 cleancs-checktestphpstan