tags:

views:

57

answers:

3

I have defined an abstract class and a method which is supposed to return the name of a template file. The user subclasses this abstract class and implements that method to return the template file name. But the problem is, that there happens no warning or whatever if the user just does not return anything.

How could I make this sure? The code that calls this method belongs to the framework, so I could do some fancy stuff with settype($returnVal, 'string') maybe, if that helps? Are there better solutions?

+4  A: 

In PHP, you cannot "force" a method to return anything -- and it's not possible, even with abstract classes/methods, nor interfaces.

The best you can do is indicate that the implementation should return something, using a comment -- but you cannot force people to do so :

/**
 * @param string $a blah blah
 * @return int The return value blah blah
 */
public function my_method($a);

Of course, if you are calling this method (the implementation) from your framework, you can check what has been returned, and throw an Exception if it doesn't correspond to what you expected...


And here is a quick example of how this could be implemented :

class ClassA {
    /**
     * @param string $a blah blah
     * @return ClassB The return value blah blah
     */
    public function my_method($a) {
        echo 'blah';
    }
}

class ClassB {
    // ...
}


$a = new ClassA();
$returned = $a->my_method(10);
if (!$returned instanceof ClassB) {
    throw new Exception("Should have returned an instance of ClassB !");
}

Here, as the method doesn't return an instance of ClassB, the exception will be thrown.

Pascal MARTIN
well but it would be possible to check the return value, right?
openfrog
@openfrog : yes, of course -- but you'll have to code that yourself : it's not enforced by PHP (I edited my answer while you were posting your comment -- I'll edit again with an example)
Pascal MARTIN
That's great. Thanks!! You practically answered two of my questions at once :-)
openfrog
@openfrog : Yeah, when I saw your question about detecting if an object is an instance of a class, I thought "hey, I just used the instanceof operator in another answer" ^^
Pascal MARTIN
+1  A: 

As far as I know, there is no way to achieve type hinting for return values in PHP. Since PHP 5, there is limited hinting for function parameters.

But even if there were, what you are trying to do is not a job for type hinting. What happens if the string I return is empty? You will need to check for the return value wherever the method is called, and react appropriately.

Pekka
+1  A: 

The only way I can think to do this is create a public final method in the parent class that the calling code will use, and a protected method which will be called by the public final method. The protected method contains the functionality, and the public final method validates the return value of the protected method.

class A {

    public final call_this($param) {

     $return_value = $this->extend_this($param);

     // validate $return_value
     if( $return_value == '' )
      throw new Exception("uh-oh! Don't return an empty string!");

     return $return_value;

    }

    protected extend_this($param) {

     // default behavior

     return $whatever;

    }

}

class B extends A {

    protected extend_this($param) {

     // new behavior

     return ''; //whoops!

    }

}

$b = new B;
$b->call_this("testing testing 123");
//exception!

This can be a little confusing for the person extending the class though, if you try something like this, make sure it is well documented.

public final is a public method that cannot be overridden, in case you didn't know. Also note that this will only work in PHP 5.0.0 or better.

Carson Myers