 |
Account Login
|
 |
 |
Latest Articles
|
 |
 |
IRC Channel
|
 |
 |
Associates
|
 |
 |
Associates
|
 |
|
 |
 |
|
 |
05-07-2008, 06:04 AM
|
#1 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Exceptions and suppressing mysqli errors
I'm just learning about exceptions and the Exception class, so I decided to give this a go;
PHP Code:
// in my construct
try {
$this->connectDB();
} catch (Exception $e) {
$e->getMessage();
die;
}
// the method
private function connectDB () {
$this->mysqli = @new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (!is_object($this->mysqli)) {
throw new Exception ("I'm sorry Dave, I'm afraid I can't do that.");
}
}
The problem is the @ doesn't seem to be suppressing the error from calling a new mysqli object...
|
|
|
|
05-07-2008, 09:59 AM
|
#2 (permalink)
|
|
The Frequenter
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
|
Don't use error suppression (@). It only slows your script. Instead, use error_reporting to show or hide the errors (error_reporting(0) in a live environment, error_reporting(E_ALL) when testing).
mysqli::__construct([...]) returns false if a connection couldn't be established, so there's no need for error suppression there (it doesn't generate a notice/error/warning). Instead, try:
PHP Code:
$this->mysqli = new mysqli(...); if($this->mysqli == false) { echo mysqli_connect_error(); }
__________________
I have optimistic thoughts, even though sometimes (if not always) life's a bitch.
|
|
|
|
05-07-2008, 10:37 AM
|
#3 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
Testing it just now, contrary to the manual the __construct method doesn't seem to return false on connect failure; it instead returns an object of type mysqli along with the warning
Code:
Warning: mysqli::mysqli() [function.mysqli-mysqli]: (28000/1045): Access denied for user 'user'@'localhost' (using password: YES)
therefore use mysqli_connect_errno()
PHP Code:
$mysqli = new mysqli('localhost', 'user', 'password', 'db');
if (mysqli_connect_errno()) { die('Connect failed: ' . mysqli_connect_error()); }
and xenon is correct error suppression can have a speed impact on your script, so use error_reporting(0); to hide all warnings/errors/notices etc etc and use your own error handling stuff (for example exceptions)
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-07-2008, 02:06 PM
|
#4 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Okay, you both seemed to miss the question, but thank you for trying. :)
I'm not worried about the speed impact of using @, because I'm learning about using the Exception class, and in particular the try {} catch {} and throw expressions. I'm also aware of mysqli_connect_error(), errno(), and die() the problem is I don't want to use those just yet. I want the throw new exception to handle the error, without turning off all error reporting on my test server.
@ isn't working anyways, it's not suppressing the error. Neither is error_reporting(0), it's still pumping out Connect failed: Unknown MySQL server host 'DB_SERVE' (11004). The mispelled CONST is on purpose, I'm trying to cause the error in this case.
|
|
|
|
05-07-2008, 02:48 PM
|
#5 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
Quote:
Originally Posted by delayedinsanity
The problem is the @ doesn't seem to be suppressing the error from calling a new mysqli object...
|
If the code is precisely as you posted, the @ should suppress any error. If you're still getting the error message then show us a full copy/paste script which doesn't work for you so that we can try it.
The following file outputs (for me) the expected output (error successfully suppressed): Doh MySQLi Exception: Access denied for user 'root'@'localhost' (using password: YES)
PHP Code:
<?php header('Content-Type: text/plain;charset=utf-8'); error_reporting(E_ALL | E_STRICT);
class DI_Test {
const SERVER = 'localhost',
USER = 'root',
PASS = 'invalid',
DB = 'talkphp_test';
private $mysqli;
public function __construct()
{
try {
$this->connectDB();
} catch (Exception $e) {
die($e->getMessage());
}
}
private function connectDB ()
{
$this->mysqli = @new mysqli(self::SERVER, self::USER, self::PASS, self::DB);
if (mysqli_connect_errno())
throw new Exception ('Doh MySQLi Exception: '.mysqli_connect_error());
}
}
$test = new DI_Test;
var_dump($test);
|
|
|
|
05-07-2008, 02:54 PM
|
#6 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
I believe that message is what the mysqli object is printing from its internal error reporting system so therefore it wont get caught by error_reporting(0) or the @ operator.
i think
PHP Code:
mysqli_report(MYSQLI_REPORT_OFF);
should shut it up
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-07-2008, 03:15 PM
|
#7 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Salathe: The code is exactly as posted, minus all the other methods and properties in the class, it would look pretty much the same as yours (with the exception being that my constants are defined outside of the class in a seperate config file, thus the lack of self::)
sketch: I'll try that when I get home, that sounds like it could/should help. The wierd thing I'm curious about is this snippet from the manual on mysqli_report;
PHP Code:
mysqli_report(MYSQLI_REPORT_ALL);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */ if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); }
...seems to imply that even with error reporting on, the error shouldn't pop up unless you explicitly check mysql_connect_errno(), but that's definitely not the case.
I'll update you all when I get home. Thanks again,
-m
|
|
|
|
05-07-2008, 04:14 PM
|
#8 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
I think the manual is a little lacking in areas, it even says that the constructor for mysqli returns FALSE on connect fail, but a constructor can't return values.
taken from "http://uk.php.net/manual/en/mysqli.connect.php"
Quote:
|
Returns a object which represents the connection to a MySQL Server or FALSE if the connection failed.
|
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-07-2008, 04:37 PM
|
#9 (permalink)
|
|
is cute and cuddly
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
|
Hahah, as usual the mistake is a silly one.
No exception was being thrown because I was checking if $this->mysqli was an object, which it was, error or not. Using mysqli_connect_error() (or as Salathe did, mysqli_connect_errno()) got it to work.
As a sidenote, mysqli_report() doesn't suppress the PHP notice itself, it just means mysqli_connect_error() doesn't get any information to return to you. So I either have to use @ or error_reporting(0) to test my exception.
Oh and apparently the code wasn't *exactly* as posted, but I won't go into further detail now that it's fixed. Lets just chock it up to early morning coding should not happen in my house. Thank you for your time, I'm here all week.
-m
|
|
|
|
05-07-2008, 04:43 PM
|
#10 (permalink)
|
|
Moderateur
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
|
Good to see you're happy delayedinsanity
sketchMedia, the manual isn't very clear I must admit! However, it is simply not possible to assign a value of FALSE to a variable when using $var = new Something which is why an empty object is returned on error and you have to check connect_errno/error to see if something went all wonky.
|
|
|
|
05-07-2008, 07:11 PM
|
#11 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
Yep seems the person who wrote that document either misunderstands how the new keyword works or its been copied from the procedural version (which im supposing must have been written first) and they havent changed that, very confusing for beginners and advanced users alike, i think most of the PHP documentation needs an overhaul anyway.
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-07-2008, 07:15 PM
|
#12 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
Quote:
|
As a sidenote, mysqli_report() doesn't suppress the PHP notice itself, it just means mysqli_connect_error() doesn't get any information to return to you.
|
actually when that is active, errors that the object encounters get passed through an exception called 'mysqli_sql_exception' therefore doesnt go through the normal PHP error reporting; resulting in both '@' and 'error_reporting(0)' failing.
Glad your all sorted though.
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
05-07-2008, 07:27 PM
|
#13 (permalink)
|
|
The Prestige
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
|
Quote:
|
As a sidenote, mysqli_report() doesn't suppress the PHP notice itself, it just means mysqli_connect_error() doesn't get any information to return to you.
|
actually when that is active, errors that the object encounters get passed through an exception called 'mysqli_sql_exception' therefore doesnt go through the normal PHP error reporting; resulting in both '@' and 'error_reporting(0)' failing to catch its messages.
Also as an example, the code snippet posted by salathe, when run with mysqli_report(MYSQLI_REPORT_OFF) set, the message generated is:
Code:
Doh MySQLi Exception: Access denied for user 'root'@'localhost' (using password: YES)
which is the exception message set in the catch statement however if its set to on (MYSQLI_REPORT_ALL):
Code:
Access denied for user 'root'@'localhost' (using password: YES)
so you see, with it ON the 'mysqli_sql_exception' overrides the exception being thrown in the class because it is raised inside the mysqli object itself.
Glad your all sorted though.
__________________
mysql> SELECT * FROM `users` WHERE `users`.`clue` > 0;
Empty set (0.00 sec)
|
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|