laravelcollective/annotations

此包已被弃用且不再维护。作者建议使用 spatie/laravel-route-attributes 包代替。

Laravel 框架的路由注解。

v8.1.1 2023-04-25 02:38 UTC

README

Build Status Total Downloads Latest Stable Version Latest Unstable Version License

注解

安装

如果您已将顶级命名空间更改为类似于 'MyCompany' 的名称,则应使用新命名空间而不是 'App'。

首先,通过 Composer 安装此包。编辑您的项目 composer.json 文件以要求 laravelcollective/annotations

"require": {
    "laravelcollective/annotations": "6.0.\*"
}

接下来,在终端中更新 Composer

composer update

Composer 完成后,您需要在 app/Providers/AnnotationsServiceProvider.php 中创建一个服务提供者。

<?php namespace App\Providers;

use Collective\Annotations\AnnotationsServiceProvider as ServiceProvider;

class AnnotationsServiceProvider extends ServiceProvider {

    /**
     * The classes to scan for event annotations.
     *
     * @var array
     */
    protected $scanEvents = [];

    /**
     * The classes to scan for route annotations.
     *
     * @var array
     */
    protected $scanRoutes = [];

    /**
     * The classes to scan for model annotations.
     *
     * @var array
     */
    protected $scanModels = [];

    /**
     * Determines if we will auto-scan in the local environment.
     *
     * @var bool
     */
    protected $scanWhenLocal = false;

    /**
     * Determines whether or not to automatically scan the controllers
     * directory (App\Http\Controllers) for routes
     *
     * @var bool
     */
    protected $scanControllers = false;

    /**
     * Determines whether or not to automatically scan all namespaced
     * classes for event, route, and model annotations.
     *
     * @var bool
     */
    protected $scanEverything = false;

}

最后,将新提供者添加到 config/app.phpproviders 数组中

  'providers' => [
    // ...
    App\Providers\AnnotationsServiceProvider::class
    // ...
  ];

这不会替换 RouteServiceProvider,它仍然需要,因为它处理路由缓存的加载等。

设置扫描

将事件处理类添加到 protected $scanEvents 数组中,以扫描事件注解。

    /**
     * The classes to scan for event annotations.
     *
     * @var array
     */
    protected $scanEvents = [
      App\Handlers\Events\MailHandler::class,
    ];

将控制器添加到 protected $scanRoutes 数组中,以扫描路由注解。

    /**
     * The classes to scan for route annotations.
     *
     * @var array
     */
    protected $scanRoutes = [
      App\Http\Controllers\HomeController::class,
    ];

将模型添加到 protected $scanModels 数组中,以扫描模型注解。

    /**
     * The classes to scan for model annotations.
     *
     * @var array
     */
    protected $scanModels = [
      'App\User',
    ];

或者,您可以将 protected $scanEverything 设置为 true 以自动扫描您应用程序命名空间内的所有类。 注意: 这可能会根据您应用程序的大小增加扫描器执行所需的时间。

可以通过使用 php artisan event:scanphp artisan route:scanphp artisan model:scan 分别手动扫描事件处理程序、控制器和模型。在本地环境中,您可以通过设置 protected $scanWhenLocal = true 自动扫描它们。

事件注解

@Hears

@Hears 注解为特定事件注册事件监听器。对任何方法使用 @Hears("SomeEventName") 注解将注册一个事件监听器,该监听器将在 SomeEventName 事件触发时调用该方法。

<?php namespace App\Handlers\Events;

use App\User;

class MailHandler {

  /**
   * Send welcome email to User
   * @Hears("UserWasRegistered")
   */
  public function sendWelcomeEmail(User $user)
  {
    // send welcome email to $user
  }

}

路由注解

路由注解非常强大,但是您的路由定义顺序可能会影响您的应用程序如何匹配特定路由,特别是任何通配符路由。如果将 protected $scanEverything 设置为 true,您将无法控制路由定义的顺序。

@Get

@Get 注解为 HTTP GET 请求注册路由。

<?php namespace App\Http\Controllers;

class HomeController {

  /**
   * Show the Index Page
   * @Get("/")
   */
  public function getIndex()
  {
    return view('index');
  }

}

您还可以设置路由名称。

  /**
   * @Get("/", as="index")
   */

... 或者中间件。

  /**
   * @Get("/", middleware="guest")
   */

... 或者两者。

  /**
   * @Get("/", as="index", middleware="guest")
   */

以下是一个示例,它使用了一个@Get注解的所有可用参数。

  /**
   * @Get("/profiles/{id}", as="profiles.show", middleware="guest", domain="foo.com", where={"id": "[0-9]+"}, no_prefix="true")
   */

no_prefix允许忽略控制器中特定路由添加的任何前缀。

@Post@Options@Put@Patch@Delete@any

@Post@Options@Put@Patch@Delete@Any注解的语法与@Get注解完全相同,不同之处在于它将注册一个对应于相应HTTP动词的路由,而不是GET动词。

@Middleware

