关于PHP部分框架中 action 参数绑定的原理

php中文网
发布: 2016-07-06 13:53:58
原创
1411人浏览过

例如thinkphp

<code>class xxController
{
    public function index($id,$age)
    {
        //这些参数是通过$_GET['id'],$_GET['age']来的
        
    }
}
//按PHP的实现方法大致应该是以下
$ctr = new xxController();
return $ctr->index(); //他这里怎么有知道应该传哪些参数呢?!

//本人愚钝,我想不是这样做的,那应该是怎么实现呢?!!请各位大神讲解一下其中的实现原理!</code>
登录后复制

回复内容:

例如thinkphp

<code>class xxController
{
    public function index($id,$age)
    {
        //这些参数是通过$_GET['id'],$_GET['age']来的
        
    }
}
//按PHP的实现方法大致应该是以下
$ctr = new xxController();
return $ctr->index(); //他这里怎么有知道应该传哪些参数呢?!

//本人愚钝,我想不是这样做的,那应该是怎么实现呢?!!请各位大神讲解一下其中的实现原理!</code>
登录后复制

反射,通过反射得的类的方法的参数列表。然后对应起来就可以。

<code><?php
/**
 * 一个用于测试的类
 * Class TestController
 */
class TestController {
    /**
     * 嗯,著名的hello world
     * @param $name
     */
    public function helloWordAction($name)
    {
        echo "hello {$name}!".PHP_EOL;
    }
}

# 通过反射进行参数绑定调起类的方法
# @see http://php.net/manual/zh/book.reflection.php

# 方法,从路由获取的,类也是由路由获取的,这里意思一下就好了
$action = 'helloWordAction';
# 传进来的参数,从路由获取的
$paramsInput['name'] = 'toozy';

# 获取类的反射
$controllerReflection = new ReflectionClass(TestController::class);
# 不能实例化,就是不能new一个的话,这个游戏就玩不下去了啊
if (!$controllerReflection->isInstantiable()) {
    throw new RuntimeException("{$controllerReflection->getName()}不能被实例化");
}

# 获取对应方法的反射
if (!$controllerReflection->hasMethod($action)) {
    throw new RuntimeException("{$controllerReflection->getName()}没有指定的方法:{$action}");
}
$actionReflection = $controllerReflection->getMethod($action);
# 获取方法的参数的反射列表(多个参数反射组成的数组)
$paramReflectionList = $actionReflection->getParameters();
# 参数,用于action
$params = [];
# 循环参数反射
# 如果存在路由参数的名称和参数的名称一致,就压进params里面
# 如果存在默认值,就将默认值压进params里面
# 如果。。。没有如果了,异常
foreach ($paramReflectionList as $paramReflection) {
    # 是否存在同名字的路由参数
    if (isset($paramsInput[$paramReflection->getName()])) {
        $params[] = $paramsInput[$paramReflection->getName()];
        continue;
    }
    # 是否存在默认值
    if ($paramReflection->isDefaultValueAvailable()) {
        $params[] = $paramReflection->getDefaultValue();
        continue;
    }
    # 异常
    throw new RuntimeException(
        "{$controllerReflection->getName()}::{$actionReflection->getName()}的参数{$paramReflection->getName()}必须传值"
    );
}

# 调起
$actionReflection->invokeArgs($controllerReflection->newInstance(), $params);</code>
登录后复制

保存为:reflection.php

<code>root@work:/media/sf_project/php-hello-world# php refrection.php 
hello toozy!</code>
登录后复制

这种情况的框架都有一个“路由定义”,客户端只能匹配到定义好的路由,包含了路径、Method、以及请求参数。
拿 Laravel 举例:

Action Figure AI
Action Figure AI

借助Action Figure AI的先进技术,瞬间将照片转化为定制动作人偶。

Action Figure AI 68
查看详情 Action Figure AI

立即学习PHP免费学习笔记(深入)”;

<code>Route::get('api/article/{articleId}', 'ArticleController@articleDetail');

//...

ArticleController extends Controller
{
    public function articleDetail($articleId)
    {
        //...
    }
}</code>
登录后复制

在匹配路由过程,因为定义的这个路由包含了{articleId} 这个约定好形式的占位符,路由模块会匹配包含 articleId 的 URL,并获取到参数值传给对应 Controller 的 action。

相关标签:
php
PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号