2017-06-15 28 views
0

以下代碼工作較早,但現在它的投擲錯誤構造函數調用類xyz失敗,我已經添加了有助於理解問題的代碼。Cunstructor調用失敗使用ReflectionClass在php

代碼:

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

感謝您的回覆。我添加了更多的構造函數類和其他文件的代碼,請檢查並讓我知道,參考構造函數參數是一個問題? – Amit