Laravel框架源码中反射机制如何具体应用和详解?

2026-04-01 06:561阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1597个文字,预计阅读时间需要7分钟。

Laravel框架源码中反射机制如何具体应用和详解?

原文示例:本文字例讲述了Laravel框架源码解析中反射的使用。分享给广大开发者供参考,具体如下:

前言:PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法、成员,而反射则是拆解封装类。

解析:

1.反射类:PHP中,反射类提供了一种动态访问类、方法和属性的能力。通过反射,可以获取类的信息,如类名、父类、接口、属性、方法等。

2.实例化对象:实例化对象是创建一个类的实例,即创建一个对象。通过实例化,可以调用类中的方法、访问属性。

Laravel框架源码中反射机制如何具体应用和详解?

3.反射与实例化的作用:

- 实例化:调用封装类中的方法、成员,实现类的设计功能。 - 反射:拆解封装类,获取类的信息,用于动态访问和操作。

在Laravel框架中,反射被广泛应用于以下几个方面:

1. 服务容器:Laravel的服务容器利用反射机制,动态解析和绑定服务。当请求一个服务时,服务容器会通过反射找到对应的类,并实例化对象。

2.路由解析:Laravel的路由解析器使用反射来解析路由参数,并将请求分配给对应的控制器方法。

3.控制器解析:控制器解析器通过反射获取控制器类的属性和方法,实现路由请求与控制器方法的映射。

4.依赖注入:Laravel的依赖注入容器利用反射机制,动态解析和注入依赖关系。

总结:反射在Laravel框架中发挥着重要作用,它使得框架更加灵活、可扩展。通过反射,Laravel能够动态解析和操作类、方法、属性,为开发者提供便捷的开发体验。

本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如下:

前言

PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法、成员,而反射类则是拆封类中的所有方法、成员变量,并包括私有方法等。就如“解刨”一样,我们可以调用任何关键字修饰的方法、成员。当然在正常业务中是建议不使用,比较反射类已经摒弃了封装的概念。

本章讲解反射类的使用及Laravel对反射的使用。

反射

反射类是PHP内部类,无需加载即可使用,你可以通过实例化 ReflectionClass 类去使用它。

方法

这里列举下PHP反射类常用的方法

方法名 注释 ReflectionClass::getConstant 获取定义过的一个常量 ReflectionClass::getConstants 获取一组常量 ReflectionClass::getConstructor 获取类的构造函数 ReflectionClass::getDefaultProperties 获取默认属性 ReflectionClass::getDocComment 获取文档注释 ReflectionClass::getEndLine 获取最后一行的行数 ReflectionClass::getFileName 获取定义类的文件名 ReflectionClass::getInterfaceNames 获取接口(interface)名称 ReflectionClass::getMethods 获取方法的数组 ReflectionClass::getModifiers 获取类的修饰符 ReflectionClass::getName 获取类名 ReflectionClass::getNamespaceName 获取命名空间的名称 ReflectionClass::getParentClass 获取父类

等等等等.... 所有关于类的方法、属性及其继承的父类、实现的接口都可以查询到。
详细文档请参考官网: php.net/manual/zh/class.reflectionclass.php

栗子

<?php namespace A\B; class Foo { } $function = new \ReflectionClass('stdClass'); var_dump($function->inNamespace()); var_dump($function->getName()); var_dump($function->getNamespaceName()); var_dump($function->getShortName()); $function = new \ReflectionClass('A\\B\\Foo'); var_dump($function->inNamespace()); var_dump($function->getName()); var_dump($function->getNamespaceName()); var_dump($function->getShortName()); ?>

输出结果

bool(false) string(8) "stdClass" string(0) "" string(8) "stdClass" bool(true) string(7) "A\B\Foo" string(3) "A\B" string(3) "Foo"

Laravel

Laravel在实现服务容器加载时使用了反射类。现在我们开启“解刨”模式

入口文件

index.php

$app = require_once __DIR__.'/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- | Run The Application |-------------------------------------------------------------------------- | | Once we have the application, we can handle the incoming request | through the kernel, and send the associated response back to | the client's browser allowing them to enjoy the creative | and wonderful application we have prepared for them. | */ $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);

是引用语句发生的下一行调用了make方法。各位很清楚,make方法用于解析类,所有make方法的实现一定是在引用的文件内。

bootstrap\app.php

$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') );

