packerit/laravel-core

此包已废弃,不再维护。没有建议的替代包。

提供Laravel框架中服务、仓库等使用的标准化核心类库。

5.0.0 2022-02-16 21:10 UTC

README

GitHub tag (latest by date) GitHub Packagist PHP from Packagist StyleCI Build Status

Laravel和Lumen框架中服务、仓库等使用的标准化核心类库包。

安装

您可以通过composer安装此包

composer require pacerit/laravel-core

版本兼容性

Laravel

框架 注意
5.8.x ^1.x.x 不再维护。
6.0.x ^2.x.x 仅修复bug。
7.x.x ^3.x.x 仅修复bug。
8.x.x ^4.x.x PHP ^8.0 从4.0.4版本开始支持
9.x.x ^5.x.x

Lumen

框架 注意
5.8.x ^1.1.x 不再维护。
6.0.x ^2.x.x 仅修复bug。
7.x.x ^3.x.x 仅修复bug。
8.x.x ^4.x.x PHP ^8.0 从4.0.4版本开始支持
9.x.x ^5.x.x

包含的类

基本类

CoreEntity::class - base class models
CoreRepository::class - base class of repositories (provided by package)
CoreService::class - base class of services
CoreFormatter::class - base class of formatter
CoreException::class - base class of exceptions

特质

ScenatioTrait::class
StringTrait::class
NumberTrait::class
XMLTrait::class

实现

实体实现

为了使用Service、Repositories或Formatter类,首先您必须准备您的实体。您应用中的每个实体都必须

  • 继承CoreEntity类
  • 实现扩展CoreEntityInterface的接口

例如,这是Example实体的实现

Example类

class Example extends CoreEntity implements ExampleInterface
{}

ExampleInterface

interface ExampleInterface extends CoreEntityInterface
{}

接口和实体类必须在您的app ServiceProvider中绑定

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    $this->app->bind(ExampleInterface::class, Example::class);
}

在实体中使用UUID

要使用UUID功能,请安装建议的ramsey/uuid包

此包提供了在实体中作为次要键使用UUID的可能性,用于外部使用(例如,在路由中)。它仍然需要在您的数据库中使用整数类型的ID作为主键。

要在您的实体中使用UUID,它必须

  • 实现UUIDInterface
  • 使用UsesUUID特质

在您的迁移中创建字段,使用"uuid"键和uuid()方法。

$table->uuid(UsesUUID::UUID);

UUID将在创建新实体时自动生成。如果您使用Service,可以将WithUUID特质添加到您的CoreService类的实现中,以添加使用UUID时有用的方法。

class MyEntityService extends CoreService implements MyEntityServiceInterface
    use WithUUID;
    (...)

仓库实现和使用

仓库的文档可以在这里找到。

服务实现

要使用Service,创建一个服务类,该类

  • 扩展CoreService类
  • 实现扩展CoreServiceInterface的接口

例如,这是Example实体服务的实现

ExampleServiceInterface

interface ExampleServiceInterface extends CoreRepositoryInterface
{}

ExampleService 类。在类的 __construct() 函数中,提供实体的存储库类,并通过 setRepository() 函数设置它。可选地,您可以通过 setFormatter() 函数传递实体格式化程序来设置格式化功能。提供的类必须是 CoreRepository/CoreFormatter 的实现。

class ExampleService extends CoreService implements ExampleServiceInterface
{
    /**
     * ExampleService constructor.
     *
     * @param ExampleRepositoryInterface $exampleRepository
     * @param ExampleFormatterInterface $exampleFormatter
     */
    public function __construct(
        ExampleRepositoryInterface $exampleRepository,
        ExampleFormatterInterface $exampleFormatter
    ) {
        $this->setRepository($exampleRepository)
            ->setFormatter($exampleFormatter);
    }

}

使用服务

要在控制器或其他类中使用服务,您可以使用依赖注入或容器。以下是使用控制器中服务的示例代码。

class ExampleController extends Controller {

    /**
     * @var ExampleServiceInterface $exampleService
     */
    protected $exampleService;

    public function __construct(ExampleServiceInterface $exampleService){
        $this->exampleService = $exampleService;
    }

    ....
}

