目录
PHP自定义注解:增强代码灵活性和可扩展性
首页 后端开发 php教程 您自己的自定义注释 - 不仅仅是评论!

您自己的自定义注释 - 不仅仅是评论!

Feb 15, 2025 am 09:22 AM

PHP自定义注解:增强代码灵活性和可扩展性

本文探讨如何在Symfony 3应用中创建和使用自定义注解。注解是我们在类、方法和属性上方看到的文档块元数据/配置,常用于声明控制器路由(@Route())、Doctrine ORM映射(@ORM())或控制对Rauth等包中各种类和方法的访问。本文将介绍如何自定义注解,并在不加载类的情况下读取类或方法信息。

关键要点:

  • PHP自定义注解可用于向代码添加元数据,影响代码行为,使其更灵活、更易于适应。它们可用于定义路由信息、指定验证规则或配置依赖注入。
  • 创建PHP自定义注解需要定义一个新的类来表示该注解。此类应具有与您希望在注解中设置的值相对应的属性。
  • Doctrine支持自定义注解。您可以定义自己的注解并将其用于Doctrine实体中。Doctrine的注解读取器将解析这些注解,然后可以使用它们来影响实体的行为。
  • 使用PHP自定义注解的一个限制是它们不受语言本身的原生支持。这意味着您需要使用提供注解支持的库或工具,例如Doctrine或PHP-DI。
  • PHP自定义注解的用途多种多样,包括在Web应用程序中定义路由信息、为表单输入指定验证规则或配置依赖注入。它们还可用于向代码添加文档。

Your Own Custom Annotations - More than Just Comments!

免责声明: 注解与Symfony无关,它是作为Doctrine项目的一部分开发的概念,用于解决将ORM信息映射到类方法的问题。

本文将构建一个名为WorkerBundle的小型可重用捆绑包(仅用于演示目的,并非真正可打包的)。我们将开发一个小型概念,允许定义各种以不同速度“运行”的Worker类型,然后应用程序中的任何人都可以使用它们。实际的worker操作不在本文的讨论范围之内,因为我们关注的是设置管理它们的系统(并通过注解发现它们)。

您可以查看这个仓库并按照其中介绍的说明在本地Symfony应用程序中设置捆绑包。

Worker

Worker将实现一个接口,该接口需要一个方法:::work()。在新的WorkerBundle中,让我们创建一个Workers/目录来保持整洁,并在其中添加接口:

1

2

3

4

5

6

7

8

9

10

11

12

<?php

namespace WorkerBundle\Workers;

 

interface WorkerInterface

{

    /**

     * 执行工作

     *

     * @return NULL

     */

    public function work();

}

登录后复制
登录后复制
登录后复制

注解

每个worker都必须实现上述接口。很清楚。但除此之外,我们还需要它们在类上方有一个注解,以便找到它们并读取有关它们的某些元数据。

Doctrine将文档块注解映射到一个类,该类的属性表示注解本身内部的键。让我们创建我们自己的注解并实际操作一下。

每个WorkerInterface实例在其文档块中都将具有以下注解:

1

2

3

4

5

6

7

8

9

10

11

12

<?php

namespace WorkerBundle\Workers;

 

interface WorkerInterface

{

    /**

     * 执行工作

     *

     * @return NULL

     */

    public function work();

}

登录后复制
登录后复制
登录后复制

我们将保持简单,只有两个属性:唯一名称(字符串)和worker速度(整数)。为了使Doctrine的注解库能够识别此注解,我们必须创建一个匹配的类,不出所料,它自己也有一些注解。

我们将此类放在捆绑包命名空间的Annotation文件夹中,并将其简单地命名为Worker:

1

2

3

4

5

6

/**

 * @Worker(

 *     name = "唯一的Worker名称",

 *     speed = 10

 * )

 */

登录后复制
登录后复制

如您所见,我们有两个属性和一些简单的getter方法。更重要的是,我们在顶部有两个注解:@Annotation(告诉Doctrine此类表示一个注解)和@Target("CLASS")(告诉它应该在整个类而不是方法或属性上方使用)。就是这样,WorkerInterface类现在可以通过确保在文件顶部使用use语句导入相应的类来使用此注解:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<?php

namespace WorkerBundle\Annotation;

 

use Doctrine\Common\Annotations\Annotation;

 

/**

 * @Annotation

 * @Target("CLASS")

 */

class Worker

{

    /**

     * @Required

     *

     * @var string

     */

    public $name;

 

    /**

     * @Required

     *

     * @var int

     */

    public $speed;

 

    /**

     * @return string

     */

    public function getName()

    {

        return $this->name;

    }

 

    /**

     * @return int

     */

    public function getSpeed()

    {

        return $this->speed;

    }

}

登录后复制
登录后复制

管理器

接下来,我们需要一个管理器,我们的应用程序可以使用它来获取所有可用worker的列表并创建它们。在与WorkerInterface相同的命名空间中,我们可以使用这个简单的管理器类:

1

