不使用eval将数据库存储的类名字符串转为可调用类的实现方法
字符串转可调用类的无eval实现方案
你提到的::类层级写法常见于PHP、Ruby两类编程语言,以下分别给出对应实现:
PHP 场景
PHP原生支持类名字符串直接调用,不需要依赖eval:
- 如果存储的
::就是实际类名的一部分(如嵌套类、类常量指向的类),可直接使用:
// 从数据库取出的字符串 $classStr = "Mymodel::FirstClass"; // 校验类是否存在(必加,避免非法输入报错) if (class_exists($classStr)) { // 实例化 $instance = new $classStr(); // 调用静态方法 $result = $classStr::staticMethod(); }
- 如果存储的
::是命名空间分隔符的写法替代(实际为Mymodel\FirstClass),先做字符替换再使用:
$classStr = str_replace('::', '\\', "Mymodel::FirstClass"); if (class_exists($classStr)) { $instance = new $classStr(); }
Ruby 场景
Ruby使用const_get方法递归获取命名空间下的类,全程无eval:
# 从数据库取出的字符串 class_str = "Mymodel::FirstClass" # 递归查找类 klass = class_str.split("::").inject(Object) { |parent, const_name| parent.const_get(const_name) } # 校验是否为合法类 if klass.is_a?(Class) # 实例化 instance = klass.new # 调用类方法 result = klass.some_class_method end
安全提示:数据库存储的字符串属于外部不可信输入,建议提前维护合法类名白名单,只有输入匹配白名单内的类时才执行后续操作,避免恶意输入调用敏感类引发安全问题。
内容的提问来源于stack exchange,提问作者Tilipim
相关产品推荐
相关产品推荐

