Page 1 of 1

Error Function Help/Suggestions

Posted: Fri Jun 17, 2005 6:22 pm
by Skara
I'm trying to write an error function that is easy to use and versitile to use with all of my sites (I host quite a few).
I don't like large error classes that do all sorts of fancy stuff. I also like text logs rather than database ones. Just my preference.
That said, here's the code:

Code: Select all

<?php
/**
 * define ERRLOG to change location and/or filename of the log. (default: error.log)
 * define ERRUSER as the user varialbe to log the user.         (default: off)
 *   -- without $, as so: define("ERRUSER","_SESSION['user']");
 * define ERRPAGE to produce a server error like page           (default: off)
 * define ERRLINE and use __LINE__ as a second parameter to log
 *   the line the error occurred on.                            (default: off) [if defined:(default: ??)]
 *
 * Example Use: err("Error message.");
 *              err("Error message.",__LINE__);
 */
function err($msg='Undefined Error',$line='??') {
  $out = time().'|'.$msg.'|'.$_SERVER['REQUEST_URI'];
  if (defined('ERRLINE')) {
    $out .= '|'.$line;
    $msg .= " ({$line})";
  }
  if (defined('ERRUSER')) {
    $uservar = ERRUSER;
    global $$uservar;
    $user = isset($$uservar) ? $$uservar : 'G';
    $out .= '|'.$user;
  }
  $log = defined('ERRLOG') ? ERRLOG : 'error.log';
  $handle = @fopen($log,'a');
  @fwrite($handle,$out."\n");
  if (defined('ERRPAGE')) {
    $err = 'Error'; // for the error page \/
    require '/var/www/localhost/error/main.php';
    die;
  }
  else die("<b>Error:</b>&nbsp; {$msg}");
}
?>
The problem I'm having is with logging the user. It works fine if the variable that stores the user is something like $user, but that doesn't often happen.
How could I define the name of the user variable as something like $_SESSION['user'] and have it work right?

Also, any suggestions would be great great.

