我正在研究一个对象以允许我们修改包含PHP对象的PHP文件。 (具体而言,它们是我们必须修改的Doctrine实体文件。)PHP对象定义缓存?使用反射删除方法时遇到问题
无论如何,这里没有无聊的细节就是发生了什么。我首先找到类文件的位置,并且包含它。然后,我使用下面的代码创建类的实例和类反射器。正如你所看到的,当我实例化对象和反射器时,我还调用一个方法将类的文本从磁盘加载到字符串中,另一种方法是将该字符串按行分解成数组。
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
问题是,对象apears被缓存在某处。当我再次运行$this->deleteMethod("anotherBadMethod");
函数时,它不再为下一个要删除的方法返回适当的开始/结束行。经过一番检查,很明显发生的事情是,当我尝试获取下一个方法的开始/结束行时,PHP仍然使用OLD类定义。它似乎没有“看到”某些代码已从文件中删除,并且行号已更改。正如你所看到的,每当我们运行loadClass()
时,我都会实例化对象和反射对象。是的,我试图在设置它们之前将它们设置为NULL。
我也验证了PHP能够正确地看到类定义文件。这意味着即使该文件包含在内,反射getFileName();
确实可以看到该类被定义在应该在的位置。
Soooo .... PHP是否缓存了我已经包含在内存中的类的定义?如果是这样,我该如何冲洗这些现金?有没有什么方法可以“取消定义”,该类,并重新加载?任何帮助将不胜感激。
我不明白你为什么使用反射而不是真实物体 – dynamic 2011-06-02 20:44:26