TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 05-07-2008, 06:04 AM   #1 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default 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_SERVERDB_USERDB_PASSDB_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...
delayedinsanity is offline  
Reply With Quote
Old 05-07-2008, 09:59 AM   #2 (permalink)
The Frequenter
Newcomer 
 
xenon's Avatar
 
Join Date: Dec 2007
Location: Bucharest, Romania
Posts: 438
Thanks: 3
xenon is on a distinguished road
Default

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.
xenon is offline  
Reply With Quote
Old 05-07-2008, 10:37 AM   #3 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-07-2008, 02:06 PM   #4 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

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.
delayedinsanity is offline  
Reply With Quote
Old 05-07-2008, 02:48 PM   #5 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

Quote:
Originally Posted by delayedinsanity View Post
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::SERVERself::USERself::PASSself::DB);
        if (
mysqli_connect_errno())
            throw new 
Exception ('Doh MySQLi Exception: '.mysqli_connect_error());
    }
}

$test = new DI_Test;
var_dump($test);
Salathe is offline  
Reply With Quote
Old 05-07-2008, 02:54 PM   #6 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-07-2008, 03:15 PM   #7 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

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
delayedinsanity is offline  
Reply With Quote
Old 05-07-2008, 04:14 PM   #8 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-07-2008, 04:37 PM   #9 (permalink)
is cute and cuddly
 
delayedinsanity's Avatar
 
Join Date: Mar 2008
Location: Vegas, Baby
Posts: 963
Thanks: 31
delayedinsanity is on a distinguished road
Default

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
delayedinsanity is offline  
Reply With Quote
Old 05-07-2008, 04:43 PM   #10 (permalink)
Moderateur
RegEx Guru PHP Guru Top Contributor Advanced Programmer 
 
Salathe's Avatar
 
Join Date: Apr 2007
Posts: 1,393
Thanks: 5
Salathe is on a distinguished road
Default

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.
Salathe is offline  
Reply With Quote
Old 05-07-2008, 07:11 PM   #11 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-07-2008, 07:15 PM   #12 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Old 05-07-2008, 07:27 PM   #13 (permalink)
The Prestige
Advanced Programmer Top Contributor Good Samaritan 
 
sketchMedia's Avatar
 
Join Date: Oct 2007
Location: Manchester, UK
Posts: 854
Thanks: 32
sketchMedia is on a distinguished road
Default

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)
sketchMedia is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 03:25 PM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design