[英]Cunstructor invocation failed using ReflectionClass in php
以下代碼之前工作正常,但是現在拋出類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
反射創建類的實例,並始終按值傳遞參數,您遇到的錯誤是因為您要讓構造函數獲取指向該參數的指針,但只將其傳遞一個值。
您可以傳遞包含如下引用的參數:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.