0

I wrote the following snippet in order to handle errors.

(Page.php gets included in index page through : array( falseNamePage=> page.php, ....ect))

Perfoming some tests to see how it reacts, I delete a page.php from public_html.

RESULT :

-error logging ok

-alert email sending ok

-recording in DB : ERROR :

Notice: Undefined variable: $database in /home/.../public_html/index.php on line 40

Warning: mysql_query() expects parameter 2 to be resource, null given in /home/.../public_html/index.php on line 40 "impossible to connect with DB2"

I do not understands why it fails connecting to the DB in this case and sends back an error.

DB Connection works fine in every other cases ( delete, select,update, insert ...)

function errorHandler($errno, $errstr, $errfile, $errline)
    {
    require_once('connection.php');
    $now = time();
    $date = date("Y-m-d H:i:s",$now);    
    switch ($errno) {
        case E_NOTICE:
        case E_USER_NOTICE:
        case E_DEPRECATED:
        case E_USER_DEPRECATED:
        case E_STRICT:

            ............ 5 first cases code...............

        case E_WARNING:
        case E_USER_WARNING:            

            $message_warning = "Warning : ".$errno." : ".$errstr." : ".$errfile." : ".$errline;
            error_log ( $message_warning ,0);
            $mail = 'my_mail@yahoo.com';  $sujet = $message_warning;  $body_warning = $date." : ".$message_warning;                             
            mail($mail,'=?UTF-8?B?'.base64_encode($sujet).'?=',stripslashes($body_warning));
            $query_warning  =" INSERT INTO errorlog (severity,errno,errstr,errfile,errline,time) 
            VALUES ('WARNING','".$errno."','".$errstr."','".$errfile."','".$errline."','".$date."')";           
            $result_warning = mysql_query($query_warning,$database) or die("impossible to connect with DB2");
                break;

        case E_ERROR:
        case E_USER_ERROR:

       ............... 2 last cases code ..........
    }       
}    
set_error_handler("errorHandler");  

The final question is :

WHY IS AN INCLUDE ERROR ECHOED 4 TIMES ?

Does the system attempts 4 times to "open stream"?

I did :

function errorHandler($errno, $errstr, $errfile, $errline)
           {
        if     ($errno == E_NOTICE )
        { echo "<br/>".$errno."== E_NOTICE<br/>";}
        if     ($errno == E_USER_NOTICE)
        { echo "<br/>".$errno."== E_USER_NOTICE<br/>";}
        if     ($errno == E_DEPRECATED)
        { echo "<br/>".$errno."== E_DEPRECATED<br/>";}
        if     ($errno == E_USER_DEPRECATED)
        { echo "<br/>".$errno."== E_USER_DEPRECATED<br/>";}
        if     ($errno == E_STRICT)
        { echo "<br/>".$errno."== E_STRICT<br/>";}
        if     ($errno == E_WARNING)
        { echo "<br/>".$errno."== E_WARNING<br/>";}
        if     ($errno == E_USER_WARNING)
        { echo "<br/>".$errno."== E_USER_WARNING<br/>";}
        if     ($errno == E_ERROR)
        { echo "<br/>".$errno."== E_ERROR<br/>";}
        if     ($errno == E_USER_ERROR)
        { echo "<br/>".$errno."== E_USER_ERROR<br/>";}
           }             
           set_error_handler("errorHandler");   

RESULT :

2== E_WARNING

2== E_WARNING

2== E_WARNING

2== E_WARNING

