David Bélanger
David Bélanger

Reputation: 7438

PHP Initialize class with a var is ok but with a constant it fail. Why?

I am currently building a MVC and I ran into a little problem (I got the solution already), but :

This fail because Fatal error: Call to undefined method Controller_Home::DMVC_DEF_CTRL_FUNCTION() ..

if(method_exists($Controller, DMVC_DEF_CTRL_FUNCTION)){
    $Controller->DMVC_DEF_CTRL_FUNCTION($SecondRoute);
} else {
    // 404
    die;
}

This work :

$MethodName = DMVC_DEF_CTRL_FUNCTION;
if(method_exists($Controller, $MethodName)){
    $Controller->$MethodName($SecondRoute);
} else {
    // 404
    die;
}

DMVC_DEF_CTRL_FUNCTION is a constant.

Can someone explain this to me why a constant wouldn't work ? I also tryed for fun with the constant function but no success.

I think PHP think it is a function. How can I tell PHP that the constant DMVC_DEF_CTRL_FUNCTION ain't a function ?

Thanks

Upvotes: 0

Views: 74

Answers (5)

None
None

Reputation: 5649

PHP doesn't know that you aren't calling a function DMVC_DEF_CTRL_FUNCTION as in

function DMVC_DEF_CTRL_FUNCTION()
{
    // some function
}

Crashspeeder is right. You can use call_user_func, but why not just tell PHP to replace the constant before it tries to call the function:

$Controller->{DMVC_DEF_CTRL_FUNCTION}($SecondRoute);

Add brackets around the constant.

Upvotes: 0

j4kes
j4kes

Reputation: 374

In your current code the interpreter believes that you are calling a method on the object with the name DMVC_DEF_CTRL_FUNCTION. Since DMVC_DEF_CTRL_FUNCTION is a constant and not a varaible, php is taking the name instead of the actual value it is holding.

You can force php to take the value instead in the following way:

 $controller->{DMVC_DEF_CTRL_FUNCTION}( "Blah" );

Update

When using a class constant instead of a global constants, the following will work as well:

 $controller->{self::DMVC_DEF_CTRL_FUNCTION}( "Blah" );

Upvotes: 2

mario
mario

Reputation: 145512

If you want to use a constants value as method name, you could utilize the curly expression syntax:

 $Controller->{CONSTANT_NAME}($SecondRoute);

As otherwise the identifier would only ever be interpreted as method name.

Upvotes: 2

Marc B
Marc B

Reputation: 360872

For this line:

if(method_exists($Controller, DMVC_DEF_CTRL_FUNCTION)){

have you done a define('DMVC_DEF_CTRL_FUNCTION', 'some value') previously? If not, you're checking for an undefined constant, which will effectly become

if (method_exists($Controller, NULL)){

method_exists() requires you pass in the name of the method as a STRING. Since you've not quoted the DMVC... part, it's going in as a constant, which means it must have been defined previously.

edit:

$x = 'hello';
define('x', 'goodbye');

$obj->x();  // this is NOT going to call hello() **OR** goodbye()

Upvotes: 0

Crashspeeder
Crashspeeder

Reputation: 4311

PHP knows that a variable holds data, that's the purpose of a variable. This is why you can use variable variables and execute a function like you're trying to do, by evaluating the variable How would it know that you meant to use this as a constant instead of just the actual name of the function?

You could use the following to execute the same purpose:

if(method_exists($Controller, DMVC_DEF_CTRL_FUNCTION)){
    call_user_func(array($Controller, DMVC_DEF_CTRL_FUNCTION),$SecondRoute);
} else {
    // 404
    die;
}

Upvotes: 1

Related Questions