PHP   发布时间:2022-04-04  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了PHP对象定义缓存?带有反射的故障删除方法大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在研究一个对象,以允许我们修改包含PHP对象的PHP文件. (具体来说,它们是我们必须修改的Doctrine实体文件.)

无论如何,这里没有无聊的细节.我首先找到类文件的位置,并包含它.然后,使用下面的代码创建类的实例和类反射器.如您所见,当实例化对象和反射器时,我还调用一个方法,将类的文本从磁盘加载到字符串中,另一个方法是将该字符串按行拆分为数组.

public function loadClass()
   if(!class_exists($this->class_name)) {
      $this->error = "Class name: '$this->class_name' was not found.";}
   else {
      //Class is found. Load it and populate properties
      $this->oClass          = new $this->class_name;
      $this->oRClass         = new \ReflectionClass($this->oClass);
      $this->source_file     = $this->oRClass->getFileName();
      $this->error           = "";
      $this->class_namespace = $this->oRClass->getNamespaceName();
      $this->getClassText();  //Load class code from source file
      $this->getClassArray(); //Load class text into array
   }
}

然后,我使用一个名为“ deleteMethod()”的函数删除特定方法PHP代码,如下所示:$this-> deleteMethod(“ badMethod”);.然后,此函数查找所要方法的开始行和结束行,删除该行,将PHP代码保存回磁盘,然后再次运行“ loadClass()”以重新解析更新的对象,以便为更多编辑.下面是“ deleteMethod()”函数的摘录.

$oMethod = $this->oRClass->getmethod($meth_name);       //Get a refection method object 
$oMethod->setAccessible(true);                          //In case method is private
$start_line = $oMethod->getStartLine() -1;              //Line method starts at
$length = $oMethod->getEndLine() - $start_line + 1      //Number of lines in method
array_splice($this->class_array, $start_line, $length); //Hack lines out of array
$this->class_text = implode("\n", $this->class_array);  //Convert array back to a string
$this->saveClassText();                              //Save updated code back to disk.
$this->loadClass();                                     //Reload and reparse for consistancy

问题在于该对象将被缓存在某个地方.当我运行$this-> deleteMethod(“ anotherBadMethod”);时,再次起作用,它将不再为下一个删除方法返回正确的开始/结束行.经过一番检查之后,很明显发生了什么事情,当我尝试获取删除的下一个方法的开始/结束行时,PHP仍在使用OLD类定义.似乎“看不到”某些代码已从文件删除,并且行号已更改.如您所见,每次运行loadClass()时,我都实例化了对象和反射对象.是的,我尝试在实例化它们之前将它们设置为NULL.

我还验证了PHP可以正确看到类定义文件.这意味着即使包含了文件,反射getFileName();确实看到该类已定义在应该在的位置.

Soooo …. PHP是否在缓存我包含在内存中的类的定义?如果是这样,我该如何充值现金?有什么办法可以“取消定义”该类并重新加载它?任何帮助将不胜感激.

解决方法:

这是不可能的. PHP只能加载一次类定义.将其加载并放入内存后,“刷新”它的唯一方法是终止脚本并重新执行它.如果尝试重新包含该文件,显然会得到“类已定义的错误”.无论脚本运行多长时间,一旦类定义存储在内存中,就无法更改(除非您使用第三方扩展名).

Reflection API适用于内存中的类定义,而不适用于磁盘上的类定义.

我认为您可以从以下三个选项中进行选择:

>使用磁盘上的类定义.这意味着您不能使用反射,而必须使用标记器/解析器.
>篡改文件,以便将该类重新加载到另一个名称空间中.因为一旦定义了它们,就无法卸载它们,这将极大地污染您的全局命名空间.
>执行在单独的过程中加载/修改类的脚本.当该过程开始时,它将加载类定义,并在终止时将其遗忘,从而产生您想要的“刷新”效果.显然,这是您最好的选择.

大佬总结

以上是大佬教程为你收集整理的PHP对象定义缓存?带有反射的故障删除方法全部内容,希望文章能够帮你解决PHP对象定义缓存?带有反射的故障删除方法所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: