在函数中根据文件名加载对应的类很容易,创建实例也很容易,困难的是如何在创建实例的同时传递初始参数进去?而且这个参数数量是不固定的! // 手动加载模型
function M($ClassName, $init = false) {
if (!class_exists($ClassName, false)) {
$dir = MODULE_DIR ? MODULE_DIR . '/' : '';
if (file_exists($f = JXCMS_ROOT . $dir . "Model/{$ClassName}.class.php")) include($f);
else exit("Could not find class {$name}, searched in {$f}");
}
if ($init) {
return new $name();
}
}我想做下改进,这个M函数后面还可以放不固定的参数,作为新建实例的参数,但是我没办法作为正常的参数传递进去,获取对应的参数的数组是有办法的,PHP有这样的函数。

解决方案 »

  1.   

    http://www.php.net/manual/en/reflectionclass.newinstanceargs.php
      

  2.   

    例class A{
      function __construct($a, $b) {
        $this->x1 = $a;
        $this->x2 = $b;
      }
    }
    $ref = new ReflectionClass('A');
    $p = $ref->newInstanceArgs(array( 1,2));
    print_r($p);A Object
    (
        [x1] => 1
        [x2] => 2
    )问题在于你如何根据不同的类,构造出相应的构造函数参数数组,而能保证不出错!实际上我们并不这样做,而是创建一个 context 类对象,他携带了所有可能在类间传递的原始数据和中间结果。
    换句话说就是:所有的类都只是与 context 进行交互 
      

  3.   


    // 手动加载模型
    function M($className, $init = false) {
    $className = substr($className, -5) == 'Model' ? $className : ucwords($className) . 'Model';
    if (!class_exists($className, false)) {
    $dir = MODULE_DIR ? MODULE_DIR . '/' : '';
    if (file_exists($f = JXCMS_ROOT . $dir . "Model/{$className}.class.php")) include($f);
    else exit("Could not find class {$className}, searched in {$f}");
    }
    if ($init) {
    if (func_num_args() < 3)
    return new $className();
    else { //下面方法要求 PHP 5 >= 5.1.3
    $args = func_get_args();
    array_shift($args);
    array_shift($args);
    $ref = new ReflectionClass($className);
    return $ref -> newInstanceArgs($args);
    }
    }
    }
    这是我改进后的结果,谢谢楼上两位。实际上我们并不这样做,而是创建一个 context 类对象,他携带了所有可能在类间传递的原始数据和中间结果。
    换句话说就是:所有的类都只是与 context 进行交互我不明白的是为什么要增加一个 context 类对象进行交互,如果只是为了传递数据的话,可以在类实例化后进行参数设置,用魔术方法是可以做到的。
      

  4.   

    ReflectionClass 唯一的缺点应该是对PHP版本有>= 5.1.3 的要求,而应该不可能会出错,$args = func_get_args();array_shift($args);array_shift($args);得到的参数就是实际需要传递的参数了!
      

  5.   

    $p = M($className, ....);
    当 $className 也是动态产生的时候,你如何确定参数?
      

  6.   

    我的框架的做法是大部分的类是用魔术方法自动加载的,只有模型类才有可能手动加载,很多不需要初始化的类,都写成作用域方式访问,这样不用生成实例,到目前为止还没有发现 $p = M($className, ....);这种类名也动态生成的需求.
      

  7.   

    要是直接有 $className 也是动态生成的需求时,我想只能不传递参数了,而是到后来用魔术方法设置参数了.
      

  8.   

    同求结果。。http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
      

  9.   

    <a href="http://www.php.net/manual/en/reflectionclass.newinstanceargs.php">http://www.php.net/manual/en/reflectionclass.newinstanceargs.php</a>
      

  10.   

    <a href="http://www.php.net/manual/en/reflectionclass.newinstanceargs.php">http://www.php.net/manual/en/reflectionclass.newinstanceargs.php</a>