可用方法

  • setRepository() - 设置在服务中使用的存储库。传递的对象必须是 CoreRepositoryInterface 的实现。
  • getRepository() - 返回之前设置的存储库类实例。
  • setFormatter() - 设置在服务中使用的格式化程序类。传递的对象必须是 CoreFormatterInterface 的实现。
  • getFormatter() - 返回之前设置的格式化程序类实例。
  • setModel() - 设置您想要工作的模型,即如果您已经有了实例。
  • setModelByID() - 根据给定的 ID(整数)设置模型。如果存在具有给定 ID 的模型,则将其设置,否则将抛出异常。
  • setModelByKey() - 根据给定的键(表中的列)和给定值设置模型。当需要根据除 ID 之外的列查找记录时很有用(例如外键)。
  • setNewMode() - 设置新的模型类实例。
  • getModel() - 获取之前设置的模型类实例。
  • format() - 获取之前设置的模型类实例并将其传递给格式化程序类。将返回 CoreFormatterInterface 实例。使用示例。
// Return Example entity record with ID 1 as an array.
return $this->exampleService->setModelByID(1)->format()->toArray();
  • create() - 根据实际设置的模型和给定的参数创建新的实体记录。示例。
For this example, we assume that Example entity class have setFirstValue() and setSecondValue() functions (setters)
and const. Both of this example, create the same records in database.

// Create based on previously set entity.
$this->exampleService
    ->setNewModel()
    ->getModel()
    ->setFirstValue(1)
    ->setSecondValue(2);

$this->exampleService->create();

// Create model based on parameters.
$this-exampleService->create(
    [
        ExampleInterface::FIRST_VALUE => 1,
        ExampleInterface::SECOND_VALUE => 2,
    ]
);
  • update() - 更新模型。类似于 create 方法,它基于之前设置的模型或参数,但我们必须在之前设置现有的模型记录。否则,将抛出异常。示例。
// Update based on previously set entity.
$this->exampleService
    ->setModelByID(1)
    ->getModel()
    ->setFirstValue(2);

$this->exampleService->update();

// Update model based on parameters.
$this-exampleService->update(
    1,
    [
        ExampleInterface::FIRST_VALUE => 2,
    ]
);
  • delete() - 删除模型。类似于 update() 方法,这也需要在之前设置现有的模型。
$this->exampleService->setModelByID(1)->delete();

特质

ScenarioTrait

ScenarioTrait 包含非常实用的函数,如果我们要根据某些键(例如实体中的 "type" 字段)使用不同的类。

例如 - 我们有一个抽象的 "PaymentService" 类,它未实现 "create()" 方法。我们创建了两个扩展此类的类,并实现了 create() 函数 - 每个类用于不同的支付提供商

* DummyProviderPaymentService::class - for "DummyProvider"
* OtherDummyProviderPaymentService::class - for "OtherDummyProvider"

每个类都稍微不同地实现了 create() 函数。

通常,如果我们想调用匹配类中的 create() 函数,我们会这样做

(...)
switch ($type) {
    case 'DummyProvider':
        $service = new DummyProviderPaymentService::class;
        break;

    case 'OtherDummyProvider':
        $service = new OtherDummyProviderService::class;
        break;  
    
     default:
        // Dunno what to do..
}

$service->create();
(...)

但是,如果这个类有依赖注入,那就不可行。并且不是很优雅。

这时,ScenarioTrait 就派上用场了。有了这个类,我们可以解决这个问题,例如,这样

(...)
$this->registerScenario('DummyProvider', DummyProviderPaymentService::class);
$this->registerScenatio('OtherDummyProvider', OtherDummyProviderService::class);

$this->getScenatioInstance($type)->create();
(...)

这就完成了。是的 - 我们可以只传递类的命名空间(即使有依赖注入) - 在调用 getScenarioInstance() 方法时将创建新实例。当然,您也可以传递类的现有实例(即来自依赖注入) - 这取决于您。

变更日志

请访问 变更日志,以获取该包的完整变更历史。

测试

composer test

安全漏洞

如果您在包中发现安全漏洞,请通过 kontakt@pacerit.pl 向 Wiktor Pacer 发送电子邮件。所有安全漏洞都将得到及时解决。

许可

本软件包是开源软件,许可协议为MIT许可证