除了在路由定义标签(如@Get@Post等)中内联定义中间件之外,@Middleware标签也可以单独使用。它既适用于单个方法,也适用于整个控制器,并且与laravel中其他地方可用的only/exclude过滤语法相同。

  /**
   * Show the Login Page
   *
   * @Get("login")
   * @Middleware("guest")
   */
  public function login()
  {
    return view('index');
  }

或者在一个整个控制器上,与laravel其他地方可用的only/exclude过滤语法相同

/**
 * @Middleware("guest", except={"logout"}, prefix="/your/prefix")
 */
class AuthController extends Controller {

  /**
   * Log the user out.
   *
   * @Get("logout", as="logout")
   * @Middleware("auth")
   *
   * @return Response
   */
  public function logout()
  {
    $this->auth->logout();

    return redirect( route('login') );
  }

}

@Resource

在控制器上使用@Resource注解允许你轻松地设置资源控制器。

<?php
/**
 * @Resource('users')
 */
class UsersController extends Controller {
  // index(), create(), store(), show($id), edit($id), update($id), destroy($id)
}

你可以指定onlyexcept参数,就像你可以使用常规的Route::resource()命令一样。

  /**
   * @Resource('users', only={"index", "show"})
   */

你还可以指定每个资源方法的路由名称。

  /**
   * @Resource('users', names={"index"="user.all", "show"="user.view"})
   */

@Controller

在控制器上使用@Controller注解允许你为其包含的路由设置各种选项。

<?php
/**
 * @Controller(prefix="admin", domain="foo.com")
 */
class AdminController extends Controller {
  // All routes will be prefixed by admin/
}

扫描控制器目录

为了递归地扫描整个控制器命名空间(App\Http\Controllers),你可以将$scanControllers标志设置为true。

它将自动将App调整为你的应用程序命名空间。

    $scanControllers = true;

高级

如果你想要使用任何逻辑来添加类到要扫描的列表中,你可以覆盖routeScans()eventScans()方法。

以下是一个示例,如果当前环境是local,则将控制器添加到扫描列表中。

public function routeScans() {
    $classes = parent::routeScans();

    if ( $this->app->environment('local') ) {
        $classes = array_merge($classes, [App\Http\Controllers\LocalOnlyController::class]);
    }

    return $classes;
}

扫描命名空间

你可以使用getClassesFromNamespace( $namespace )方法递归地向列表添加命名空间。这将扫描给定的命名空间。它只适用于app目录中的类,并且依赖于PSR-4命名空间标准。

这是$scanControllers标志在控制器目录中使用的样子。

以下是一个示例,它基于上一个示例构建 - 添加一个仅限本地的完整命名空间。

public function routeScans() {
    $classes = parent::routeScans();

    if ( $this->app->environment('local') ) {
        $classes = array_merge(
            $classes,
            $this->getClassesFromNamespace( App\Http\Controllers\Local::class )
        );
    }

    return $classes;
}

模型注解

你可以使用注解来自动将你的模型绑定到路由参数,使用Route Model Binding。为此,请使用@Bind注解。

/**
 * @Bind("users")
 */
class User extends Eloquent {
  //
}

这相当于调用Route::model('users', 'App\Users')

自定义注解

如果你想注册自己的注解,创建一个包含Collective\Annotations\Routing\Annotations\Annotations\Annotation子类的命名空间 - 假设为App\Http\Annotations

然后,在你的注解服务提供者中,覆盖addRoutingAnnotations( RouteScanner $scanner )方法,并注册你的路由注解命名空间

<?php namespace App\Providers;

use Collective\Annotations\Routing\Annotations\Scanner as RouteScanner;

/* ... then, in the class definition ... */

    /**
     * Add annotation classes to the route scanner
     *
     * @param RouteScanner $namespace
     */
    public function addRoutingAnnotations( RouteScanner $scanner )
    {
      $scanner->addAnnotationNamespace( 'App\Http\Annotations' );
    }

你的注解类必须具有@Annotation类注解(请参阅以下示例)。

存在一个用于事件注释的等效方法:addEventAnnotations( EventScanner $scanner )

自定义注释示例

以下是一个创建@Auth注释的示例。它提供了与使用注释@Middleware("auth")相同的功能。

在一个命名空间中 - 在本例中,App\Annotations

<?php namespace App\Http\Annotations;

use Collective\Annotations\Routing\Annotations\Annotations\Annotation;
use Collective\Annotations\Routing\Annotations\MethodEndpoint;
use ReflectionMethod;

/**
 * @Annotation
 */
class Auth extends Annotation {

  /**
   * {@inheritdoc}
   */
  public function modify(MethodEndpoint $endpoint, ReflectionMethod $method)
  {
    if ($endpoint->hasPaths())
    {
      foreach ($endpoint->getPaths() as $path)
      {
        $path->middleware = array_merge($path->middleware, (array) 'auth');
      }
    }
    else
    {
      $endpoint->middleware = array_merge($endpoint->middleware, (array) 'auth');
    }
  }

}