laravel开始加载它的核心类,所有的实现从 Illuminate\Foundation\Application 开始。

Illuminate\Foundation\Application

public function make($abstract, array $parameters = []) { $abstract = $this->getAlias($abstract); if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) { $this->loadDeferredProvider($abstract); } return parent::make($abstract, $parameters); }

在核心类中你可能准确的查找到make方法的存在,它加载了服务提供者随后调用了父类的方法make,要知道作为独立的模块 “服务容器”是绝对不能写在核心类的。懂点设计模式的都很清楚。

Illuminate\Container\Container

$api = $this->app->make('HelpSpot\API',['id'=>1]); 为例来讲解

// 真正的make方法,它直接调用了resolve继续去实现make的功能 // $abstract = 'HelpSpot\API' public function make($abstract, array $parameters = []) { // $abstract = 'HelpSpot\API' return $this->resolve($abstract, $parameters); } ... protected function resolve($abstract, $parameters = []) { ... // 判断是否可以合理反射 // $abstract = 'HelpSpot\API' if ($this->isBuildable($concrete, $abstract)) { // 实例化具体实例 (实际并不是实例化,而是通过反射“解刨”了) $object = $this->build($concrete); } else { $object = $this->make($concrete); } ... } public function build($concrete) { // $concrete = 'HelpSpot\API' if ($concrete instanceof Closure) { return $concrete($this, $this->getLastParameterOverride()); } // 实例化反射类 $reflector = new ReflectionClass($concrete); // 检查类是否可实例化 if (! $reflector->isInstantiable()) { return $this->notInstantiable($concrete); } $this->buildStack[] = $concrete; // 获取类的构造函数 $constructor = $reflector->getConstructor(); if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } $dependencies = $constructor->getParameters(); $instances = $this->resolveDependencies( $dependencies ); array_pop($this->buildStack); // 从给出的参数创建一个新的类实例。 return $reflector->newInstanceArgs($instances); }

可见一个服务容器就加载成功了。

更多关于Laravel相关内容感兴趣的读者可查看本站专题:《Laravel框架入门与进阶教程》、《php优秀开发框架总结》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

标签:使用详解

本文共计1597个文字,预计阅读时间需要7分钟。

Laravel框架源码中反射机制如何具体应用和详解?

原文示例:本文字例讲述了Laravel框架源码解析中反射的使用。分享给广大开发者供参考,具体如下:

前言:PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法、成员,而反射则是拆解封装类。

解析:

1.反射类:PHP中,反射类提供了一种动态访问类、方法和属性的能力。通过反射,可以获取类的信息,如类名、父类、接口、属性、方法等。

2.实例化对象:实例化对象是创建一个类的实例,即创建一个对象。通过实例化,可以调用类中的方法、访问属性。

Laravel框架源码中反射机制如何具体应用和详解?

3.反射与实例化的作用:

- 实例化:调用封装类中的方法、成员,实现类的设计功能。 - 反射:拆解封装类,获取类的信息,用于动态访问和操作。

在Laravel框架中,反射被广泛应用于以下几个方面:

1. 服务容器:Laravel的服务容器利用反射机制,动态解析和绑定服务。当请求一个服务时,服务容器会通过反射找到对应的类,并实例化对象。

2.路由解析:Laravel的路由解析器使用反射来解析路由参数,并将请求分配给对应的控制器方法。

3.控制器解析:控制器解析器通过反射获取控制器类的属性和方法,实现路由请求与控制器方法的映射。

4.依赖注入:Laravel的依赖注入容器利用反射机制,动态解析和注入依赖关系。

总结:反射在Laravel框架中发挥着重要作用,它使得框架更加灵活、可扩展。通过反射,Laravel能够动态解析和操作类、方法、属性,为开发者提供便捷的开发体验。

本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如下:

前言

PHP的反射类与实例化对象作用相反,实例化是调用封装类中的方法、成员,而反射类则是拆封类中的所有方法、成员变量,并包括私有方法等。就如“解刨”一样,我们可以调用任何关键字修饰的方法、成员。当然在正常业务中是建议不使用,比较反射类已经摒弃了封装的概念。

本章讲解反射类的使用及Laravel对反射的使用。

反射

反射类是PHP内部类,无需加载即可使用,你可以通过实例化 ReflectionClass 类去使用它。

方法

这里列举下PHP反射类常用的方法

