I hate methods/functions returning multiple types

Basically the title.

i always see these functions like

function f1 ( $a1, $a2, $a3 ) {

if ( $a1 ) {
return false;

if ( $a2 ) {
return 'some string';

return array('some data');


When the code returns multiple types from a single function it automatically becomes code smell.

Because whenever i want to use this function f1, i would need check the type it returned.

$result = f1( $a1, $a2, $a3 );

if ( is_array($result ) ) {
// do thing 1
elseif ( is_string($result) ) {
// do thing 2
else {
// do thing 3

just to use this function i would need 6 lines of code. 6 lines of code everywhere where i need to use the function. As a developer i would hate to use this function anywhere, because everywhere i would need to handle 3 flows.

But i get your intention, what happens when the value doesn't match function expectation in run time. You can avoid this by either

  • Throwing exceptions

  • Creating objects to represent invalid states

Throwing exceptions

Throwing exceptions is usually helpful, because i could handle all the exceptions which arise in the block of code with the single try catch block.

function f1($a1, $a2, $a3 ) {
if ( ! $a1 || !$a2 ) {
throw new Exception('something terrible happened');
return array('some data');

Creating objects to represent invalid states

lets say you have a function which returns subscription by id and the interface for subscription looks like this.

interface Subscription {

function get_id();


and the function looks like this.

function get_subscription_by_id ( $id ) {
if ( ! $id ) {
throw new Exception("subscription id is not valid");

return Subscription_Factory::get($id);

I could create a object which represent invalid subscription and return it instead of throwing exception

class Invalid_Subscription implements Subscription {

function get_id() {
// do nothing.


now one might ask how to handle this state, i prefer to handle it inside a factory.

Lets say i get a subscription and i call an api. in that that logic would be inside the factory method

class Request_Factory {

// request class has execute() method which sends the request.

static function get($subscription) {

if ( ! $subscription instance of Valid_Subscription ) {
return Invalid_Request();

return Valid_Request();



now lets see how the usage would look like.

Request_Factory::get( Subscription_Factory::get(2) )->execute();

we have eliminated all the ifs, they are delegated to factories.

Let me know your thoughts on the comments.



Post a Comment