Error Function Help/Suggestions

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Error Function Help/Suggestions

Post 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.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post by Skara »

bump. No one has any ideas...? :(
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post 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.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post 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.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post 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 :\
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post 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.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post 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?
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post 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. :/
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post 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.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post 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...?
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post 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.
User avatar
Skara
Forum Regular
Posts: 703
Joined: Sat Mar 12, 2005 7:13 pm
Location: US

Post 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?
:?
Post Reply