【问题标题】:php, refreshing ReflectionClass after dynamic changephp,动态变化后刷新ReflectionClass
【发布时间】:2020-07-23 00:42:54
【问题描述】:

我正在尝试构建一个工具来为我在一个类中添加/删除方法,基本上节省了我输入一些我在我的框架中使用的标准方法的时间。

但是,在我看来,ReflectionClass 的 getMethods 方法使用某种缓存,因为如果我调用 getMethods 一次,然后动态更改方法(例如实例将类文件替换为另一个类名相同但方法不同的类文件),然后再次调用getMethods,它没有考虑我的动态变化。

我试过睡眠,但显然不是这样。

我想知道 php 中是否有一种方法(但恐怕没有)来“刷新”ReflectionClass,以便它可以“反映”实际内容而不是某种缓存。

作为一种变通方法,我可以依赖令牌,但这比仅使用反射类需要更多的工作,所以如果我能以某种方式“重置”反射缓存会很棒。

【问题讨论】:

  • 基本上节省了我输入一些我在框架中使用的标准方法的时间。这听起来像是继承应该做的事情。
  • @Nigel Ren。在这种情况下,我有理由更喜欢代码生成而不是继承:我想要一个“点菜”生成工具,继承对于我想要实现的目标并不灵活(许多不同的方法在许多不同的域),基本上我正在为我从自己的编码风格中确定的一些模式构建一个开发者向导。
  • @ling 你能说更多关于“用另一个替换类文件”的事情吗?您不能要求/重新声明同一类。您的意思是在文件执行时物理替换文件的内容吗?我认为这对调用不提及反射的方法甚至没有影响。
  • @blahy,是的,完全正确:在 php 进程运行时物理替换文件的内容。因此,例如在 t=1 时在文件上调用反射,tnen 在同一脚本期间使用 unlink 和 file_put_contents 之类的内容更改文件内容,然后在同一文件上再次使用反射,但在 t=2 时,反射正在显示t=1 时文件的内容。
  • @ling 我想到了你写的东西,但仍然不知道你是如何替换课程的,因为我认为这是不可能的。请看一下我的回答,如果我的假设有误,请使用实际代码更新您的问题,在这些代码中,您的类使用更新后的代码可以正常工作,但反射不能。

标签: php reflection


【解决方案1】:

由于您的限制,我看不到本地执行此操作的方法。

也许您可以考虑使用 runkit https://www.php.net/manual/en/function.runkit-method-redefine.php,因为这似乎是可能的(也许它会满足您的需求),但我会在回答中坚持使用基础 PHP。

你永远不会在文件上使用反射,你在类/函数上使用反射等等,等等。并且要在一个类上使用反射,你必须首先声明它(require、autoload 等),一旦它被声明,你就不能重新声明它。尝试 require 具有相同类的文件会导致错误。

因此,需要一个带有类的文件,使用该类然后更改文件本身将没有任何效果。看一下代码:

<?php

file_put_contents('a.php', '<?php class A {function a() {return "a";}}');

require('a.php');

$a = new A();
var_dump($a->a());

file_put_contents('a.php', '<?php class A {function b() {return "b";}}');

$a = new A();
var_dump($a->b());

此时甚至没有提到反射——你如何让这段代码打印“b”?您将获得PHP Fatal error: Uncaught Error: Call to undefined method A::b() in ...,因为定义的版本仍然是您需要的版本。再次请求文件将导致PHP Fatal error: Cannot declare class A, because the name is already in use in ...

所以我认为反射工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2011-12-23
    • 2011-08-02
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多