Autor Zpráva
llook
Profil
Je nějak možné staticky (::) volat metodu třídy, jejíž název mám uložený v proměnné?
Něco podobného tomuhle:
class MyClass {

function hello() {
echo('hello');
}
}
$className = 'MyClass';
$className::hello(); // tohle nefunguje! error!

Zkoušel jsem všechno možný včetně call_user_func, ale na nic jsem nepřišel. Abych tu třídu vůbec, ani jednou, nemusel instantovat.
Nakonec jsem to vyřešil jinak (podle zásady "když něco nejde, něco jinýho jde"), ale i tak by mě to zajímalo.
Leo
Profil
Asi tomu nerozumim, ale instanci tvorit nemusite, da se prece primo volat

MyClass::hello();

Leo
llook
Profil
To jo, v případě, kdy už při psaní skriptu vím název třídy, jako v tom příkladu.
Ale co když mám více tříd a se všema chci provést to samý, třeba tohle:

$classes = array('JednaTrida', 'DruhaTrida', 'TretiTrida');

foreach ($classes as $class) {
if ($class::test()) {
$class::display();
}
}

Tak je jedinou možností buďto místo foreach otrocky napsat tři ify, nebo vytvořit si od každý třídy objekt:

foreach($classes as $class) {
$object = new $class;
if ($object->test()) {
$object->display();
}
}

A tomu vytváření objektu jsem se právě chtěl vyhnout.
Leo
Profil
"se všema chci provést to samý,..."

A neresi se takovy veci dedicnosti? Leo
llook
Profil
Špatně jsem se vyjádřil. Ne provést to samý, ale zavolat metodu stejného názvu. JednaTrida::test() dělá něco jiného než DruhaTrida::test(), prostě to implementuje stejný rozhraní.

Jasně že se to dá vždycky nějak obejít, jen mě zajímalo, jestli lze proměnnou obsahující název třídy využít i jinde než při vytváření objektu. A asi nelze.
Leo
Profil
Netusim. A ani netusim, k cemu by to mohlo byt v praxi dobry, Leo
...
Profil *
Kdyz nejde

<?
class MyClass {
function hello() {
echo('hello');
}
}
$className = 'MyClass';
$className::hello();
?>

tak bych to holt asi udelal pres

<?
class MyClass {
function hello() {
echo('hello');
}
}
$className = 'MyClass';
$class = new $className;
$class->hello();
?>
bukaj
Profil
Vím, že je to dosti staré téma. Ale kdyby se to někomu hodilo:

Řešením je fce call_user_func(), popř. její setra call_user_func_array().
Jako první parametr obě fce přijímají callback, což je v podstatě string obsahující název funkce nebo se pole, jehož první prvkem je název třídy nebo objekt, druhý prvek je název volané metody.

První funkce předá callbacku kromě prvního všechny své parametry. Druhá (tj. call_user_func_array) dostává jako druhý parametr pole, jehož prvky předá callbacku jako parametry.

Příklad:
class Trida
{

public static function tridni_fce_napis($text)
{
printf("Třídní (statická): %s\n", $text);
}

public function instancni_fce_napis($text)
{
printf("Instanční: %s\n", $text);
}

}

call_user_func(array('Trida', 'tridni_fce_napis'), 'Ahoj světe!'); //je jako kdybste napsali: "Trida::tridni_fce_napis('Ahoj světe!');"
$nazev_tridy = 'Trida';
call_user_func_array(array($nazev_tridy, 'tridni_fce_napis'), array('Ahoj světe!')); //opět zavolá to co předtím
$instance = new Trida;
call_user_func_array(array(&$instance, 'instancni_fce_napis'), 'Ahoj světe!'); //jako, kdybyste napsali: "$instance->instancni_fce_napis('Ahoj světe!');"

Příklad vypíše:
Třídní (statická): Ahoj světe!
Třídní (statická): Ahoj světe!
Instanční: Ahoj světe!
Toto téma je uzamčeno. Odpověď nelze zaslat.