Posted: Sat Jun 18, 2005 1:40 pm
by Skara
bump. No one has any ideas...? :(

Posted: Sat Jun 18, 2005 2:24 pm
by John Cartwright
Firstly, I beleive your whole question is a bit confusing.

Secondly, are you looking to have 1 log file to deal with ALL Your sites?
Could be a problem unless you set some permissions correctly.

I would never rely a global variable to exist over multiple websites -- too unreliable, yet you say you are the person hosting/maintaining them so you could potentially design the sites to log a "user". I would probably use $_SERVER['SERVER_NAME'] as it will always exist and be able to identify the unique user.

Posted: Sat Jun 18, 2005 6:54 pm
by Skara
Hm.. Well, let me start from the beginning.
First, I intend to use this same error function for all my sites, but I intend to use the file differently. For example, some of my sites don't have a user system, so I wouldn't use that part. Given that, the error.log (or whatever) file would obviously be different for each site.
About the permissions thing.. I think you misunderstand what I mean by user. I design and maintain all my sites. By user I mean user like this forum has users. This forum more than likely uses a different variable to store the user than my other sites do. Some sites might use a cookie, others a session, some maybe just a regular variable. My problem is how to pass the name of that variable to the error function.
To make the problem simpler, let me put it like this:

Code: Select all

function foo($name) {
  echo $$name;
}
foo("bar");
foo("baz['meh']");
foo("_SESSION['other']");
"bar" will work, but the other two won't.
Now with the above, I could just do foo($bar) and be fine. But I plan on defining the name of the variable once and be done with it rather than passing it as a param/argument each time.

Posted: Sat Jun 18, 2005 7:30 pm
by John Cartwright
If its going to be different on each site.. why don't you just pass the variable you are using. In other words hard code it in there.

site uses cookies, pass the cookie for on domain 1
site uses sessions, pass the session var on domain 2..

Sorry if I'm being thick but I just don't see the problem :\

Posted: Sat Jun 18, 2005 8:05 pm
by Skara
Yeah, I know I could do that. But I'd rather define the name of the variable once and be done with it.
If that's not possible, oh well.

Posted: Sat Jun 18, 2005 8:43 pm
by Chris Corbyn
It is possible....

Let's say you have a variable you need to call but that variable changes. Sometimes it's called $var1, sometimes $var2 and sometimes $var3 etc.

You don't want to hard code for each case so you allow it to be chaged (I'm sure you'll work out how to get this into your class / function so it makes more sense than what I write below).

Code: Select all

//These have come from wherever
$var1 = 'I am variable one';
$var2 = 'I am variable two';
$var3 = 'I am variable three';

$varname = 'var1'; //As an example

echo $$varname; //Or ${$varname}
Have I misunderstood you?

Posted: Sat Jun 18, 2005 10:15 pm
by Skara
Well, you understood right. But you didn't notice where my problem is.

Code: Select all

$_SESSION['foo'] = 'blah';
$meh = "_SESSION['foo']";
echo $$meh;
It doesn't work. :/

Posted: Sun Jun 19, 2005 12:29 am
by Ambush Commander
Maybe you should rethink where you're getting all this data form. Tie it in an object or something. When you need to start manipulating variable names something's wrong.

Posted: Sun Jun 19, 2005 11:57 am
by Skara
Voila! Never even thought of an object. ^^;

I'm not really sure if I'm doing the reference for the user variable right. Never needed to work with them before.

Here's the class now:

Code: Select all

<?php
/**
 *  Example Usage: $errobj =& new err('/path/to/error.log',$_SESSION['user'],true,'skara@jumpfrog.org');
 *                 trigger_error('error message', E_USER_ERROR);
 */
class err {
  var $user; // User who triggered the error *
  var $page; // Display a server error page (like 404 etc)
  var $mail; // Email $mail a message *
  var $elog; // Log the error to $elog *
  // * If false, skip that section

  ## The part in question \/ ##
  function err($e=false,&$u=false,$p=false,$m=false) {
    $this->$elog = $e;
    $this->$user = &$u; ## here too
    $this->$page = $p;
    $this->$mail = $m;
    set_error_handler(array(&$this,'handler'));
  }
  function handler($errno,$errstr,$errfile,$errline) {
    switch ($errno) {
      case E_ERROR:
      case E_USER_ERROR:
      case E_STRICT:          $type = "Fatal Error";     break;
      case E_WARNING:
      case E_USER_WARNING:    $type = "Warning";         break;
      case E_PARSE:           $type = "Parse Error";     break;
      case E_NOTICE:
      case E_USER_NOTICE:     $type = "Notice";          break;
      case E_CORE_ERROR:      $type = "Core Error";      break;
      case E_CORE_WARNING:    $type = "Core Warning";    break;
      case E_COMPILE_ERROR:   $type = "Compile Error";   break;
      case E_COMPILE_WARNING: $type = "Compile Warning"; break;
      default:                $type = "Undefined Error"; break;
    }
    // are we logging to a file?
    if ($this->$elog !== false) {
      // ex: 1119198698|example.php?foo|8|Generic error has occurred.|34
      $logmsg = time().'|'.$_SERVER['REQUEST_URI'].'|'.$errno.'|'.$errstr.'|'.$errline;
      // are we logging the user?
      if ($this->$user !== false) $logmsg .= '|'.$this->$user;
      // log it to $elog
      error_log($logmsg."\n",3,$this->$elog);
    }
    // are we emailing someone?
    if ($this->$mail !== false) {
      $mailmsg = "An Error has occurred on {$_SERVER['SERVER_NAME']}:\n\n".
                 date('F d, Y g:i a')."\n{$_SERVER['REQUEST_URI']}\n{$type}:\n{$errstr}\nLine: {$errline}";
      $headers = "Subject: Error on {$_SERVER['SERVER_NAME']}\nFrom: Error Handler <errors@jumpfrog.org>";
      // mail it to $mail
      error_log($mailmsg,1,$this->$mail,$headers);
    }
    // set here because main.php uses it as well
    $msg = $errstr.' ('.$errline.')';
    // only for the big uhohs do we die
    if ($type == "Fatal Error") {
      // should we display a server-error-like page?
      if ($this->$page !== false) {
        $err = $type; // sets title in main.php
        require '/var/www/localhost/error/main.php';
      }
      die;
    }
    // not fatal
    else print("<b>{$type}:</b>&nbsp; {$msg}<br />\n");
  }
}
?>
Pretty much rewritten, I know.

Here's what I might do:

Code: Select all

$errobj =& new err('/path/error.log',$_SESSION['user']);
$_SESSION['user'] = 'different';
trigger_error('whoops',E_USER_ERROR);
Now will that work...?

Posted: Sun Jun 19, 2005 12:26 pm
by John Cartwright
Thats what I was getting at, once you pass whatever variable you are using to the function create a object which can be passed throughout the class. Sorry for not being clear.

Posted: Sun Jun 19, 2005 1:33 pm
by Skara
...I really have no idea what you just said.
First pass the user variable to "the function."
Then create an object. As in create an object with the function? Or do you mean I have it right in that "$obj = new foo($variable);" passes the $variable through foo() then creates $obj?
:?