Log in

View Full Version : Resolved Fatal error: Call to a member function query() on a non-object



ggalan
05-06-2011, 08:08 PM
im getting an error on this line of code in red, can anyone lend a hand please



<?php

function writeShoppingCart() {
$cart = $_SESSION['cart'];
if (!$cart) {
return '<p class="cartResponse">You have no items in your shopping cart</p>';
} else {
// Parse the cart session variable
$items = explode(',',$cart);
$s = (count($items) > 1) ? 's':'';
//return '<p class="cartResponse">You have '.count($items).' item'.$s.' in your shopping cart</p>';
}
}
function showCart() {
global $db;
$cart = $_SESSION['cart'];
if ($cart) {
$items = explode(',',$cart);
$contents = array();
foreach ($items as $item) {
$contents[$item] = (isset($contents[$item])) ? $contents[$item] + 1 : 1;
}
$output[] = '<div id="formDiv"><form action="cart.php?action=update" method="post" id="cart">';
$output[] = '<table width="100%" height="83" border="0" cellspacing="0" cellpadding="0" class="cartItems">';
foreach ($contents as $id=>$qty) {
$sql = 'SELECT * FROM products WHERE id = '.$id;
$result = $db->query($sql);
$row = $result->fetch();
extract($row);
$output[] = '<tr>';

$output[] = "<td width='80'>\n<a href='product.php?id=".$id."&prod=".$productID."&view=A '>";
$output[] ="<img class='barImg' src='assets/main_small/A_".$productID.".jpg' width='50' height='50' /></a>\n</td>\n";

$output[] = '<td valign="bottom" width="155">';
$output[] = "<ul class='cartDescription'>\n<li class='cartDescript1'>";
$output[] = strtoupper($itemName);
$output[] = "</li>\n<li class='cartDescript2'>";
$str6 = ($productID);
$output[] = strtoupper(substr($str6, 0, 6));
$output[] ="</li>\n</ul>\n";
$output[] = '</td>';

$output[] = "<td valign='bottom' width='160'>\n";
$output[] ="<ul class='cartDescription'>\n<li class='cartDescript1'>";
$output[] = strtoupper($fabricName);
$output[] = "</li>\n<li class='cartDescript2'>";
$str3 = ($rowX['productID']);
$three = strtoupper(substr($str3, 0, 3));
if ($three == "VOY") {
$str3 = $productID;
$output[] = strtoupper(substr($str3, -3));
}else {
$str3 = $productID;
$output[] = strtoupper(substr($str3, -2));
}
$output[] = "</li>\n</ul>";

$output[] = '<td valign="bottom" width="60" ><input type="text" name="qty'.$id.'" value="'.$qty.'" size="3" maxlength="3" /></td>';
$output[] = '<td valign="bottom" width="80" >&pound;'.($price * $qty).'</td>';
$output[] = '<td><a href="cart.php?action=delete&id='.$id.'" class="r">Remove</a></td>';
$total += $price * $qty;
$output[] = '</tr>';
}
$output[] = '</table>';
$output[] = '<p class="totalTxt">GRAND TOTAL</p>';
$output[] = '<p class="totalNum"><strong>&pound;'.$total.'</strong></p>';
$output[] = '<div id="updateBtn"><button type="submit"><strong>UPDATE CART >></strong></button></div>';
$output[] = '<a href="cartCheckout.php "><div id="continueBtn">CONTINUE</div></a>';
$output[] = '</form></div>';
} else {
$output[] = '<p><!--You shopping cart is empty.--></p>';
}
return join('',$output);
}
?>

traq
05-06-2011, 08:32 PM
"non-object" means that the variable ($db) doesn't refer to an object. Did you assign it to your database class (e.g., $db = new databaseClass();, or whatever the class you're using is named)?

ggalan
05-06-2011, 08:33 PM
weird, on my local host i used this and got that error


$host = 'localhost';
$user = 'root';
$pass = '123456';
$name = 'dBnameHere';

$db = mysql_connect($host,$user,$pass);
mysql_select_db ($name);


but on the live server if i used this, it works. but this method gets an error on my localhost - Deprecated: Assigning the return value of new by reference is deprecated


$host = 'localhost';
$user = 'root';
$pass = '123456';
$name = 'dBnameHere';
$db = &new MySQL($host,$user,$pass,$name);

traq
05-06-2011, 10:39 PM
this



$db = mysql_connect($host,$user,$pass);
mysql_select_db ($name);

is _completely_ different than this


$db = &new MySQL($host,$user,$pass,$name);

I'm not sure about how you're using a reference for new. what's the point of that?

