views:

51

answers:

6

Hi, would it be considered bad practice to return different types from the same method in php. Maybe there is a best pattern for this but essentially i want my method to do something and if it fails return a string error message but if it works then return true. This doesnt seem quite right to me but the only other way i can see to make this work would be to return a string for the error message and a string with something like 'worked' or 'valid' or something if all goes ok. Again this means there is more coupling beetween methods that use this as they cant just check true of false but the have to know the word that will be representing a valid response from the method.

A: 

Well, you could return an array, I suppose - the first index would contain your boolean true/false, and the second index would contain more information if necessary.

hollsk
i had though about that also but again the calling method needs to which index to look at for what etc so they still become more coupled
David
+2  A: 

If you are trying to monitor whether a function worked, you are best served by making use of Exceptions. As in all programming languages that provide them, these are indicative of "exceptional" cases outside the confines of expected program flow, and do not require any type of return to indicate something went wrong. See the associated documentation linked below for the PHP specifics.

PHP Exceptions

apiri
This does make the assumption you are using PHP5, as 5 was the first version to introduce the idea of Exceptions to PHP. Workarounds in PHP4 to make up for this utilized the trigger_error function http://www.php.net/manual/en/function.trigger-error.php
apiri
yes but i am wanting to split my code up in seperate funcions. so for example the method i am talking about would be used for validating a string say. if the string has an error i want to return what the error is but true if its ok.
David
Then subclassing the PHP base Exception to have your own StringValidationException class is possible. Your method could then take a String and perform validation on it, returning true if valid, throwing the exception if it is not with a field in it.Another option that might be, closer to your original intent, is to have an isInvalid method that just returns a string explaining the error or an empty string "" as this evaluates to false.Sample usage would be isInvalid($myString), returning true if it is invalid with your specified message, or "" which equates to false as defined by PHP.
apiri
+1  A: 

Assuming that you are referring to a method in a class, it would be better to simply return a TRUE or FALSE from the method but use an $_error property in the class that can contain an array of error messages.

Then if the result is false, before returning the method can set the error message(s) in the $_error property and you can retrieve the message using a get_error() method.

Noah Goodrich
+1 This is how most OOP libraries and frameworks shipped with PHP do it and the best way IMO. Alternatively, some libraries have functions like `mysql_error()` or `curl_error()` that return the error raised in the last operation. But if you're working with objects, and can't/don't want to use exceptions, go with the `error` property.
Pekka
Yes i was referring to oop. Would you suggest having an actuall error object. I am relatively new to programming but i was convinced there would be some sort of standard design pattern used for this type of problem
David
My general advice is to "Keep It Simple" otherwise referred to as the KISS principle. If you want to track multiple errors use an array to begin with, if its a single error then store it as a string. If you identify additional properties or behaviors of an error message then begin worrying about using an actual object.I highly suggest only using objects once you've identified an inherent need to do so. Otherwise use native types and their functions.
Noah Goodrich
A: 

You can certainly get away with it in PHP, but it might cause problems down the road. Esp when you or someone else has to maintain the app in the future. In general I'd recommend avoiding any approach like this that creates an ambiguity about whats in the variable.

One way to achieve what you are doing is to have the function return a result code or message, and have the actual value that gets returned sent back using referenced parameters.

ex:

   $msg = MyFunc( $o);
    if ($msg == 'OK')   //or ($msg == 0)
    {
        //use the returned object or value
        $o->Foo();
    }
    else
    {
        //respond to error
    }
GrandmasterB
A: 

Returning true or anything else may be a good solution. Sometimes. I't may break if you decide to change returned values. Personally, I like it.

You could return an array. If it's empty, there was no error. Every error would be a separate item in array.

Besides, you may try to throw exception.

ghaxx
A: 

PHP is a loosely typed language, so it's pretty ordinary in the culture of PHP to return dissimilar types from functions.

For example, mysql_query() returns a resource on success and a boolean false on error. You test for the error state and then call another function like mysql_error() to get the specific information about the nature of the error.

$query = mysql_query($sql);
if ($query === false) {
  die(mysql_error());
}

However, when writing OO code, I would be cautious about returning different unrelated object types from a function. It requires developers to write lots of tedious type-checking code:

$result = $search->find($keyword);

if ($result === null) {
  // no entry matches $id
} elseif ($result instanceof ResultClass) {
  // one row found; do something with the result
  print $result;
} elseif ($result instanceof ResultCollection) {
  foreach ($result as $element) {
    print $element;
  }
} else {
  // are there other types for $result?
}

What a pain to write all that code every time you call find()!

The above example would be better if the find() method always returned a ResultCollection. If no results are found, the collection would have zero entries. If you can assume the function returns a given type consistently, your code is simpler:

$result = $search->find($keyword);
foreach ($result as $element) {
  print $element;
}
Bill Karwin