php 使用反射方式(ReflectionClass|ReflectionMethod)创建类和执行类方法

方文锋  2025-12-29 21:47:16  63  首页学习PHP

代码如下:


<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2025/12/24
 * Time: 14:55
 */

/**
 * 类的容器
 * Class Container
 */
class Container
{
    /**
     * 用于存放资源,如对象和数组
     * @var array
     */
    private static $instances = array();

    /**
     * 获取 self::$instances
     * @param string $name
     * @return array|object|mixed
     */
    static public function &get_instance($name = '')
    {
        return self::y_string($name) ? self::$instances[self::keyName($name)] : self::$instances;
    }

    /**
     * 设置添加 self::$instances
     * @param object|array|string $resource 类|数组|类名称
     * @param string $aliasName
     */
    static public function set_instance(&$resource, $aliasName = '', $args = [])
    {
        if (self::y_string($resource)) {
            $name = $resource;
            self::y_string($aliasName) && ($name = $aliasName);
            $class = self::new_class($resource, $args);
            self::instance_exist($name) || (self::$instances[self::keyName($name)] = &$class);
        } elseif (is_object($resource)) {
            $name = get_class($resource);
            self::y_string($aliasName) && ($name = $aliasName);
            self::instance_exist($name) || (self::$instances[self::keyName($name)] = $resource);
        } elseif (is_array($resource) && self::y_string($aliasName)) {
            $name = $aliasName;
            self::instance_exist($name) || (self::$instances[self::keyName($name)] = $resource);
        }
    }

    /**
     * 移除 self::$instances
     * @param string $name
     */
    static public function remove_instance($name = '')
    {
        if (self::y_string($name) && self::instance_exist($name)) {
            unset(self::$instances[self::keyName($name)]);
        }
    }

    /**
     * 清楚全部 self::$instances
     */
    static public function clear_instance()
    {
        foreach (self::$instances as $key => $instance) {
            unset(self::$instances[$key]);
        }
        self::$instances = [];
    }

    /**
     * @param string $name
     * @return array|mixed|object
     */
    public static function get_object($name = '', $args = [])
    {
        if (self::y_string($name)) {
            $resource = self::get_instance($name);
        }
        if (!is_object($resource)) {
            self::set_instance($name, '', $args);
            $resource = self::get_instance($name);
        }
        return $resource;
    }

    /**
     * 使用类反射创建类实例
     * @param object|string $class
     * @param array $args
     * @return object
     * @throws ReflectionException
     */
    public static function &new_class($class, $args = [])
    {
        $args = is_array($args) ? $args : [];
        $Reflection = new ReflectionClass($class);
        return $Reflection->newInstanceArgs($args);
    }

    /**
     * 格式化参数,转为下标为数字的数组
     * @param array $args
     * @return array
     */
    public static function newInstanceArgsFormat($args = [])
    {
        $arguments = [];
        if (is_array($args) && count($args) > 0) {
            foreach ($args as $index => $arg) {
                $arguments[] = $arg;
            }
        }
        unset($args);
        return $arguments;
    }

    /**
     * 获取类方法的参数类型数据
     * @param object|ReflectionMethod|string $class
     * @param string $method
     * @return array|bool
     * @throws ReflectionException
     */
    public static function methodArgs($class, $method = '')
    {
        if ($class instanceof ReflectionMethod) {
            $reflectionMethod = $class;
            $parameters = $reflectionMethod->getParameters();
            $args_msg = [];
            $args_type = [];
            foreach ($parameters as $index => $parameter) {
                $type = $parameter->getType();
                $name = $parameter->getName();
                $selfClass = $parameter->getClass();
                $defaultValue = false;
                $parameter->isDefaultValueAvailable() && ($defaultValue = $parameter->getDefaultValue());
                if ($type === null) {
                    $typeName = 'mixed';
                } else {
                    if ($type instanceof ReflectionNamedType) {
                        $typeName = $type->getName();
                    } elseif ($type instanceof ReflectionType) {
                        $typeName = $type->getName();
                    } else {
                        $typeName = (string)$type;
                    }
                }
                $args_type[] = $typeName;
                $args_msg[] = ['name' => $name, 'type' => $typeName, 'value' => $defaultValue];
            }
            return ['type' => $args_type, 'msg' => $args_msg];
        } elseif (is_object($class) || class_exists($class)) {
            $reflectionMethod = new ReflectionMethod($class, $method);
            return self::methodArgs($reflectionMethod, $method);
        }
        return false;
    }