SunnyOne
  • 197
  • 5
  • 15
  • $database is defined in connection.php? – powtac Jul 03 '12 at 11:03
  • Yes $database stands for "database" (constant name) in PhpMyAdmin – SunnyOne Jul 03 '12 at 11:17
  • PHP's `mysql_*` functions are [deprecated](http://www.php.net/manual/en/faq.databases.php#faq.databases.mysql.deprecated). The [suggested alternatives](http://www.php.net/manual/en/mysqlinfo.api.choosing.php) also happen to be [easier to use safely](http://stackoverflow.com/a/60496/132382). – pilcrow Jul 03 '12 at 15:40
  • Yes it is a pity, I was taught mysql at school in spite of the fact is almost deprecated. Is it possible to use PDO with a site all written in procedural ? – SunnyOne Jul 03 '12 at 16:16
  • Answering the final question (btw, it's not quite good changing the topic, I suppose; the title becomes misleading, and all the answers seem to be irrelevant too): you do `return false` in your error_handler routine, right? – raina77ow Jul 05 '12 at 12:19
  • Sorry, you are right about changing the topic. You answer to the first question is also right : using REQUIRE instead of REQUIRE_ONCE allowed me to INSERT in DB. But then appeared the problem we are talking about right now : multiple inserts in DB and multiple echoes of the error message in the browser. No I do not return false, as PHP manual says "The error handler must return FALSE to populate $php_errormsg. ", but as far as I understand, I think I do not make use of "$php_errormsg" in these scripts. Am I wrong ? – SunnyOne Jul 05 '12 at 21:17

3 Answers3

1

Probably connection.php has already been included before, so when you use require_once in your code, it does not include connection.php again. Then, $database variable will not be defined, and you will got that error message.

J. Bruni
  • 20,322
  • 12
  • 75
  • 92
0

When there is no function definition and no constant definition in connection.php use require instead of require_once.

The variable $database will not be available when the function is called the second time, because of require_once. It is a little bit bad designed here.

A solution would be to have $database as a constant, so it acts like a global variable no matter if connection.php was the included first or second time.

powtac
  • 40,542
  • 28
  • 115
  • 170
  • 3 times this one :[03-Jul-2012 11:27:12 UTC] Warning : 2 : include(file.php) [0function.include0]: failed to open stream: No such file or directory : /home/.../public_html/index.php : 627 gives => 3x times an insert in DB////// 1 time : [03-Jul-2012 11:27:12 UTC] Warning : 2 : include() [0function.include0]: Failed opening 'file.php' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') : /home/.../public_html/index.php : 627 =>die() on this one. It seems that error number [2] is issued by each switch. – SunnyOne Jul 03 '12 at 13:59
  • Are you sure you wrote this "snippet" by yourself or you copied it? – powtac Jul 03 '12 at 14:02
  • I found some parts of this code and transformed it to do a lot more than it did. – SunnyOne Jul 03 '12 at 14:06
0

Your problem is simple, and, in my opinion, it's YAPHPB: you're using require_once within a function definition, hoping that the file will be included just once - to shape up a function's body.

But it doesn't work like that: this code will be parsed each time (well, it's a bit simplified, but the reasons still the same) the function will get called. And because it's require_once, your file will be included just once indeed - only when the function is called first time. All the next calls will skip the file's inclusion, hence $database will not be defined.

The easiest way to fix it is to replace require_once with require. But I think the problem just will be covered - but not solved. The real solution would be to restructure your code in such way that your $database will actually become a record in registry - and will be lazily extracted from that registry if needed.

There are many ways to implement such behaviour: we often use Zend_Registry component for that. And in this topic there are some examples of how to use this component effectively.

Community
  • 1
  • 1
raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • Well, I've just used REQUIRE instead of required_once. Recording in DB = ok (however I get the die(message)). Mail sending = ok. BUT ... I echo a own error handling message in each code block and I get 4 times my custom error message although placed in different switch cases. AND Error logging appears 4 times ... thanks for your help. – SunnyOne Jul 03 '12 at 11:34
  • What do you mean by 'recording is ok, but `die` is executed'? – raina77ow Jul 03 '12 at 11:41
  • 3 times this one :[03-Jul-2012 11:27:12 UTC] Warning : 2 : include(file.php) [0function.include0]: failed to open stream: No such file or directory : /home/.../public_html/index.php : 627 1 time : [03-Jul-2012 11:27:12 UTC] Warning : 2 : include() [0function.include0]: Failed opening 'file.php' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') : /home/.../public_html/index.php : 627 AND one insert in DB in spite of die() !!! strange indeed ! – SunnyOne Jul 03 '12 at 13:21
  • 3 inserts in DB in fact, not one. Each time with the same error number [2] --They are generated all 3 by switch number 2 (Warning) – SunnyOne Jul 03 '12 at 14:49
  • Does `connection.php` includes any other file? – raina77ow Jul 03 '12 at 15:11
  • Connection.php is only the connection script to the DB, containing mysql_select_db//mysql_connect//password//username//hostname//// file.php the missing file I deleted to test my error handler. File.php is called to get included thanks to a forward array in index. – SunnyOne Jul 03 '12 at 16:07