Page 1 of 1

One BIGASS emergency!

Posted: Sat Nov 22, 2003 2:02 pm
by Gen-ik
Ok, I'm half way through one the best bits of website PHP'ing that I've ever done and I'm getting a MySQL error that I can not for the life of me track down.

The error is plain enough... Column count doesn't match value count at row 1 ...but the way that I've designed the 'backend' of the site to work means that I have a shed load of PHP files each with self-contained functions that get loaded into one 'parent' class. Basically I have a lot of pages with a lot of MySQL queries in each page, and the error could be being kicked up by any one of them.

Is there any way I can get PHP to show me which file the error is coming from and what the actual query was?

Any help would be better than a good romp in the sack..................... well almost.

Posted: Sat Nov 22, 2003 5:02 pm
by DuFF
All I know is that error is the result of trying to send more variables then there are columns to fit them in. If you are using 1 class to do the database queries then you could output the query with the error. Here is an example I've seen used in paFileDB:

Code: Select all

<?php
class sql {
        function query($db,$query,$type) {
                $result = mysql_query($query);
                $error = mysql_error();
                if (!empty($error)) {
                        $errno = mysql_errno();
                        $this->error("paFileDB was unable to successfully run a MySQL query.<br>MySQL Returned this error: <b>$error</b> Error number: <b>$errno</b><br>The query that caused this error was: <b>$query</b>");
        }
        function error($error) {
                die($error);
        }
}
?>
But If you are not using 1 class, then I wish you good luck looking through the PHP files :?

Posted: Sat Nov 22, 2003 5:24 pm
by Bill H
Fundamental design error. You have overlooked a process called error handling. At each function call that has the potential to create an error you must place code to handle or at least report the error.

Code: Select all

<?php
     if (mysql_query($Query, $Link) != TRUE)
     {    echo "meaningful statement describing position and nature of error";
     }
?>
That's an oversimplification, but it will give you the idea. The principal applies whether you are using oop, classes or just plain vanilla code.

Posted: Sat Nov 22, 2003 8:55 pm
by sanyuan
If you want to know what file the error is on, you can put another variable in your function...

Code: Select all

<?php
function query($db,$query,$type, $FILE_THAT_RAN_THIS_QUERY) 
?>

Posted: Sat Nov 22, 2003 9:06 pm
by sanyuan
Another neat trick if you are contantly executing same queries from different files is this function...

Code: Select all

<?php
function query($PRESET)
{
$GET_FILES = "SELECT * FROM files";
$GET_MENUS = "SELECT * FROM menus";
/* as many as you want */

if ( $$PRESET )
{
/* Put what ever query handler you have here */
return mysql_query($$PRESET);
}

}
?>
works as query(GET_FILES);

Posted: Sat Nov 22, 2003 11:01 pm
by McGruff
This is something I use for development:

Code: Select all

<?php

$location = __FILE__ . '<br />' . __LINE__ . '<br />';
$query = mysqlQuery($mysql, $this->monitor, $location);

// and the custom function is:

function mysqlQuery($mysql, &$monitor, $location) 
{
    $monitor->setArray('mysql', $location . ' <br /> ' . $mysql);
    
    $query = mysql_query($mysql) or die('sql error: ' . mysql_errno() . ' - '
                                        . mysql_error() . '<br/>' . $location . 
                                        '<br />'
                                        );
    return $query;
}
?>
Every query gets logged in the $monitor object (always available everywhere) and the $monitor object is printed after every script. If a die() is triggered, $location is shown. Hope that gives you some ideas.

Posted: Sun Nov 23, 2003 9:17 am
by Gen-ik
Ok thanks for all of those posts. I guess I really should have thought about using some sort of error catching function but it just slipped my mind.

I did find the problem though, had to 'follow' the path of the code and find out which bit could possibly be screwing up, but it's sorted now.

I think I will take a couple of hours to implement an error catching function though.... just in case it happens again ;)


Thanks.

Posted: Sun Nov 23, 2003 10:04 pm
by Gen-ik
McGruff wrote:This is something I use for development:

Code: Select all

<?php

$location = __FILE__ . '<br />' . __LINE__ . '<br />';
$query = mysqlQuery($mysql, $this->monitor, $location);

// and the custom function is:

function mysqlQuery($mysql, &$monitor, $location) 
{
    $monitor->setArray('mysql', $location . ' <br /> ' . $mysql);
    
    $query = mysql_query($mysql) or die('sql error: ' . mysql_errno() . ' - '
                                        . mysql_error() . '<br/>' . $location . 
                                        '<br />'
                                        );
    return $query;
}
?>
Every query gets logged in the $monitor object (always available everywhere) and the $monitor object is printed after every script. If a die() is triggered, $location is shown. Hope that gives you some ideas.
Hi McGruff. Could you point me towards some info about how the "&" symbol works in the case of your script. Does that setup a global object within the actual class/function.. or am I just completely mad?

Posted: Sun Nov 23, 2003 10:29 pm
by McGruff
I use OOP in all my scripts: the $monitor object is a sort of "global" logging object which is passed to every other script object. $monitor is instantiated early on and passed to other objects by reference. It has to be passed by reference so that all the different objects share the same $monitor.

Once it's in the object, you again pass it by ref to any custom functions by specifying that in the function def.

This, from eclipse docs, explains referencing pretty well:
- To get Java-like object behavior, ALWAYS use references when:
- Creating objects : $object =& new Object;
- Passing objects : function receiveObject(&$object) { //... }
- Returning objects: function &returnObject() { return $object; }

PHP's default behavior is to create copies, which is almost always NOT what
you really want. When some object contains a reference to a second object
and you create a copy of the first object instead of a reference, this copy
will NOT share the reference to the second object, but will hold a copy of
that object instead. This can (and will) lead to strange and undesired
behavior. To summarize:

function &getNiftyComputationResult(&$iterator))
{
$result =& new NiftyComputationResult;
for ($iterator->reset(); $iterator->isValid(); $it->next())
{
$result->add($iterator->getCurrent());
}
return $result;
}

$it =& new ArrayIterator(array(8, 5, 3, 9, 6, 1, 7, 4, 2));
$result =& getNiftyComputationResult($it);

It takes a while to get used to, but it is truly the only way to correctly
handle objects in PHP 4 ('correctly' meaning 'Java-like' in this context).
The $monitor setArray method adds keys to an array - helps to keep the report tidy by putting all the mysql queries together - but it doesn't really matter how you add data.

Posted: Sun Nov 23, 2003 11:41 pm
by sanyuan
Im a little shy for asking this because i have been using php for a while now, but i don't understand the '&' symbol infront of functions and variables.... care to elaborate ?

Posted: Mon Nov 24, 2003 12:19 am
by JPlush76
sanyuan wrote:Im a little shy for asking this because i have been using php for a while now, but i don't understand the '&' symbol infront of functions and variables.... care to elaborate ?
http://perl.about.com/library/phpCR/bl_pass_by_ref.htm