0

以下代码之前工作,但现在它抛出错误构造函数调用类 xyz 失败,我添加了有助于理解问题的代码。

代码:

public static function & Instance( $class )

 {

  static $loaded = array();

  if ( !( isset( $loaded[ $class ] ) ) ) {

   $c = SPLoader::loadClass( $class, false, null, false );

   if ( !( strlen( $c ) ) ) {

    $c = SPLoader::loadClass( $class, defined( 'SOBIPRO_ADM' ) );

   }

   if ( !( strlen( $c ) ) ) {

    throw new SPException( SPLang::e( 'Cannot create instance of "%s". Class file does not exist', $class ) );

   }

   $loaded[ $class ] = $c;

  }

  $args = func_get_args();

  unset( $args[ 0 ] );

  try {

   $obj = new ReflectionClass( $loaded[ $class ] );

   $instance = $obj->newInstanceArgs( $args );

  } catch ( LogicException $Exception ) {

   throw new SPException( SPLang::e( 'Cannot create instance of "%s". Class file does not exist. Error %s', $class, $Exception->getMessage() ) );

  } catch ( ReflectionException $Exception ) {

   throw new SPException( SPLang::e( 'Cannot create instance of "%s". Class file does not exist. Error %s', $class, $Exception->getMessage() ) );

  }

  return $instance;

 }

构造函数类:

class SPImexExportDownload

{

    /**

     * @var SPImexCtrl

     */

    protected $proxy = null;



    public function __construct( SPImexCtrl &$proxy )

    {

        $this->proxy =& $proxy;

    }



    public function data( $field )

    {

        $data = $field->getRaw();

        $out = array();

        try {

            $data = SPConfig::unserialize( $data );

            if ( count( $data ) ) {

                // "{'label':'Nothing Special','protocol':'http','url':'radek.suski.eu'}"

                if ( isset( $data[ 'label' ] ) && $data[ 'label' ] ) {

                    $out[ ] = $data[ 'label' ];

                }

                $out[ ] = $data[ 'protocol' ] . '://' . $data[ 'url' ];

            }

        }

        catch ( SPException $x ) {

            $this->proxy->log( $field->get( 'nid' ) . ": " . $x->getMessage(), 'error' );

            $data = null;

        }

        return $out;

    }

}

我的 PHP 版本:5.6

4

1 回答 1

0

反射创建类的一个实例并始终按值传递参数,您遇到的错误是因为您要求构造函数获取指向参数的指针,但它只是被传递了一个值。

您可以传递包含如下引用的参数:

function invokeWithReference(StdClass &$class)
{
    // Create args array using reference
    $args = [&$class];
    $obj = new ReflectionClass('xyz');
    return $obj->newInstanceArgs($args);
}

您必须从类中的构造函数中删除引用,但将其作为引用参数传递将允许您在类内部和外部操作引用:

class xyz
{
    public $class;

    public function __construct(StdClass $class)
    {
        // May as well remove the reference here since it'll only be 
        // a reference to the value passed
        $this->class = $class;
    }

    public function setTest2()
    {
        $this->class->test2 = 'goodbye';
    }
}

$class = new StdClass;
$instance = invokeWithReference($class);

$class->test = 'hello';
$instance->setTest2();

echo $instance->class->test; // Echos 'hello'
echo PHP_EOL;
echo $class->test2; // Echos 'goodbye'

此处示例:http: //ideone.com/BNP5Oy

但是,这不应该起作用,因为参数总是要作为值而不是引用传递,实际上将引用全部删除仍然允许此代码工作:

// Still works
function invokeWithReference(StdClass $class)
{
    // Create args array using reference
    $args = [$class];
    $obj = new ReflectionClass('xyz');
    return $obj->newInstanceArgs($args);
}

// Also still works
function invokeWithReference()
{
    $args = func_get_args();
    $obj = new ReflectionClass('xyz');
    return $obj->newInstanceArgs($args);
}

这使我相信实施已被破坏,并且将来可能会修复,这可能会导致其停止工作。

示例:http: //ideone.com/TkihRs

于 2017-06-15T06:32:41.043 回答