anyway:

in $db = mysql_connect($host,$user,$pass);, you're using the variable $db to hold a resource: the connection to your database.

however, in the case of $db = new MySQL($host,$user,$pass,$name);, you're using $db to store an object that you're creating from your MySQL class (which, presumably, creates a connection and has various methods - like query() - that allow you to interact with your database).

This is Object-Oriented Programming, whereas the more direct mysql_connect() method is procedural. OOP is generally more useful in larger, more complex scripts or software packages that are made up of many scripts.

If you're encountering this problem when you try to use it locally (and not on your live server), then code (somewhere) on your live server probably instantiates the MySQL class and assigns it to the variable $db before you try to use it, and that's not happening when you try the script locally.

If you're using a CMS, for example, it might do that somewhere upstream in order to provide a hook for you to use the database with custom or add-on scripts without interfering with anything else the CMS does.

Do you know where your MySQL class definition is?

ggalan
05-06-2011, 11:17 PM
well OOP is definitely where i want to be.
so then how do i get rid of the error message when using this route


$db = &new MySQL($host,$user,$pass,$name);


heres the MySql class



<?php
/**
* MySQL Database Connection Class
* @access public
* @package SPLIB
*/
class MySQL {
var $host; /* MySQL server hostname @access private @var string */
var $dbUser; /* MySQL username @access private @var string */
var $dbPass; /* MySQL user's password @access private @var string */
var $dbName; /* Name of database to use @access private @var string */
var $dbConn; /* MySQL Resource link identifier stored here @access private @var string */
var $connectError;/* Stores error messages for connection errors @access private @var string */

/** * MySQL constructor * @param string host (MySQL server hostname) * @param string dbUser (MySQL User Name)
* @param string dbPass (MySQL User Password) * @param string dbName (Database to select) * @access public */
function MySQL ($host,$dbUser,$dbPass,$dbName) {
$this->host=$host;
$this->dbUser=$dbUser;
$this->dbPass=$dbPass;
$this->dbName=$dbName;
$this->connectToDb();
}

/* Establishes connection to MySQL and selects a database @return void * @access private */
function connectToDb () {
// Make connection to MySQL server
if (!$this->dbConn = @mysql_connect($this->host,
$this->dbUser,
$this->dbPass)) {
trigger_error('Could not connect to server');
$this->connectError=true;
// Select database
} else if ( !@mysql_select_db($this->dbName,$this->dbConn) ) {
trigger_error('Could not select database');
$this->connectError=true;
}
}

/* Checks for MySQL errors * @return boolean * @access public */
function isError () {
if ( $this->connectError )
return true;
$error=mysql_error ($this->dbConn);
if ( empty ($error) )
return false;
else
return true;
}

/* Returns an instance of MySQLResult to fetch rows with * @param $sql string the database query to run * @return MySQLResult * @access public */
function query($sql) {
if (!$queryResource=mysql_query($sql,$this->dbConn))
trigger_error ('Query failed: '.mysql_error($this->dbConn).
' SQL: '.$sql);
return new MySQLResult($this,$queryResource);
}
}

/* MySQLResult Data Fetching Class @access public * @package SPLIB */
class MySQLResult {
/* Instance of MySQL providing database connection @access private @var MySQL */
var $mysql;
/* Query resource @access private @var resource */
var $query;
/* MySQLResult constructor @param object mysql (instance of MySQL class) @param resource query (MySQL query resource) @access public */
function MySQLResult(& $mysql,$query) {
$this->mysql=& $mysql;
$this->query=$query;
}
/* Fetches a row from the result @return array @access public */
function fetch () {
if ( $row=mysql_fetch_array($this->query,MYSQL_ASSOC) ) {
return $row;
} else if ( $this->size() > 0 ) {
mysql_data_seek($this->query,0);
return false;
} else {
return false;
}
}
/* Returns the number of rows selected return int @access public */
function size () {
return mysql_num_rows($this->query);
}
/* Returns the ID of the last row inserted @return int @access public */
function insertID () {
return mysql_insert_id($this->mysql->dbConn);
}
/* Checks for MySQL errors @return boolean @access public */
function isError () {
return $this->mysql->isError();
}
}
?>

ggalan
05-07-2011, 12:39 AM
the error


Deprecated: Assigning the return value of new by reference is deprecated


seems to be because of xampp - php 5.3, i need to revert to 5.2

traq
05-07-2011, 01:03 AM
as I said above, I had _never_ seen that before, not even in php4 versions of Object-Oriented scripts (which, apparently, is where that comes from). After some research, I still can't determine what the point of doing it that way was in the first place.

