Jump to content
Larry Ullman's Book Forums

Mysqli_Fetch_Object Error


Recommended Posts

Hey, everybody.

 

I'm using the function mysqli_fetch_object. This function is returning objects of the Class stdClass by default. (Main object class if I'm not mistaken).

 

The function has an optional parameter "class_name". This gives you opportunity to specify a class the object should be of. (A Season, Player, Team or any other class)

 

The problem is that mysqli_fetch_object is not returning anything if I specify a Class name. Do anyone know if this is a common problem or maybe a host issue? My host is running Version 5.2.17.

 

I have two classes and a main/run file to demonstrate this. Season class initializeses Season Objects, and SeasonList Class adds objects to an array. The Classes are simplified by removing checks/etc.

 

Class Season:

<?php

class Season {

// Object variables
private $id;
private $season;

// Create Season Objects. Checks are removed for simplicity here
public function __construct($id, $season) {
  	 $this->id = $id;
  	 $this->season = $season;
}

// Standard toString method for printing out objects.
public function toString() {
	return $this->id . ' - ' . $this->season . '<br />';
}

}

?>

 

Class SeasonList


<?php

class SeasonList {

// Object variables
private $seasonList = array();
public static $arrayPointer = 0;

   // __NOTE stdClass here__.
public function addObject( stdClass $object ) {
   $this->seasonList[self::$arrayPointer] = array($object);
	self::$arrayPointer++;
}

// Return the array (hopefully) filled with Season objects
public function getAllSeasons() {
	return $this->seasonList;
}

}

?>

 

Run file season_test.php:

<?php

include("db.php");

$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); // from db.php
$mysqli->set_charset("utf8");

// include the classes
include("SeasonList.php");
include("Season.php");

// Initialize a SeasonList Object
$seasonList = new SeasonList();

// Create query to get Seasons from DB
$query = "SELECT id, seasons AS season FROM abc_seasons";

if ($result = $mysqli->query($query)) {

while ($obj = $result->fetch_object()) {
	$seasonList->addObject($obj);
}

}

// Print_r on the SeasonList Array to check that data is there
print_r($seasonList->getAllSeasons());

?>

 

This produces this result: (And this is correct)

Array
(
[0] => Array
	(
		[0] => stdClass Object
			(
				[id] => 1
				[season] => 2009/10
			)

	)

[1] => Array
	(
		[0] => stdClass Object
			(
				[id] => 2
				[season] => 2010/11
			)

	)

[2] => Array
	(
		[0] => stdClass Object
			(
				[id] => 3
				[season] => 2011/12
			)

	)

[3] => Array
	(
		[0] => stdClass Object
			(
				[id] => 4
				[season] => 2012/13
			)

	)

[4] => Array
	(
		[0] => stdClass Object
			(
				[id] => 5
				[season] => 2015/16
			)

	)

[5] => Array
	(
		[0] => stdClass Object
			(
				[id] => 6
				[season] => 2015/16
			)

	)

)

----------------------------------------

 

If I change to $result->fetch_object('Season') however, I get NOTHING. This is Ok as the Method addObject expects a stdClass object. However, If I change that to "Season", it's still not working.

 

This may seem like a small problem, but really, it's not. I only want to add Season objects to the array. I also just want to know why this is not working. *Pulling hair*

 

Thanks for any help. :)

Edited by Antonio Conte
Link to comment
Share on other sites

Your season object constructor is expecting 2 parameters $id and $season.

 

The fetch_object method takes a second (when using OOP style) parameter for the object constructor:

 

object mysqli_result::fetch_object ([ string $class_name [, array $params ]] )

 

However, you don't really need to set id and season through a constructor in your season object, they'll be set as object properties anyway.

Link to comment
Share on other sites

Did you remove stdClass from SeasonList::addObject when specifying 'season' as the name of the class to instantiate, set the properties of and return?

 

public function addObject( stdClass $object ) {

 

I get a blank screen with error reporting off if stdClass is not removed.

Link to comment
Share on other sites

Yes. I changed it to:

 

$result->fetch_object('Season'))

And

 

public function addObject( Season $object ) {  }

 

 

The reason why I specified stdClass i only because mysqli_fetch_objects returns an object of that class by default. This is the only way I've got it working. If I use any class_name as parameter, the script is not working. This is what I found weird. :/

 

Edit:

 

The parameter actually works if I use 'stdClass' as the class to return an object from. Weird. That means it's nothing wrong with the parameter in my php version at least.

 

$result->fetch_object('stdClass'))

Edited by Antonio Conte
Link to comment
Share on other sites

It returns nothing. Blank. If I use 'stdClass', objects are returned. If I try 'class', 'abc' or 'anything', it does not work. I've tried to use the $params array as a second parameter. That is also failing, even with 'stdClass' as the first parameter. If I use $params as the only parameter, an empty array is returned.

 

I found a solution, though: (With fetch_object)

 

	
while ($obj = $result->fetch_object()) {
    // $my_obj = new Season($obj->id, $obj->seasons);
    // $seasonList->addObject($my_obj);
    // Shorter
    $seasonList->addObject( new Season($obj->id, $obj->seasons) );
}

 

And the same with fetch_array:

 

	
while ($obj = $result->fetch_row()) {
    // $my_obj = new Season($obj[0], $obj[1]);
    // $seasonList->addObject($my_obj);
    // shorter
    $seasonList->addObject( new Season($obj[0], $obj[1]) );
}

 

It makes sense that this works. I really don't understand why I can't use the parameter, though. I think I like this second version best. It will allow me to reuse this syntax with all classes, only changing the parameter list for the object to be created and the name of the Class to instantiate objects from. :)

 

As for overhead, etc. The fetch_array() may be faster, or what do you think, Larry/rob?

 

Both tricks return this:

Array
(
[0] => Array
	(
		[0] => Season Object
			(
				[id:private] => 1
				[season:private] => 2009/10
			)

	)

[1] => Array
	(
		[0] => Season Object
			(
				[id:private] => 2
				[season:private] => 2010/11
			)

	)

[2] => Array
	(
		[0] => Season Object
			(
				[id:private] => 3
				[season:private] => 2011/12
			)

	)

[3] => Array
	(
		[0] => Season Object
			(
				[id:private] => 4
				[season:private] => 2012/13
			)

	)

[4] => Array
	(
		[0] => Season Object
			(
				[id:private] => 5
				[season:private] => 2015/16
			)

	)

[5] => Array
	(
		[0] => Season Object
			(
				[id:private] => 6
				[season:private] => 2015/16
			)

	)

)

 

Larry: In Java, you can use Class hinting.

 

$my_object = (Season) $obj;
print_r($my_obj);

 

Can you do something like this in PHP? That might solve my problems.

It would make sense, as all classes are children of stdClass? (I think). Just wondering.

Link to comment
Share on other sites

I believe you can do class type hinting in PHP. The real question is why your code isn't working. I just looked at some code I did a month or two ago that used fetch_object() and it fetched objects of a specific type without a problem (not stdClass). Do me a favor and see what happens if you make the Season variables public. I'm wondering if the constructor is not being called when the objects are created in this way.

 

As for stdClass, in other OOP languages, it would be make sense that all classes are children of stdClass, but my suspicion is that's not the case in PHP, as OOP has existed in PHP for years and the stdClass is a rather new construct. And, I believe, stdClass is part of the standard PHP library, not part of the true PHP core.

Link to comment
Share on other sites

 Share

×
×
  • Create New...