    /**
     * 执行类的方法
     * @param object $class
     * @param string $method
     * @param array $args
     */
    public static function methodInvokeArgs($class, $method = '', $args = [])
    {
        $reflectionMethod = new ReflectionMethod($class, $method);
        $methodArgs = self::methodArgs($reflectionMethod, $method);
        $newArgs = [];
        if ($methodArgs) {
            $typeArgs = $methodArgs['type'];
            $msgArgs = $methodArgs['msg'];
            foreach ($msgArgs as $index => $msgArg) {
                $var_name = $msgArg['name'];
                $type = $msgArg['type'];
                $def_val = $msgArg['value'];
                $argsTypeGet = self::argsTypeGet($args, $type);
                $ok_ATG = is_array($argsTypeGet);
                if (!in_array(strtolower($type), ['bool', 'boolean', 'int', 'integer', 'float', 'double', 'string', 'array', 'callable', 'resource', 'mixed'], true)) {
                    $className = $type;
                    if ($ok_ATG) {
                        $newArgs[] = $className === $argsTypeGet['type'] ? $argsTypeGet['value'] : self::get_object($type);
                        unset($args[$argsTypeGet['key']]);
                    } else {
                        $newArgs[] = self::get_object($type);
                    }
                } else {
                    if ($ok_ATG && $type === $argsTypeGet['type']) {
                        $newArgs[] = $argsTypeGet['value'];
                        unset($args[$argsTypeGet['key']]);
                    } elseif (self::y_string($def_val) && preg_match("/^([@:]{1}.+)$/", $def_val)) {
                        $key = trim($def_val, ':@');
                        if (self::is_exist($args[$key])) {
                            $newArgs[] = $args[$key];
                            unset($args[$key]);
                        } else {
                            $newArgs[] = '';
                        }
                    } elseif (self::is_exist($args[$var_name])) {
                        $newArgs[] = $args[$var_name];
                        unset($args[$var_name]);
                    } else {
                        continue;
                    }
                }
            }
            $newArgs = array_merge($newArgs, $args);
        }
        return $reflectionMethod->invokeArgs($class, $newArgs);
    }

    /**
     * 获取符合类型的参数值
     * @param array $args
     * @param string $type 参数数据类型
     * @return array|bool
     */
    public static function argsTypeGet($args = [], $type = '')
    {
        $argType = 'mixed';
        foreach ($args as $index => $arg) {
            if (is_object($arg)) {
                $argType = get_class($arg);
            } elseif (is_array($arg)) {
                $argType = 'array';
            } elseif (is_int($arg)) {
                $argType = 'int';
            } elseif (is_integer($arg)) {
                $argType = 'integer';
            } elseif (is_float($arg)) {
                $argType = 'float';
            } elseif (is_double($arg)) {
                $argType = 'double';
            } elseif (is_string($arg)) {
                $argType = 'string';
            } elseif (is_bool($arg)) {
                $argType = 'bool';
            } elseif (is_callable($arg)) {
                $argType = 'callable';
            } elseif (is_null($arg)) {
                $argType = 'null';
            }

            if ($type === $argType) {
                return ['key' => $index, 'value' => $arg, 'type' => $argType];
            }
        }
        return false;
    }

    /**
     * 检擦是否是对象和数组
     * @param string $name
     * @return bool
     */
    static public function instance_exist($name = '')
    {
        $name = self::keyName($name);
        return is_object(self::$instances[$name]) || is_array(self::$instances[$name]);
    }

    static private function keyName($name = '')
    {
        return md5($name . '@Container/instances');
    }

    static public function y_string($str = '')
    {
        return !in_array($str, array('', null, false), true) && (is_string($str) || is_numeric($str));
    }

    public static function is_exist($var = '', $opt = array('', null, false))
    {
        return !in_array($var, $opt, true);
    }

    /**
     * 正则表达式字符串转义
     * @param string|array $string
     * @param string $preg
     * @param int $op
     * @return array|null|string|string[]
     */
    private static function escape_preg_string($string = '', $preg = '', $op = 1)
    {
        $preg = self::y_string($preg) ? $preg : "([{}()\[\]?.*+\\\\\|\/\-])";
        $replacement = $op == 2 ? "\\\\\\\\\$1" : "\\\\\$1";
        if (self::y_string($string)) {
            $string = preg_replace("/({$preg})/", "$replacement", $string);
        } elseif (is_array($string) && count($string) > 0) {
            foreach ($string as $index => $item) {
                if (self::y_string($item)) {
                    $string[$index] = preg_replace("/($preg)/", "$replacement", $item);
                } else {
                    continue;
                }
            }
        }
        return $string;
    }
}



<?php
// 使用类反射创建类实例
Container::new_class($class, $args);
//执行类的方法
Container::methodInvokeArgs($class, $method, $args);
//获取类对象
Container::get_object($className,$args);
?>


相关的项目地址: https://gitee.com/fang_wen_feng/my_php_plugCode/tree/phpcode/phpCode/project01