MySQLi and exceptions

Hey,

I’ve created a class with mysqli methods. I’m using exceptions as my error handling. If I do this though:


class mysql
{
  private $host;
  private $username;
  private $password;
  private $dbname;
  private $link;

  public function __construct($host = '', $username = '', $password = '', $dbname = '')
  {
    $this->host = $host;
    $this->username = $username;
    $this->password = $password;
    $this->connect();
  }

  public function connect()
  {
    $this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname);
    if (!$this->link)
      Throw New Exception(mysqli_error());
    return $this->link;
  }
}

I would expect for this to throw an exception if the connection was not made, but its not. This is what I’m doing in the index:


try
{
  $mysqli = new mysql('localhost', 'root', '', 'cms222');
  echo 'connected';
}
catch (Exception $e)
{
  echo $e->getMessage();
}

The correct database name is ‘cms’ but I added the extra digits to make it fail. But it doesn’t, it still prints “connected”.

  public function connect()
  if (!$this->link)

This will always evaluate to TRUE because $this->link is a MySQLi object you have just created. What you need to do is check its connection_error property:

(As a side note: always use curly brackets with if constructs. It’s just good practice.)


  public function connect()
  {
    $this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname);

    if ($this->link->connect_error) {
      throw New Exception(mysqli_error());
    }

    return $this->link;
  }

I tried what you said and it’s working but its also displaying an error:

Warning: mysqli_error() expects exactly 1 parameter, 0 given in C:\Users\9three\Desktop\Server\htdocs\library\mysqli.package.php on line 23

I’m assuming it’s because im not suppressing the error messages from within the class (eg. @) ?

BTW, is there an exception list I can view online? The only one I know is catch (Exception $e). I’m assuming (I’m a java developer) that you have more than one exception available through PHP?

P.S. I don’t use curly bracers because it’s only one line. I use curly bracers for more than one line.

It merely good practice to use braces for control structures, I think that is what Paul was hinting at.

I’m also sure you meant to say thanks too.

:wink:

Never use error suppression. You should handle errors, not suppress them.

You should use $this->link->connect_error instead of mysqli_error().

Exception is the only native exception class. You can, however, extend it and build your own.

Yes, I know. It’s bad practice. First of all the code is more readable with braces even if there’s only one line. Also, you won’t have to worry that you forget to add braces if you want to add another line in the future. Always use braces.

Got it, it’s working now. I forgot to change the exception to mysqli_connect_error().

I didn’t mean any disrespect about the curly bracers.

As always,

Thanks for the help

You shouldn’t use procedural access to MySQLi (it’s deprecated). Use OO manner instead: MySQLi->connect_error (so in your code that would be $this->link->connect_error).

thanks for the advice, good stuff.

BTW, is there an exception list I can view online? The only one I know is catch (Exception $e). I’m assuming (I’m a java developer) that you have more than one exception available through PHP?

eg. in java you have all kinds of different exceptions:

Exception e
FileNotFoundException e
etc

As far as I’m aware, most native PHP objects throw a generic Exception. Although there is nothing stopping you catching the original exception and throw an extending exception which is a bit more descriptive.

Exceptions in PHP are relatively new, and therefore appear quite lacking compared to other more mature OOP languages.

Look above (post #5). I answered it there.

thanks

sorry deco i didn’t see that part of your post.

Hey,

I’m having an issue. It’s always returning “connected” whether the data base name is correct or not.


  public function connect()
  {
    $this->link = new mysqli($this->host, $this->username, $this->password, $this->dbname);
    if ($this->link->connect_error) { // Error returned true
      Throw New Exception($this->link->connect_error);
    }
    return $this->link; //No exception was thrown, return $this->link
  }

This is the index:


try {
  $mysqli = new mysql('localhost', 'root', '', 'cms2');
  echo 'Connected';
}
catch (Exception $e) {
  echo $e;
}

the database name is actually ‘cms’ not ‘cms2’. But either way it prints “connected”

If I do !$this->link->connect_error it returns an exception


exception 'Exception' in C:\\Users\\9three\\Desktop\\Server\\htdocs\\library\\mysqli.package.php:23 Stack trace: #0 C:\\Users\\9three\\Desktop\\Server\\htdocs\\library\\mysqli.package.php(16): mysql->connect() #1 C:\\Users\\9three\\Desktop\\Server\\htdocs\\library\\index.php(12): mysql->__construct('localhost', 'root', '', 'cms2') #2 {main} 

Again, whether I use ‘cms’ or ‘cms2’ it still throws this exception. Now I don’t know why, the syntax looks correct in the class.

Anyone ? :slight_smile:

Try mysqli_connect_error() instead. Apparently MySQLi->connect_error was broken until PHP 5.2.9.

If I use $this->link->mysqli_connnect_error() I can an error of undefined method.

If I do $this->link->connect_error and I change the exception to mysqli_connect_error() I’m back to the same thing :frowning:

This appears to work just fine…

<?php
class OurDatabase
{
    protected $oConnection = null;
    
    public function __construct()
    {
        $this->oConnection = @new mysqli('127.0.0.1', 'root', '', 'mysql');
        if(mysqli_connect_errno() > 0)
        {
            throw new Exception(sprintf('Cannot connect to database: &#37;s', mysqli_connect_error()));
        }
    }
}

try
{
    $oDB = new OurDatabase();
}
catch(Exception $oException)
{
    echo $oException->getMessage();    
}
?>

Ah you’re using mysqli_connect_errno which returns a int. good thinking.

So the preferred way is using $mysqli->connect_error ? But it’s not working right as of 5.2.9?

thanks

It’s not working for me using 5.2.6, so quite possibly. :slight_smile:

ah cool thanks everyone