tags:

views:

96

answers:

3

Hi Everyone,

I'm having some problems getting my object to gracefully fail out if an invalid parameter is given during instantiation. I have a feeling it's a small syntax thing somewhere that I simply need fresh eyes on. Any help is more than appreciated.

class bib {
   protected $bibid;
   public function __construct($new_bibid) {
      if(!$this->bibid = $this->validate_bibid($new_bibid)) {
       echo 'me';
     return false;
      }
      //carry on with other stuff if valid bibid
    }

    private static function validate_bibid($test_bibid) {
    //call this method every time you get a bibid from the user
    if(!is_int($test_bibid)) {
      return false;
    }
    return (int)$test_bibid;
    }
 }

Note that I have an 'echo me' line in there to demonstrate that it is in fact, returning false. The way that I'm calling this in my PHP is as follows:

if(!$bib=new bib('612e436')) {
    echo 'Error Message';
} else {
    //do what I intend to do with the object
}

This outputs the me from above, but then continues on into the else block, doing what I intend to do with a valid object.

Can anyone spot anything I'm doing wrong in there?

Thanks!

+1  A: 

You can't return in a constructor in PHP - the object is still created as normal.

You could use a factory or something similar;

if(!$bib = Bib_Factory::loadValidBib('612e436')){
    echo 'Error Message';
} else {
    //do what I intend to do with the object
}

Or throw an exception in the constructor and use a try catch instead of the if statement.

Simon
Would it be considered bad form to have a property called 'valid', and then just do something like:$bib = new bib('612e436');if($bib->isValid()) {//do stuff}
Cory Dee
I don't see a problem with it really, but personally if all the isValid method is doing is checking that the var passed to the constructor is an integer, then I'd perform the check in the constructor and throw an exception. But it's a matter of taste at the end of the day.
Simon
+2  A: 

I see several problems in this code.

  • First of all, I think you want to do something like this:

    $myBib=new bib(); if($myBib->validate_bibid('612e436')) { ..do stuff.. }

    (or something similar)

    remember that __construct is not a normal method. It's a constructor, and it shouldn't return anything. It already implicitly returns a reference to the new instance that you've made.

  • Second, your validate_bibid returns either a boolean or an integer. You won't get immediate problems with that, but I personally don't like the style.

  • Third, you've declared a protected member $bibid, but you don't set or reference it anywhere. I'd expect it to be set in the constructor for example. After that you can just call validate_bibid without any argument.

This piece of code is obviously confusing you because it has some weird constructs and therefore doesn't behave in a normal way. I'd suggest to rethink and rewrite this piece from scratch.

Update:

Another issue:

I don't think this line does what you think it does:

 if(!$this->bibid = $this->validate_bibid($new_bibid)) {

You probably mean this:

 if(!$this->bibid == $this->validate_bibid($new_bibid)) {

 // Or even better:

 if($this->bibid <> $this->validate_bibid($new_bibid)) {
Wouter van Nifterick
Thanks for the comment. The construct sets $bibid with the validated bibid that is returned, so it is used. Also, the construct does a lot of database access to get other properties of the bib, that is why I'm attempting to validate and instantiate all in one step. I'll definitely consider point 2.
Cory Dee
A: 

definitely, you need to have comparison with == instead of = which is an assign operation.

dusoft
I was assigning the returned, validated int to bibid. If it failed validation, it would return false, and not meet the if condition.
Cory Dee