How to get error messages?

I am on Ubuntu 10.04 using PHP5 and MySQL 5.

Being my first php program I put some tracing code in using fopen, fwrite and fclose to trace what was going on as shown below.
Before I added the handledbrequest function the tracing worked fine and produced trace information in file dumpfile.txt, but after there was no dumpfile.txt generated. After some hours I pinpointed the problem to variable reqnames misssing $ in function handledbrequest. Putting $reqnames cleared the problem and dumpfile.txt reappeared.

My guess is that the php parser stopped when detecting the error which meant the rest of the code was never executed including the fopen, fwrite. Is that so?

Q1. How do I get parsing errors like this to show? (and other errors too)

Q2. If error reporting is controlled by an ini or config file where is it
(for Ubuntu) and what do I put in it?

Would be grateful for advice.


<?php

function handledbrequest ( $con , $reqtp , $sql )
   {
   $reqnames = array('i'=>'Insert', 'q'=>'Select','u'=>'Update',
                     'd'=>'Delete');
   // skipped section
   $error = regnames[$reqtp] . ' error: ' . mysql_error(); //<<<problem
   return $error ;
   } 

$host='localhost';
$userid='root';
$passwd='secret';
$dbname='mydb';

$err= "0";

$myFile = "dumpfile.txt";
$fh = fopen($myFile, 'w') or die("can't open file");

$con = mysql_connect($host,$userid,$passwd);
fwrite($fh, "con=$con\
");
if (!$con)
   {
   $err = 'Could not connect: ' . mysql_error();
   }
else
   {
   $dbselected = mysql_select_db($dbname, $con);
   if ( !$dbselected )
      {
      $err = 'Could not select db: '. $dbname . ' '. mysql_error();
      }
   else
      {   
      fwrite($fh, "$dbname dbselected\
");
      $reqtp = $_GET['req'];
      $sql =  $_GET['sql'];
      fwrite($fh, "req=$reqtp sql=$sql\
");
      //$err = handledbrequest ( $con , $reqtp, $sql );
      }
   fwrite($fh, "err=$err\
");
   }

fclose($fh);
?>

  1. You shouldn’t pass raw sql by GET or POST that matter, they’re too easily manipulated.
  2. What are your runtime expectations
  3. instead of using fopen fwriter for debug messages error_log() will print to the error log.

I would not recommend changing your php.ini. Instead, try this in the script in question:

echo ini_get(‘display_errors’);

if (!ini_get(‘display_errors’)) {
ini_set(‘display_errors’, 1);
}

echo ini_get(‘display_errors’);

for more info check http://php.net/manual/en/errorfunc.configuration.php

Having this at the top of php:


error_reporting(E_ALL|E_STRICT);
ini_set('display_startup_errors', 0);
ini_set('display_errors', 0);
ini_set('log_errors',1);
ini_set('error_log', '/home/ken/myerrorlog.txt'); 
error_log ( "KEN LOG: starting" , 0 );

function handledbrequest ( $con , $reqtp , $sql )
   {
   global $fh;
   $reqnames = array('i'=>'Insert', 'q'=>'Select','u'=>'Update',
                     'd'=>'Delete');
   $error = $reggnames[$reqtp] . ' error: ' . mysql_error();
   return $error ;
   } 

Then the following was put into myerrorlog.txt:


www/dbjs.php on line 22
[22-Sep-2010 18:25:39] PHP Stack trace:
[22-Sep-2010 18:25:39] PHP   1. {main}() /var/www/dbjs.php:0
[22-Sep-2010 18:25:39] PHP   2. handledbrequest() /var/www/dbjs.php:90
[22-Sep-2010 18:44:45] KEN LOG: starting
[22-Sep-2010 18:44:45] PHP Notice:  Undefined variable: reggnames in /var/www/dbjs.php on line 22
[22-Sep-2010 18:44:45] PHP Stack trace:
[22-Sep-2010 18:44:45] PHP   1. {main}() /var/www/dbjs.php:0
[22-Sep-2010 18:44:45] PHP   2. handledbrequest() /var/www/dbjs.php:90

which is correct and dumpfile.txt was also created with the fwrite trace info.

However with reggnames instead of $reggnames:


function handledbrequest ( $con , $reqtp , $sql )
   {
   global $fh;
   $reqnames = array('i'=>'Insert', 'q'=>'Select','u'=>'Update',
                     'd'=>'Delete');
   $error = reggnames[$reqtp] . ' error: ' . mysql_error();
   return $error ;
   } 

nothing was added to /home/ken/myerrorlog.txt and the dumpfile.txt was not created. My guess is that the parser just gives up for this error and abandons execution. Otherwise there should have been a log entry. This error could have been reported by the parser as ‘unknown keyword’ or ‘unknown symbol’ and is no more difficult to detect than a missing $ for a variable. There are probably more cases like this.

Need to sleep on this… (in UK)…

Is there a way to get the parse-time error message always to come out?
Anyone?

  1. http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors
  2. etc/php5/apache2/php.ini

Error_logging works and fopen&fwrite tracing too, except for one case that I found and mentioned in the previous post. There may be more cases, but this will do. A syntax highlighting editor should help catching missing $ signs etc and reduce the instances when the parser fails silently.

Many thanks everyone.

Many thanks for the info.

Using fopen, fwrite worked very well at runtime and put the trace into dumpfile.txt in the web directory var/www. I do not need any more than that for runtime debugging.

I am testing using url localhost/kentest.html with kentest.htmp containing javascript code that builds a query string:

?req=i&sql=INSERT INTO table VALUES(…); that is passed to the php

program. The fwrite php tracing shows that these are passed across ok.

The important missing information now is the parse-time error messages and have not been able to get these to show. I have tried:


ini_set('display_errors', 'On');
error_reporting(E_ALL|E_STRICT);

and


error_reporting(E_ALL);
ini_set("display_errors", 1);
include("file_with_errors.php"); 

with no error info appearing.

I also tried getting the error info to a logfile by:


error_reporting(E_ALL|E_STRICT);
ini_set('display_startup_errors', 0);
ini_set('display_errors', 0);
ini_set('log_errors',1);
ini_set('error_log', '/home/ken/myerrorlog.txt');  // my homedir  

but no logfile was generated. ini_set(‘error_log’, ‘/var/www/myerrorlog.txt’) gave the same negative result.

If the php parser finds an error, stops parsing and abandons execution then the ini_sets would never be called.

What can I do to be able to see the parse-time errors ideally via a logfile of my choice?

Have you tried to do a simple echo at points of your app? Maybe something is getting nulled out, thus not writing a file, but also not throwing an error.