方法名 注释 ReflectionClass::getConstant 获取定义过的一个常量 ReflectionClass::getConstants 获取一组常量 ReflectionClass::getConstructor 获取类的构造函数 ReflectionClass::getDefaultProperties 获取默认属性 ReflectionClass::getDocComment 获取文档注释 ReflectionClass::getEndLine 获取最后一行的行数 ReflectionClass::getFileName 获取定义类的文件名 ReflectionClass::getInterfaceNames 获取接口(interface)名称 ReflectionClass::getMethods 获取方法的数组 ReflectionClass::getModifiers 获取类的修饰符 ReflectionClass::getName 获取类名 ReflectionClass::getNamespaceName 获取命名空间的名称 ReflectionClass::getParentClass 获取父类

等等等等.... 所有关于类的方法、属性及其继承的父类、实现的接口都可以查询到。
详细文档请参考官网: php.net/manual/zh/class.reflectionclass.php

栗子

<?php namespace A\B; class Foo { } $function = new \ReflectionClass('stdClass'); var_dump($function->inNamespace()); var_dump($function->getName()); var_dump($function->getNamespaceName()); var_dump($function->getShortName()); $function = new \ReflectionClass('A\\B\\Foo'); var_dump($function->inNamespace()); var_dump($function->getName()); var_dump($function->getNamespaceName()); var_dump($function->getShortName()); ?>

输出结果

bool(false) string(8) "stdClass" string(0) "" string(8) "stdClass" bool(true) string(7) "A\B\Foo" string(3) "A\B" string(3) "Foo"

Laravel

Laravel在实现服务容器加载时使用了反射类。现在我们开启“解刨”模式

入口文件

index.php

$app = require_once __DIR__.'/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- | Run The Application |-------------------------------------------------------------------------- | | Once we have the application, we can handle the incoming request | through the kernel, and send the associated response back to | the client's browser allowing them to enjoy the creative | and wonderful application we have prepared for them. | */ $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);

是引用语句发生的下一行调用了make方法。各位很清楚,make方法用于解析类,所有make方法的实现一定是在引用的文件内。

bootstrap\app.php

$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../') );

laravel开始加载它的核心类,所有的实现从 Illuminate\Foundation\Application 开始。

Illuminate\Foundation\Application

public function make($abstract, array $parameters = []) { $abstract = $this->getAlias($abstract); if (isset($this->deferredServices[$abstract]) && ! isset($this->instances[$abstract])) { $this->loadDeferredProvider($abstract); } return parent::make($abstract, $parameters); }

在核心类中你可能准确的查找到make方法的存在,它加载了服务提供者随后调用了父类的方法make,要知道作为独立的模块 “服务容器”是绝对不能写在核心类的。懂点设计模式的都很清楚。

Illuminate\Container\Container

$api = $this->app->make('HelpSpot\API',['id'=>1]); 为例来讲解

// 真正的make方法,它直接调用了resolve继续去实现make的功能 // $abstract = 'HelpSpot\API' public function make($abstract, array $parameters = []) { // $abstract = 'HelpSpot\API' return $this->resolve($abstract, $parameters); } ... protected function resolve($abstract, $parameters = []) { ... // 判断是否可以合理反射 // $abstract = 'HelpSpot\API' if ($this->isBuildable($concrete, $abstract)) { // 实例化具体实例 (实际并不是实例化,而是通过反射“解刨”了) $object = $this->build($concrete); } else { $object = $this->make($concrete); } ... } public function build($concrete) { // $concrete = 'HelpSpot\API' if ($concrete instanceof Closure) { return $concrete($this, $this->getLastParameterOverride()); } // 实例化反射类 $reflector = new ReflectionClass($concrete); // 检查类是否可实例化 if (! $reflector->isInstantiable()) { return $this->notInstantiable($concrete); } $this->buildStack[] = $concrete; // 获取类的构造函数 $constructor = $reflector->getConstructor(); if (is_null($constructor)) { array_pop($this->buildStack); return new $concrete; } $dependencies = $constructor->getParameters(); $instances = $this->resolveDependencies( $dependencies ); array_pop($this->buildStack); // 从给出的参数创建一个新的类实例。 return $reflector->newInstanceArgs($instances); }

可见一个服务容器就加载成功了。

更多关于Laravel相关内容感兴趣的读者可查看本站专题:《Laravel框架入门与进阶教程》、《php优秀开发框架总结》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

标签:使用详解