PHP'deki bir değişkenden bir sınıf örneği oluşturulsun mu?


150

Bu sorunun oldukça belirsiz geldiğini biliyorum, bu yüzden bir örnekle daha net hale getireceğim:

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

Yapmak istediğim bu. Nasıl yapardın? Tabii ki eval () 'u şu şekilde kullanabilirim:

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

Ama eval () 'dan uzak durmayı tercih ederim. Eval () olmadan bunu yapmanın bir yolu var mı?

Yanıtlar:


218

Önce sınıf adını bir değişkene koyun:

$classname=$var.'Class';

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

Bu genellikle bir Fabrika modeline sarılmış olarak göreceğiniz türden bir şeydir.

Daha fazla ayrıntı için Ad alanları ve dinamik dil özelliklerine bakın.


2
Ben böyle yaparım. Sınıfların içinden ebeveyn ve kendini kullanabileceğinizi unutmayın.
Ross

1
Benzer bir notta, $ var = 'Name'; $ obj -> {'get'. $ var} ();
Mario

1
İyi nokta, ancak bu yalnızca yöntem çağrıları için işe yarıyor, kurucular için değil
Paul Dixon

12
$var = __NAMESPACE__ . '\\' . $var . 'Class';
Ad alanıyla çalışıyorsanız

@bastey - ama neden? Sınıf adının önündeki ad alanı olmadan bunun neden işe yaramayacağını anlamak için çok zaman harcadım ...
jkulak

75

Ad Alanları Kullanıyorsanız

Kendi bulgularımda, (söyleyebildiğim kadarıyla) bir sınıfın tam ad alanı yolunu bildirmeniz gerektiğini söylemenin iyi olacağını düşünüyorum.

Sınıfım.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
Ad alanıyla yaratmanız gerektiğinde çalışan tek çözüm sizindir. Paylaşım için teşekkürler!
Tiago Gouvêa

Ama bu çok garip, neden beyan edilen ad alanını kullanmasın?
Yisrael Dov

@YisraelDov Evet kesinlikle karşı sezgiseldir. Ancak her ne sebeple olursa olsun bu bağlamda tuhaf davranıyor. Teşekkürler php
csga5000

@YisraelDov Sanırım bunun nedeni, bu durumda başka bir isim alanından bir sınıfın somutlaştırılması büyük bir baş ağrısı olacaktır. Ayrıca değişkenlerin aktarılabileceğini de göz önünde bulundurun. Sınıf adı bir php dosyasına metin olarak yazıldığında, onu yazan kişi tam olarak hangi ad alanına yazıldığını bilir. Ancak işlevler arasında bir değişken geçirildiğinde, onu takip etmek bir kabus olur. Ayrıca get_class () kullanırsanız, FQ sınıf adını geri verir, böylece hemen bir değişkende saklanabilir ve her yerde kullanılabilir. Dosyanın ad alanına bağlı olsaydı, pek iyi çalışmazdı.
sbnc.eu

61

Dinamik yapıcı parametreleri de nasıl iletilir

Sınıfa dinamik yapıcı parametreleri geçirmek istiyorsanız, bu kodu kullanabilirsiniz:

$reflectionClass = new ReflectionClass($className);

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

Dinamik sınıflar ve parametreler hakkında daha fazla bilgi

PHP> = 5.6

PHP 5.6'dan itibaren, Argument Unpacking'i kullanarak bunu daha da basitleştirebilirsiniz :

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

Buna işaret ettiği için DisgruntledGoat'a teşekkürler.


7
PHP 5.6'dan itibaren, aşağıdaki bağımsız değişkenleri açabilmeniz gerekir:new $className(...$params)
DisgruntledGoat

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

$var = 'Test';

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

Hayır, iyi bir örnek değil. Yalnızca her şey aynı php dosyasındaysa çalışır.
fralbo

2
2ndGAB bu yorumu kaldırmalıdır. Otomatik yüklemenin bu soruyla hiçbir ilgisi yoktur.
Jim Maguire

-1

call_user_func()Veya call_user_func_arrayphp yöntemlerini tavsiye ederim . Bunları buradan kontrol edebilirsiniz ( call_user_func_array , call_user_func ).

misal

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

Yönteme ilettiğiniz bağımsız değişkenleriniz varsa, call_user_func_array() işlevi .

misal.

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
Bu cevap soru için geçerli değil. OP, değişken bir dizeden bir sınıfın nasıl ANINDA OLUŞTURULACAĞINI soruyor (sınıf __construct yöntemini dinamik olarak tetikliyor) ve SINIF NESNESİNİ yeni bir değişkende geri alıyor - tavsiyeniz, sınıf-> yönteminin ([]) DEĞERİNİ döndürecektir. sınıf nesnesi değil, yeniden çağırır, bu nedenle bu durum için geçerli değildir. Dönüş değerine bakın php.net/manual/en/function.call-user-func-array.php
ChrisN
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.