2017-06-15 6 views
0

次のコードは以前は動作していましたが、今はxyzクラスのエラーコンストラクタ呼び出しが失敗しました。問題を理解するのに役立つコードを追加しました。phpのReflectionClassを使用してCunstructorの呼び出しに失敗しました

コード:

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

答えて

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

ホークラスの内側と外側からwever、このは、引数として仕事は常に値ではなく参照として渡されることを意図されているべきではない、実際に参照を削除し、すべて一緒に、まだこのコードが動作することができ:

// 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

+0

感謝。私はコンストラクタクラスと他のファイルのコードを追加しました、レビューしてください、私に教えてください、コンストラクタargsのrefは問題ですか? – Amit

関連する問題