TUTORIAL: Making Troubleshooting a bit easier

  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8399
  • Loc: USA

Post 3+ Months Ago

Introduction


PHP Knowledge level: Beginner.

This tutorial is for those who knows PHP enough to know that trouble shooting SQL statements and any other problems could be hard, especially when the file reaches greater than 500 lines of code. I have come up with a solution (a technique) for this. To make troubleshooting easier.

Requirements to accomplish this tutorial successfully... besides some kind of PHP server and knowledge, I have no problem with it. You can get WAMP for local testing... it's free.

The Problem


Have you ever tried to fix an error when all you get is Unknown 'column' in 'field list'? AND there is a ton of SQL on that page and you have to go and see which one is written incorrectly? Well, this tutorial would help you fix that problem.

If you already have a huge file you want to use this technique on... you can use a simple search/replace function build into most editors... even the regular Notepad that came with your computer (Probably :lol:)

The Solution


There are two predefined constants that would help us here... The first one is the line number that the parser is on and the second one is the file that the function is on. This way you would know on which line and file the error occurred if you have a class or just simply some PHP code where you include one file into another.

1: __LINE__ = The line that the parser is on.
2: __FILE__ = The file that the parser is on.

Now, how can we get this to work for us? Lets say we have the following SQL statement (It has an error in it...)
PHP Code: [ Select ]
<?php
$sql = "CREATE TABLE `table` (
         `ID` TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
         `field1` VARCHAR(255) NOT NULL,
         `field2` VARCHAR(255) NOT NULL
         )
         ENGINE = innodb;";
mysql_query($sql) or die(mysql_error());
$sql = "INSERT INTO `{$dbName}`.`table` (
       `field1`,
       `field3`,
       ) VALUES ('". NULL ."', 'VALUE1','VALUE2');";
mysql_query($sql) or die(mysql_error());
?>
  1. <?php
  2. $sql = "CREATE TABLE `table` (
  3.          `ID` TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  4.          `field1` VARCHAR(255) NOT NULL,
  5.          `field2` VARCHAR(255) NOT NULL
  6.          )
  7.          ENGINE = innodb;";
  8. mysql_query($sql) or die(mysql_error());
  9. $sql = "INSERT INTO `{$dbName}`.`table` (
  10.        `field1`,
  11.        `field3`,
  12.        ) VALUES ('". NULL ."', 'VALUE1','VALUE2');";
  13. mysql_query($sql) or die(mysql_error());
  14. ?>

Do you see me using mysql_error(); there? That is NOT ENOUGH when all you get from it is Unknown 'column' in 'field list'

By the way, the error is that there is no field3 created in table... So you will get that error that doesn't give you from much to go on.

Even if the error that mysql_error(); spits out has a number, it usually has 1 as the line number when the SQL is actually on line 986 in midst of a ton others SQLs that you have to look through to find the error... So, what can you do?

Use the __LINE__ and __FILE__ predefined constants... so in this case the mysql_query() would look like...

PHP Code: [ Select ]
<?php
$sql = "CREATE TABLE `table` (
         `ID` TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
         `field1` VARCHAR(255) NOT NULL,
         `field2` VARCHAR(255) NOT NULL
         )
         ENGINE = innodb;";
mysql_query($sql) or die(mysql_error() ." ( at line <strong>".  (__LINE__) ."</strong> in <strong>". (__FILE__) ."</strong>)");
$sql = "INSERT INTO `{$dbName}`.`table` (
       `field1`,
       `field3`,
       ) VALUES ('". NULL ."', 'VALUE1','VALUE2');";
mysql_query($sql) or die(mysql_error() ." ( at line <strong>".  (__LINE__) ."</strong> in <strong>". (__FILE__) ."</strong>)");
?>
  1. <?php
  2. $sql = "CREATE TABLE `table` (
  3.          `ID` TINYINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  4.          `field1` VARCHAR(255) NOT NULL,
  5.          `field2` VARCHAR(255) NOT NULL
  6.          )
  7.          ENGINE = innodb;";
  8. mysql_query($sql) or die(mysql_error() ." ( at line <strong>".  (__LINE__) ."</strong> in <strong>". (__FILE__) ."</strong>)");
  9. $sql = "INSERT INTO `{$dbName}`.`table` (
  10.        `field1`,
  11.        `field3`,
  12.        ) VALUES ('". NULL ."', 'VALUE1','VALUE2');";
  13. mysql_query($sql) or die(mysql_error() ." ( at line <strong>".  (__LINE__) ."</strong> in <strong>". (__FILE__) ."</strong>)");
  14. ?>

This way, you will have some knowledge of actually WHERE the error has happened.

Going a step farther


Yeah, why not go a step farther with this? Everyone does it... Make your own errors when you need to. Set, what I like to call, "error triggers".