recommendations:

1) if you have access to all the scripts that use this construct, I would seriously consider removing them all (replacing every $var = &new class(); with $var = new class();). Things like this get marked "depreciated" because they cause problems, or are not forward-compatible. It would be preferable to not rely on them. In this case, I can't find any indication that the changed syntax changes how the class is instantiated:

in PHP5 you generally don't need the reference operator -- at all -- when dealing with class objects, because PHP5 implements objects using Instances (which are more like C pointers than PHP's references system).

2) change your error reporting settings to ignore this error (which is actually an E_STRICT warning, not an error).

in any case, I would strongly recommend that you do not downgrade your version of PHP. It is always best to use the most current version, for security, performance, and a host of other reasons.

djr33
05-07-2011, 01:05 AM
It means that you should not be using that because it is now not recommended. You could turn off warnings like that, but the quality of your programming would be lower if you don't fix them.

The problem seems to be &new vs. new. Can you remove the & and see if it works?


[Posted at the same time as traq.]

ggalan
05-07-2011, 01:14 AM
so you think i should test localhost on php 5.3 even tho my live server is running 5.2?

djr33
05-07-2011, 01:26 AM
No. You should probably run the same versions on both servers. Personally I like to test on the live server to be sure it will work.

However, BOTH servers should be upgraded to the newest version of PHP. At least 5.3 is better than 5.2. (I don't know if you want PHP 6 yet.)
If you don't have access to change the PHP on your server or if you have old scripts that might break in the update, this is a good reason not to update. But if you can update, it's probably best.


There are also other reasons to update:
1. It is a good idea to learn with the newest trend and not learn any old bad habits.
2. If you want your software to be portable (so that others can use it) it is worth remembering that different versions exist. This means that you should be aware of different versions and make it compatible with at least the newest version, and maybe other older versions too (but not at the expense of the newest version).

ggalan
05-07-2011, 01:30 AM
1. It is a good idea to learn with the newest trend and not learn any old bad habits.
this is definitely my biggest concern but i take care of a handful of projects that are on shared servers. most are on 5.2 so i think i will use the same on localhost for now

traq
05-07-2011, 02:52 AM
If you're stuck with a particular version of PHP (i.e., on a shared server), then there is good cause to revert your local development version.

However, even in 5.2, using a reference to instantiate a class was not proper procedure - it just threw a notice, rather than a warning (which probably never made it to your screen). I can't find anything to indicate that it was ever used in any 5.x version; the only mentions I've found seem to place it in version 4, when OO programming was just being introduced to PHP (and not very well, to be blunt).

all in all, it just doesn't make any sense: the reference operator means you intend to work with the same contents as that which you're referencing. for example:

$myvar = 'value';
$urvar = $myvar;
$myref =& $myvar;

print $myvar."\n".$urvar."\n".$myref;
// prints:
// value
// value
// value

$myref = 'other value';

print $myvar."\n".$urvar."\n".$myref;
// prints:
// other value
// value
// other valuein this example, $myvar and $myref literally share the same value (not identical values, but actually two names for one box, as it were), whereas the value of $urvar is simply identical to $myvar (at the time it was assigned: it's a "copy").

doing this when creating a new class instance is pointless because there is no existing value to reference: as the keyword implies, the class instance is "new."

As I said, I'm just discovering this issue, so I may not have a complete grasp of it, so I'm sorry if something I'm going on about isn't quite right.

</tangent>

In any case, it seems the problem you actually had is solved. :)

ggalan
05-09-2011, 11:52 PM
The problem seems to be &new vs. new. Can you remove the & and see if it works?

i removed the & and that got rid of the error in php 5.3

traq
05-10-2011, 12:58 AM
did it have any negative effect, or any other effect, on code execution under v5.2 (I can't imagine it would, but in the interest of thoroughness)?

ggalan
05-10-2011, 02:25 AM
it worked fine i both 5.2 and 5.3. ive never seen that & sign used in conjunction with a new , was that something common in previous versions of php?

traq
05-10-2011, 03:55 AM
I'd never seen it before, either. I suspect (though I really don't know) that it was simply an early method of instantiating an object from a class, and was later made obsolete (perhaps due to a change in the object constructor model), but retained for backwards-compatibility. Whether or not it ever had any functional difference is another matter.

as a side note, $var =& new object(); and $var = &new object(); are equivalent statements (as would be $var=&new object(); - because of how PHP parses whitespace).
i'd say the former is how it "should be" ("should have been"?) done, and the latter (from your script) is an oddity.