php 通过反射 ReflectionMethod 类来获取类方法的相关信息,其中就包含方法的注释内容。
问题描述
在公司测试环境运行以下代码,如果是 cli 命令行模式运行,正常输出代码注释。如果是以网页打开这个页面,却会输出 bool(false)。
<?php class ReflectionTest { /** * 这是测试方法 * * @return int */ protected function methodTest() { return 9999; } } $ref = new ReflectionMethod('ReflectionTest', 'methodTest'); var_dump($ref->getDocComment());
问题解决
问了技术主管,才知道原来是 Opcache 配置项引起的问题。公司测试环境 PHP 开启了 Opcache 扩展,原配置如下:
[opcache] opcache.enable=1 opcache.enable_cli=0 opcache.memory_consumption=128 opcache.interned_strings_buffer=4 opcache.max_accelerated_files=2000 opcache.max_wasted_percentage=5 opcache.use_cwd=1 opcache.validate_timestamps=1 opcache.revalidate_freq=2 opcache.revalidate_path=1 opcache.save_comments=0 opcache.load_comments=0 opcache.fast_shutdown=0 opcache.enable_file_override=0
将 opcache.save_comments=0 改为 opcache.save_comments=1 保存重启 PHP-FPM 进程,即可通过反射获取文档的注释了。
关于 Opcache 的 save_comment 和 load_comments 的含义请参考 PHP 官方文档中的解释:
opcache.save_comment 开启后将脚本文件中的注释内容将会包含到操作码缓存文件中,适用于我所碰到的问题。
opcache.load_comment 开启或者禁用的区别只是应用程序是否会按需加载注释内容,禁用则是按需加载,开启则总是加载。
问题总结
遇到这个问题的时候, 以为是 PHP 版本的问题,我本机的 PHP 5.6 的修订版本号比测试环境的 PHP 5.6 的修订版本号略新一点,打算让运维部门编译一个新版本的 PHP 5.6 到测试服务器上的。还好问了问主管,一下就解决了问题,填补了这个知识盲区。遇问题要多沟通!