Lets say I have an if...elseif...else statement. Well first of all, lets change that to switch...case... operator.
PHP Code: [ Select ]
<?php
switch($var)
{
  case null:
  case "index":
    $this->template('index');
    break;
  case "page":
    $this->template('page');
    break;
  default:
    echo "<p><strong>ERROR 1:</strong> Variable \$var unrecognized on line ". (__LINE__) ." in file ". (__FILE__) ."</p>"\n";
    break;
}
?>
  1. <?php
  2. switch($var)
  3. {
  4.   case null:
  5.   case "index":
  6.     $this->template('index');
  7.     break;
  8.   case "page":
  9.     $this->template('page');
  10.     break;
  11.   default:
  12.     echo "<p><strong>ERROR 1:</strong> Variable \$var unrecognized on line ". (__LINE__) ." in file ". (__FILE__) ."</p>"\n";
  13.     break;
  14. }
  15. ?>

Yeah, I just did it. I just created my own error. This shall help me as well as the user if the user roams into error territory. Means "DON'T GO THERE... ERRORS HAPPEN".

Wait, trigger usually means it sets something off... so if I call it an "error trigger" what am I setting off? Well, the error of course.

The trigger is not the error itself, but the cause of the error. Usually people just leave it there so if the user goes there that should be an error and just see a blank page, the user would be puzzled. Ease their mind and say that they roamed into "error territory".

Another step down the beaten path?


Why not set your own function for error reporting... so this time you can do something like
Code: [ Select ]
$error->set_error(__LINE__,__FILE__,'Error Message');
so you could do some more and better error reporting things... maybe even set the error level... like E_ALL or E_WARNING...

You can do that with a simple function called trigger_error and it's family members listed in the "View Also" on that page.

The warnings you can use for it are...
  • E_USER_ERROR
  • E_USER_WARNING
  • E_USER_NOTICE
And explanation for them can be found here remember, it's only the E_USER_* type warnings that can be used and not all of those other error function constants.

Anyway, I'm just telling what I learned.
PHP Code: [ Select ]
<?php
 function set_error($line,$file,$message)
 {
   $error[] = "<p>An error occurred on line {$line} in file {$file}:<br /> {$message}</p>\n";
 }
?>
  1. <?php
  2.  function set_error($line,$file,$message)
  3.  {
  4.    $error[] = "<p>An error occurred on line {$line} in file {$file}:<br /> {$message}</p>\n";
  5.  }
  6. ?>

This way you could make a whole class for errors if you like :lol: with a collection of functions such as set_error(); clear_error(); count_errors(); and many more things if you are good with PHP and know how to use classes and $this; and the single arrow "->" and double arrows "=>"

You can read this tutorial made by spork to get a better idea on what you can do.

Conclusion


You just now learned a good technique to make troubleshooting easier (Hopefully).

Don't forget to use __LINE__ and __FILE__ whenever the needs be.
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • Rabid Dog
  • Web Master
  • Web Master
  • User avatar
  • Posts: 3245
  • Loc: South Africa

Post 3+ Months Ago

Nice write up there but I disagree with your "error triggers". Those cases should be handled via exceptions :) What if the error can be swallowed or needs only be logged? The method you described will always display the error and gives the developer no control over extending the system.

The error levels you describe would be more useful in a background logging scenario as to allow graceful failures on the front end. It is always good to differentiate between system errors and runtime errors. Triggering errors in PHP should be runtime and not system based. Also just because everyone is doing it doesn't make it right LOL

might be worthwhile checking out http://incubator.apache.org/log4php/index.html for the lo4j port for PHP (not sure it is stable yet)

Another thing, if the PHP file reaches 500 lines of code take a step back and reasses your responsibility allocation
  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8399
  • Loc: USA

Post 3+ Months Ago

I guess I should have added the following line to the tutorial:

"This method is good only during development stage... for the release/live stage, it is recommended to create error levels for graceful failures".
  • righteous_trespasser
  • Scuffle
  • Genius
  • User avatar
  • Posts: 6230
  • Loc: South-Africa

Post 3+ Months Ago

Also remeber, sometimes error reporting may be turned off (had a bad experience with this when I was just startig to learn PHP), to enable error reporting in PHP you can add the following line of code to the top of your script:
PHP Code: [ Select ]
<?php error_reporting(E_ALL); ?>

or if you don't want to see notices you can just exclude that with the following:
PHP Code: [ Select ]
<?php error_reporting(E_ALL ^E_NOTICE); ?>
  • Bogey
  • Genius
  • Genius
  • Bogey
  • Posts: 8399
  • Loc: USA

Post 3+ Months Ago

Thanks for pointing that out righteous.... lol R_T.

I didn't think about that one since I always have my error reporting on... well, I have the fatal warnings and user warnings and thats about it.

Post Information

  • Total Posts in this topic: 5 posts
  • Moderator: Tutorial Writers
  • Users browsing this forum: No registered users and 2 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.