use WorkerBundle\Annotation\Worker;

登录后复制

发现器

我们注解演示的关键部分实际上是发现过程的一部分。为什么?因为我们使用Worker注解来确定是否应将相应的类视为Worker。在此过程中,我们在实际实例化对象之前使用了元数据。让我们看看我们的WorkerDiscovery类:

1

2

3

4

5

6

7

<?php

namespace WorkerBundle\Workers;

 

class WorkerManager

{

    // ... (代码与原文相同) ...

}

登录后复制

连接起来

现在我们有了主要组件,是时候将所有内容连接起来了。首先,我们需要服务定义,因此在捆绑包的Resource/config文件夹中,我们可以有这个services.yml文件:

1

2

3

4

5

<?php

namespace WorkerBundle\Workers;

 

// ... (代码与原文相同) ...

}

登录后复制

为了使我们的服务定义能够被容器集中拾取,我们需要编写一个小的扩展类。因此,在捆绑包的DependencyInjection文件夹中,创建一个名为WorkerExtension的类。位置和名称对于Symfony自动拾取它都很重要。

1

2

3

4

5

6

7

services:

    worker_manager:

        class: WorkerBundle\Workers\WorkerManager

        arguments: ["@worker_discovery"]

    worker_discovery:

        class: WorkerBundle\Workers\WorkerDiscovery

        arguments: ["%worker_namespace%", "%worker_directory%", "%kernel.root_dir%", "@annotation_reader"]

登录后复制

最后,我们需要注册我们的捆绑包。在我们的AppKernel中:

1

2

3

4

5

<?php

namespace WorkerBundle\DependencyInjection;

 

// ... (代码与原文相同) ...

}

登录后复制

就是这样。

让我们工作!

现在我们准备工作了。让我们在中央parameters.yml文件中配置我们的worker将在哪里找到:

1

2

3

4

5

6

7

8

public function registerBundles()

{

    return array(

        // ...

        new WorkerBundle\WorkerBundle(),

        // ...

    );

}

登录后复制

这些参数从容器传递到WorkerDiscovery类,如上所述。

位置由您决定,但现在让我们将我们的worker放在应用程序的主要AppBundle捆绑包中。我们的第一个worker可能如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

<?php

namespace WorkerBundle\Workers;

 

interface WorkerInterface

{

    /**

     * 执行工作

     *

     * @return NULL

     */

    public function work();

}

登录后复制
登录后复制
登录后复制

我们的注解在那里,use语句到位,因此没有任何东西可以阻止某些业务逻辑找到它并实例化它。让我们假设在一个Controller方法内部:

1

2

3

4

5

6

/**

 * @Worker(

 *     name = "唯一的Worker名称",

 *     speed = 10

 * )

 */

登录后复制
登录后复制

或者

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

<?php

namespace WorkerBundle\Annotation;

 

use Doctrine\Common\Annotations\Annotation;

 

/**

 * @Annotation

 * @Target("CLASS")

 */

class Worker

{

    /**

     * @Required

     *

     * @var string

     */

    public $name;

 

    /**

     * @Required

     *

     * @var int

     */

    public $speed;

 

    /**

     * @return string

     */

    public function getName()

    {

        return $this->name;

    }

 

    /**

     * @return int

     */

    public function getSpeed()

    {

        return $this->speed;

    }

}

登录后复制
登录后复制

结论

我们现在可以使用注解来表达有关类(或方法和属性)的元数据。在本教程中,我们构建了一个小型包,它使应用程序(或其他外部捆绑包)能够通过定义有关它们的某些元数据来声明能够执行某些工作的worker。此元数据不仅使它们易于发现,而且还提供有关是否应该实际使用它们的信息。

Your Own Custom Annotations - More than Just Comments!

您在自己的项目中使用自定义注解吗?如果是这样,您是如何实现它们的?也许还有第三种方法?让我们知道!


(感兴趣了解更多关于Symfony、Doctrine、注解以及各种企业级PHP内容的信息?加入我们,参加为期三天的动手研讨会,WebSummerCamp——唯一一个完全手动的会议,并且还会照顾您想带去的任何人!)

(原文的FAQ部分已省略,因为其内容与已翻译和改写的内容高度重复。)

以上是您自己的自定义注释 - 不仅仅是评论!的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1246
24
PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? 说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP如何安全地上载文件? PHP如何安全地上载文件? Apr 10, 2025 am 09:37 AM

PHP通过$\_FILES变量处理文件上传,确保安全性的方法包括:1.检查上传错误,2.验证文件类型和大小,3.防止文件覆盖,4.移动文件到永久存储位置。

PHP类型提示如何起作用,包括标量类型,返回类型,联合类型和无效类型? PHP类型提示如何起作用,包括标量类型,返回类型,联合类型和无效类型? Apr 17, 2025 am 12:25 AM

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。

PHP的持久相关性:它还活着吗? PHP的持久相关性:它还活着吗? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP与Python:了解差异 PHP与Python:了解差异 Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

See all articles