NotionCommotion Posted December 15, 2014 Share Posted December 15, 2014 I am looking to save the user's access of an application. For instance, when they log in, I create a record in the "track_login" table which includes information such as the requesting IP, the user's ID, the date, (not the user's password), etc. And then for every page they visit, I store a record in the "track_page_viewed" table which includes a FK to the "track_login" table and also includes additional information about their request. Both the track_login and track_page_viewed tables are currently in the same database as used by the primary application. So far, so good. Next, I want to start tracking when a user does special tasks such as when they forget their password and request that a new one be emailed to them. Or maybe when they attempt to login with an invalid username and password. Currently, I just included another table called "track_special" which includes the data, the type of special request, etc. Now, I am thinking of adding three other things to track: General PHP errors MySQL errors Try/Catch errors which I did not expect to happen One option is just to add these to my "track_special" table or maybe make one or three new tables in the same database. But is this a good idea? If I have a SQL error, do I really want to store the error in the same database? Maybe I should use a separate database called "myTrackerDB", and include all the above tables in that database? Or maybe I should just write the data to a flat file, and parse the file on a regular basis, and then store the information in the database? Please provide any recommendations, guidance, suggestions, criticism, etc. Thank you Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 15, 2014 Share Posted December 15, 2014 While I don't see why you want to track many of these things the way you are, I most definitely think you should user the php error log for your last items, not a db. Read up in the manual on how to trigger error messages of your own design into the error log. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 15, 2014 Author Share Posted December 15, 2014 (edited) While I don't see why you want to track many of these things the way you are, I most definitely think you should user the php error log for your last items, not a db. Read up in the manual on how to trigger error messages of your own design into the error log. Yea, you are probably right. I've never used error_log() and have only used syslog(). Do you recommend using error_log()? Below is what I am doing. Any recommendations? Thanks <?php abstract class base { public function __construct($domain) { ini_set('display_errors', 1); error_reporting(E_ALL); set_error_handler(array($this,"my_error_handler")); //Log all to LOG_LOCAL0 which is in turn /var/messages/php.log openlog('custom_log', LOG_NDELAY, LOG_LOCAL0); //otherStuff } public function my_error_handler($e_number, $e_message, $e_file, $e_line, $e_vars) { $message = "An error occurred in script '$e_file' on line $e_line: $e_message (error no: $e_number)"; if (true || in_array(substr($_SERVER['HTTP_HOST'], 0, 5), array('local', '127.0', '192.1'))) { echo $message; } else { syslog(LOG_INFO,'my_error_handler: '.$message); // Or should I be using something like: error_log ($message, 1, 'errors@gmail.com'); if ( ($e_number != E_NOTICE) && ($e_number < 2048)) { echo '<div class="error">A system error occurred. We apologize for the inconvenience.</div>'; } } } //Called from try/catch public function sql_error($e,$sql) { syslog(LOG_INFO,'SQL Error '.$sql.', '.$e->getMessage().', file:'.$e->getFile().' line:'.$e->getLine()); //deal with displaying as applicable } //Called when the application gets some unexpected results public static function application_error($msg,$file,$line) { syslog(LOG_INFO,'Application Error - Application - '.$msg.', file:'.$file.' line:'.$line); //deal with displaying as applicable } public function otherMethods() { echo('Hello'); } } ?> Edited December 15, 2014 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 16, 2014 Author Share Posted December 16, 2014 Also, I just stumbled upon trigger_error() (http://php.net/manual/en/function.trigger-error.php). Is this what you had in mind? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 17, 2014 Share Posted December 17, 2014 The class doesn't make a lot of sense to me. It's basically just a buggy and incomplete re-implementation of the standard PHP error system. In fact, it's seriously broken: You jump into debug mode if the Host header contains something like “local”, but this header is defined by the client. They can set it to anything they want. Of course “local” won't be a valid virtual host, but many servers accept the request nonetheless and will select some default host. Those localhost detections are generally very problematic, because they may not work in all server setups. For example, if there's a reverse proxy in front of Apache running on the same machine, then the script may think that all requests are local. That's obviously a huge risk. A much better solution is explicitly activate the debug mode through a configuration file (use a constant, for example). You only catch a small subset of all possible errors. Obviously you can't handle errors which happen before the script is executed (syntax errors, startup errors). But even E_ERROR and E_STRICT aren't covered by custom error handlers (see the manual). That means your users will either see a white screen or the raw PHP error message. You don't set an appropriate HTTP status code, which means it's always “200 OK”. That's obviously a lie and a problem for everybody who relies on the code. I strongly recommend that you learn how the standard error system works before you write your own implementation. It's much more powerful than you seem to think, and it's definitely much better than most custom error handlers: The default error handler actually covers all errors, including syntax issues. PHP already takes care of logging. Simply turn on log_errors and set error_log appropriately in the php.ini. No need to manually handle SQL errors. Both PDO and MySQLi automatically throw errors or exceptions if you tell them to. PHP also sets a 500 status code if there's a fatal error and no prior output. All modern webservers support custom error pages, so no need to do that with PHP. There may be some special scenarios where a custom error handler is in fact necessary. But I don't see that in your case. If you do need your own handler, this will be much more complicated than calling set_error_handler(). Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 17, 2014 Author Share Posted December 17, 2014 Thank you for your reply Jacques, I agree my class was far from perfect, and was just my initial attempt to better learn how I should use error reporting. A couple of related questions/comments: Agree that the localhost detection should go away, and I will either use a constant as you recommend or two separate php.ini files. I see where see the manual states that E_ERROR and E_STRICT aren't covered by custom error handlers, however, http://php.net/manual/en/errorfunc.examples.php seems to show an example otherwise. Please explain. log_errors will be set per the recommended php.ini file. Should I also set error_log, or should it remain blank so they go to the SAPI Error Logger? (what does this mean?) Good point about setting the appropriate HTTP status code if a custom error handler is used. Could the standard error system both log and email errors? PHP also sets a 500 status code if there's a fatal error and no prior output. Would the custom error pages supported by all modern webservers support custom error pages display a given page should a 500 status code be given by PHP? Regarding PDO automatically throwing errors or exceptions, do I want to catch them, or just let them remain uncaught (assuming I wanted the error handler to deal with them)? <?php date_default_timezone_set('America/Los_Angeles'); error_reporting(E_ALL); ini_set('display_errors', 1); function sql_error($e,$sql) { $silent=(isset($e->errorInfo[1]) && $e->errorInfo[1]==1062)?$silent:0; //Only silent duplicate key errors $error='Error in query:<br />'.$sql.'<br />'.$e->getMessage().'<br />File Name: '.$e->getFile().'<br />Line: '.$e->getLine().'<br />Time of Error: '.date("l F j, Y, G:i:s T").'<hr>'; echo($error); } require_once('../../ayb_private/dbase.php'); $sql='SELECT a FROM b'; try { $stmt=db::db()->query($sql); $a=$stmt->fetchColumn(); } catch(PDOException $e){sql_error($e,$sql);} //uncaught $stmt=db::db()->query($sql); $a=$stmt->fetchColumn(); Error in query: SELECT a FROM b SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testing.b' doesn't exist File Name: /var/www/testing/html/testing/sql.php Line: 18 Time of Error: Wednesday December 17, 2014, 11:24:07 PST Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testing.b' doesn't exist' in /var/www/testing/html/testing/sql.php:24 Stack trace: #0 /var/www/testing/html/testing/sql.php(24): PDO->query('SELECT a FROM b') #1 {main} thrown in /var/www/testing/html/testing/sql.php on line 24 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted December 17, 2014 Share Posted December 17, 2014 I see where see the manual states that E_ERROR and E_STRICT aren't covered by custom error handlers, however, http://php.net/manual/en/errorfunc.examples.php seems to show an example otherwise. Please explain. It does not show an example otherwise. There's an array of all possible error types, but there's also a comment saying that only a few of them are actually used. log_errors will be set per the recommended php.ini file. Should I also set error_log, or should it remain blank so they go to the SAPI Error Logger? (what does this mean?) A blank value means that you leave the error logging to the server interface. For example, the various PHP/Apache interfaces will invoke the Apache logging mechanism which in turn writes the message to the webserver log. Whether you prefer a separate log for the PHP errors or want them in the general server log is up to you. Could the standard error system both log and email errors? No, it doesn't send e-mails. Would the custom error pages supported by all modern webservers support custom error pages display a given page should a 500 status code be given by PHP? I don't understand the question. When PHP emits a 500 status code, then the webserver reacts to that. Typically, it will display one of those ugly Apache error messages. But you can also set up custom error pages instead. Regarding PDO automatically throwing errors or exceptions, do I want to catch them, or just let them remain uncaught (assuming I wanted the error handler to deal with them)? Uncaught exceptions simply trigger a fatal error which is processed like any other fatal error (the script is aborted, the error handling mechanism is invoked etc.). The only reason for catching an exception is when you want to do something special with it. For example, in some rare cases you may have a backup plan for a particular problem. Or maybe you want to display a special message for the user (like “This name is already taken.” when the UNIQUE constraint of the name field has been violated). But in general, you do not catch exceptions. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted December 17, 2014 Author Share Posted December 17, 2014 Thanks again Jacques, I've been catching SQL exceptions just to log the error and exit. Don't ask me why, but I agree it doesn't make much sense. Think I started doing so after reading some stupid book or tutorial. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.