PHP의 변수에서 클래스를 인스턴스화합니까?


146

나는이 질문이 다소 모호하다는 것을 알고 있으므로 예제를 통해 더 명확하게 만들 것입니다.

$var = 'bar';
$bar = new {$var}Class('var for __construct()'); //$bar = new barClass('var for __construct()');

이것이 내가하고 싶은 일입니다. 어떻게 하시겠습니까? 물론 eval ()을 사용할 수 있습니다.

$var = 'bar';
eval('$bar = new '.$var.'Class(\'var for __construct()\');');

그러나 나는 오히려 eval ()에서 멀리 떨어져 있습니다. eval () 없이이 작업을 수행 할 수있는 방법이 있습니까?

답변:


214

클래스 이름을 변수에 먼저 넣으십시오.

$classname=$var.'Class';

$bar=new $classname("xyz");

이것은 종종 팩토리 패턴으로 싸인 종류의 것입니다.

자세한 내용은 네임 스페이스 및 동적 언어 기능 을 참조하십시오.


2
이것이 내가하는 방법입니다. 수업 내에서 부모와 자아를 사용할 수 있습니다.
Ross

1
비슷한 메모에서 $ var = 'Name'; $ obj-> { 'get'. $ var} ();
마리오

1
좋은 점은, 메소드 호출에만 작동하지만 생성자는 아닙니다.
Paul Dixon

12
네임 스페이스를 사용하는 경우 현재 네임 스페이스를 문자열에 넣습니다.$var = __NAMESPACE__ . '\\' . $var . 'Class';
bastey

@bastey-그러나 왜? 방금 알아내는 데 너무 많은 시간을 보냈습니다. 왜 클래스 이름 앞에 네임 스페이스가 없으면 작동하지
않을까요

72

네임 스페이스를 사용하는 경우

내 연구 결과에서, 내가 말할 수있는 한 클래스의 전체 네임 스페이스 경로를 선언해야한다고 언급하는 것이 좋습니다.

MyClass.php

namespace com\company\lib;
class MyClass {
}

index.php

namespace com\company\lib;

//Works fine
$i = new MyClass();

$cname = 'MyClass';

//Errors
//$i = new $cname;

//Works fine
$cname = "com\\company\\lib\\".$cname;
$i = new $cname;

6
네임 스페이스로 작성해야 할 때 유일하게 작동하는 솔루션은 귀하의 것입니다. 공유해 주셔서 감사합니다!
Tiago Gouvêa

그러나 이것은 이상합니다. 왜 선언 된 네임 스페이스를 사용하지 않습니까?
이스라엘 Dov

@YisraelDov 네, 확실히 직관적입니다. 그러나 어떤 이유로 든이 문맥에서 이상하게 행동합니다. 감사합니다 PHP
csga5000

@YisraelDov 나는이 경우 다른 네임 스페이스에서 클래스를 인스턴스화하는 것이 큰 두통이 될 것이라고 생각합니다. 또한 변수가 전달 될 수 있음을 고려하십시오. 클래스 이름이 PHP 파일에 텍스트로 쓰여질 때, 그것을 쓰는 사람은 그것이 작성된 네임 스페이스를 정확히 알고 있습니다. 그러나 변수가 함수 사이에 전달되면 후속 조치를 취하는 것은 악몽입니다. 또한 get_class ()를 사용하면 FQ 클래스 이름을 반환하므로 변수에 바로 저장하여 어디서나 사용할 수 있습니다. 파일의 네임 스페이스에 의존하면 잘 작동하지 않습니다.
sbnc.eu

61

동적 생성자 매개 변수도 전달하는 방법

동적 생성자 매개 변수를 클래스에 전달하려면 다음 코드를 사용할 수 있습니다.

$reflectionClass = new ReflectionClass($className);

$module = $reflectionClass->newInstanceArgs($arrayOfConstructorParameters);

동적 클래스 및 매개 변수에 대한 추가 정보

PHP> = 5.6

PHP 5.6부터 Argument Unpacking 을 사용하여 이것을 더욱 단순화 할 수 있습니다 .

// The "..." is part of the language and indicates an argument array to unpack.
$module = new $className(...$arrayOfConstructorParameters);

지적 해 주신 DisgruntledGoat에게 감사드립니다.


7
PHP 5.6부터 다음과 같이 인수 압축 풀기를 사용할 수 있습니다.new $className(...$params)
DisgruntledGoat

29
class Test {
    public function yo() {
        return 'yoes';
    }
}

$var = 'Test';

$obj = new $var();
echo $obj->yo(); //yoes

아니요, 좋은 예는 아닙니다. 모든 것이 동일한 PHP 파일에있는 경우에만 작동합니다.
fralbo

2
2ndGAB는이 설명을 제거해야합니다. 자동 로딩은이 질문과 관련이 없습니다.
Jim Maguire

-1

call_user_func()또는 call_user_func_arrayPHP 방법을 권장합니다 . 여기서 확인할 수 있습니다 ( call_user_func_array , call_user_func ).

class Foo {
static public function test() {
    print "Hello world!\n";
}
}

 call_user_func('Foo::test');//FOO is the class, test is the method both separated by ::
 //or
 call_user_func(array('Foo', 'test'));//alternatively you can pass the class and method as an array

메소드에 전달할 인수가 있으면 call_user_func_array()함수 를 사용하십시오 .

예.

class foo {
function bar($arg, $arg2) {
    echo __METHOD__, " got $arg and $arg2\n";
}
}

// Call the $foo->bar() method with 2 arguments
call_user_func_array(array("foo", "bar"), array("three", "four"));
//or
//FOO is the class, bar is the method both separated by ::
call_user_func_array("foo::bar"), array("three", "four"));

3
이 답변은 질문에 적용되지 않습니다. OP는 변수 문자열에서 클래스를 인스턴스화하는 방법 (클래스 __construct 메소드를 동적으로 트리거하는 방법)을 요청하고 클래스 변수를 새 변수로 다시 가져 오는 방법-조언은 클래스-> 메소드 ([])의 값을 반환합니다 클래스 객체가 아니라 다시 호출 하므로이 경우에는 적용되지 않습니다. 반환 값 php.net/manual/en/function.call-user-func-array.php
ChrisN
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.