争怎路由网/网站教程/内容

php反射类的使用及Laravel对反射的使用介绍

网站教程2024-04-10 阅读
网页的本质就是超级文本标记语言,通过结合使用其他的Web技术(如:脚本语言、公共网关接口、组件等),可以创造出功能强大的网页。因而,超级文本标记语言是万维网(Web)编程的基础,也就是说万维网是建立在超文本基础之上的。超级文本标记语言之所以称为超文本标记语言,是因为文本中包含了所谓“超级链接”点。
本篇文章给大家带来的内容是关于php反射类的使用及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
    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);
}

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

以上就是php反射类的使用及Laravel对反射的使用介绍的详细内容,更多请关注php中文网其它相关文章!


网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。



……