views:

196

answers:

11

Hey Stackfolk,

I tried to ask this before, and messed up the question, so I'll try again. Is it possible to make an object return false by default when put in an if statement? What I want:

$dog = new DogObject();
if($dog)
{
   return "This is bad;"
}
else
{
   return "Excellent!  $dog was false!"
}

Is there a way this is possible? It's not completely necessary, but would save me some lines of code. thanks!

A: 

Putting something in "an if statement" is simply evaluating the variable there as a boolean.

In your example, $dog would need to be always false for that to work. There is no way to tell when your variable is about to be evaluated in a boolean expression.

What is your ultimate purpose here? What lines of code are you trying to save?

thedz
Well, technically there's falsy and truthy. For example if you put $string = "", and then do if($string), $string will be considered false. It is the same with the int 0. I was just wondering if there was a way to make DogObject falsy.
Ethan
Okay, I see what you're trying to do. I think someone mentioned this in your other thread, but what you're really looking to do is a try/catch. You try the insert, and then catch any exceptions thrown.
thedz
A: 

I'm not sure about the object itself. Possible. You could try something like, add a public property to the DogObject class and then have that set by default to false. Such as.

class DogObject
{
    var $isValid = false;

    public function IsValid()
    {
        return $isValid;
    }
}

And then when you would instantiate it, it would be false by default.

$dog = new DogObject();
if($dog->IsValid())
{
   return "This is bad;"
}
else
{
   return "Excellent!  $dog was false!"
}

Just a thought.

Yes, but the idea is that it would be more along the lines of:$dog = couldReturnDogObjectButCouldAlsoBeArray();if($dog)... etc.if $dog isn't necessarily a DogObject, and I called IsValid() on it, then my program would crash. However, if I could make DogObject false in an if statement, then I could return true when it's an array, and return false when it's a DogObject.
Ethan
A: 

If I understand what your asking, I think you want to do this:

if (!$dog){
     return "$dog was false";
}

The ! means not. SO you could read that, "If not dog, or if dog is NOT true"

micmoo
I'm sorry if this is not what you were looking for... if its not just leave a message, don't downvote me to much, I had trouble understanding your question... figured I'd give it a shot.
micmoo
A: 

Under what conditions do you want if($dog) to evaluate to false? You can't do what you've literally asked for, but perhaps the conditioned could be replaced by something that does what you want.

Draemon
A: 

How about using an Implicit Cast Operator like the following C# ?

like so:

    class DogObject
    {
        public static implicit operator bool(DogObject a)
        {
            return false;
        }
    }

Then you can go...

    var dog = new DogObject();

    if(!dog)
    {
        Console.WriteLine("dog was false");
    }
Dog Ears
doesn't work in PHP, but thanks!
Ethan
I was too hasty to answer this without reading the question/tags! My apologies.
Dog Ears
+1  A: 

No, PHP has no support for operator overloading. Maybe they'll add it in a future version.

Jon Benedicto
Okay, that's all I needed! Thanks!
Ethan
A: 
class UserController
{
  public function newuserAction()
  {
    $userModel = new UserModel();
    if ($userModel->insertUser()) {
      // Success!
    } else {
      die($userModel->getError());
    }
  }
}

Or

class UserController
{
  public function newuserAction()
  {
    $userModel = new UserModel();
    try {
      $userModel->insertUser()
    }
    catch (Exception $e) {
      die($e);
    }
  }
}

There are a million ways to handle errors. It all depends on the complexity of the error and the amount of recovery options.

Mike B
+2  A: 

Use the instanceof keyword.

For example

$result = Users->insertNewUser();

if($result instanceof MyErrorClass){
  (CHECK WHAT WENT WRONG AND SAY WHY)
} else {
  //Go on about our business because everything worked.
}

Info is here.

Chris Lively
Hey, thanks. I'll do that.
Ethan
+1  A: 

Use this? Not a real neat solution, but does what you want:

<?php

    class Foo
    {
     private $valid = false;

     public function Bar ( )
     {
      // Do stuff
     }

     public function __toString ( )
     {
      return ( $this -> valid ) ? '1' : '0';
     }
    }

?>

Zero is considered false, one is considered true by PHP

Stefan
+1  A: 

I was attempting to do this myself and found a solution that appears to work.

In response to the others who were trying to answer the question by telling the asker to use a different solution, I will also try to explain the reason for the question. Neither the original poster or I want to use an exception, because the point is not to use exception handling features and put that burden on any code we use this class in. The point, at least for me, was to be able to use this class seamlessly in other PHP code that may be written in a non-object-oriented or non-exception-based style. Many built-in PHP functions are written in such a way that a result of false for unsuccessful processes is desirable. At the same time, we might want to be able to handle this object in a special way in our own code.

For example, we might want to do something like:

if ( !($goodObject = ObjectFactory::getObject($objectType)) ) {
  // if $objectType was not something ObjectFactory could handle, it
  // might return a Special Case object such as FalseObject below
  // (see Patterns of Enterprise Application Architecture)
  // in order to indicate something went wrong.
  // (Because it is easy to do it this way.)
  //
  // FalseObject could have methods for displaying error information.
}

Here's a very simple implementation.

class FalseObject {
  public function __toString() {
    // return an empty string that in PHP evaluates to false
    return '';
  }
}

$false = new FalseObject();

if ( $false ) {
  print $false . ' is false.';
} else {
  print $false . ' is true.';
}

print '<br />';

if ( !$false ) {
  print $false . ' is really true.';
} else {
  print $false . ' is really false.';
}

// I am printing $false just to make sure nothing unexpected is happening.

The output is:

is false. is really false.

I've tested this and it works even if you have some declared variables inside the class, such as:

class FalseObject {
  const flag = true;
  public $message = 'a message';
  public function __toString() {
    return '';
  }
}


A slightly more interesting implementation might be:

class FalseException extends Exception {
  final public function __toString() {
    return '';
  }
}

class CustomException extends FalseException { }

$false = new CustomException('Something went wrong.');

Using the same test code as before, $false evaluates to false.

Doug Treadwell
finally, someone who understands! I actually just ended up using instanceof, which wasn't that much extra, so it wasn't that bad. Thanks for the help though.
Ethan
A: 

I recently had to do something similar, using the null object pattern. Unfortunately, the null object was returning true and the variable in question was sometimes an actual null value (from the function's default parameter). The best way I came up with was if((string)$var) { although this wouldn't work for empty arrays.

Gnuffo1