lugege/laravel-aspect

efficient Laravel extension package designed to enhance development productivity. It integrates powerful annotation handling and practical helper classes, making the development of Laravel applications more convenient and flexible.

Installs: 11

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/lugege/laravel-aspect

v1.0.1 2025-08-06 04:33 UTC

This package is auto-updated.

Last update: 2025-10-06 04:57:06 UTC


README

PHP Version Laravel Version

Lugege\LaravelAspect

它融合了 Java Spring Boot 的 AOP 概念,并广泛利用 PHP8 注解来简化开发流程。

该项目目前正在开发中,在生产环境中使用时请谨慎。

简易路由

路由需要在 web.phpapi.php 中单独配置,这在开发过程中并不方便,因为需要在不同文件之间切换。

相比之下,像 Spring Boot 或 Flask 这样的框架允许使用注解配置路由,使编码过程更加流畅。因此,我封装了基于注解的路由功能。

首先,你需要在 路由文件中注册,代码如下:

use Lugege\LaravelAspect\EasyRouter;

EasyRouter::register();

然后,你可以在控制器方法前使用路由注解:

use Lugege\LaravelAspect\Attributes\Routes\GetMapping;
use Lugege\LaravelAspect\Attributes\Routes\Prefix;

#[Prefix(path: '/user')]
class UserController
{
    #[GetMapping(path: '/login')] 
    public function login() {}
}

自动装配

在 Java Spring Boot 框架中,@Autowired 注解用于自动注入依赖。我们可以使用 #[Autowired] 注解来实现相同的效果。

use Lugege\LaravelPlus\Attributes\Service;

#[Service]
class UserService
{
    public function register() {}
}


use Lugege\LaravelPlus\Traits\Injectable;

class UserController
{
    use Injectable;
  
    #[Autowired]
    private UserService $userService;
    
    public function register()
    {
        $this->userService->register(); 
    }
}

#[Autowired] 注解可以用于属性。#[Service] 注解用于将类标记为服务,这是自动装配所必需的。

配置值注入

除了依赖注入之外,Laravel-Plus 还支持配置值注入功能,让你可以直接将 Laravel 配置文件中的值注入到类属性中:

use Lugege\LaravelPlus\Traits\Injectable;
use Lugege\LaravelPlus\Attributes\Value;

class DatabaseService
{
    use Injectable;
    
    #[Value('database.connections.mysql.host', 'localhost')]
    private string $dbHost;
    
    #[Value('database.connections.mysql.port', 3306)]
    private int $dbPort;
    
    #[Value('app.timezone', 'UTC')]
    private string $timezone;
    
    public function connect()
    {
        // 使用注入的配置值
        dump("Connecting to {$this->dbHost}:{$this->dbPort}");
    }
}

#[Value] 注解的第一个参数是配置键名,第二个参数是可选的默认值。如果配置不存在,将使用默认值。

Bean

长期以来,PHP 开发者习惯于使用功能强大的数组作为所有数据的载体。这不是一个优雅的做法,并且存在以下问题:

  • 数组键容易拼写错误,当发现这些错误时,已经是运行时了
  • 编码过程不够流畅;你总是需要暂停思考下一个键是什么
  • 违反了单一职责原则,经常将所有数据放在一个巨大的数组中
  • 降低了代码的可扩展性、可读性和健壮性...

因此,我引入了 Bean 的概念。Bean 是一个具有强类型属性的数据载体,让你在编码过程中获得更好的提示:

use Lugege\LaravelPlus\Bean;

/**
 * @method getUsername()
 * @method setUsername()
 * @method getPassword()
 * @method setPassword()
 */
class RegisterParams extends Bean
{
    protected string $username;
    
    protected string $password;
}

new RegisterParams(['username' => 'bob', 'password' => 'passw0rd']);

你可以使用数组初始化 Bean,这是最常见的方法。当然,有时你也可以从一个 Bean 转换为另一个 Bean,它会过滤掉不匹配的字段:

use Lugege\LaravelPlus\Bean;

$bean = new Bean();
class Bar extends Bean {  
    // 一些属性  
}
Bar::fromBean($bean)

你可以轻松地将 Bean 转换为数组或 JSON。默认情况下,将使用蛇形命名法。你可以使用 usingSnakeCase 参数关闭此功能:

use Lugege\LaravelPlus\Bean;

$bean = new Bean();
$arr = $bean->toArray(usingSnakeCase: false);
$json = $bean->toJson(usingSnakeCase: true);

有时,你可能需要比较两个 Bean:

use Lugege\LaravelPlus\Bean;
(new Bean())->equals($bean2);

通常,我们需要对从客户端传递的数据进行类型转换等预处理工作:

use Lugege\LaravelPlus\Bean;
use Lugege\LaravelPlus\Attributes\TypeConverter;

class User extends Bean
{
    #[TypeConverter(value: BoolConverter::class)]
    protected BoolEnum $isGuest;
}

class BoolConverter
{
    public function convert(bool|string $value): BoolEnum
    {
        if ($value === 'YES' || $value === 'yes' || $value === 'y' || $value === 'Y') {
            return BoolEnum::TRUE;
        }
        if ($value === 'NO' || $value === 'no' || $value === 'N' || $value === 'n') {
            return BoolEnum::FALSE;
        }

        return $value ? BoolEnum::TRUE : BoolEnum::FALSE;
    }
}

你甚至可以执行 XSS 过滤。

Bean 的一个特别有用的功能是支持嵌套:

use Lugege\LaravelPlus\Bean;

class User extends Bean
{
    protected Company $company;
}

class Company extends Bean
{
    protected string $name;
}

它甚至支持数组嵌套:

use Lugege\LaravelPlus\Bean;
use Lugege\LaravelPlus\Attributes\BeanList;

/**
 * @method Company[] getCompanies()
 */
class User extends Bean
{
    /**
     * @var Company[]
     */
    #[BeanList(value: Company::class)]
    protected array $companies;
}

$user = new User(['companies' => [['name' => 'Lugege'], ['name' => 'Google']]]);
foreach ($user->getCompanies() as $company) {
    dump($company->getName());
}