Brianna Vay Brianna Vay - 7 months ago 9
SQL Question

PHP class providing empty object

My index.php page had this code that defaults the user to the homepage.

<?php
require_once ( "config.php" );
$action = isset( $_GET['action'] ) ? $_GET['action'] : "";
switch ( $action ) {
case 'seeAll':
seeAll();
break;
case 'viewResource':
viewResource();
break;
default:
homepage();
}

function homepage() {
$results = array();
$learnData = Resource::getHomePageTiles( 'learn' );
$practiceData = Resource::getHomePageTiles( 'practice' );
$elseData = Resource::getHomePageTiles( 'else' );
$results['learn'] = $learnData;
$results['practice'] = $practiceData;
$results['else'] = $elseData;
$results['pageTitle'] = "Couch To Code";
require_once ( "templates/homepage.php" );
}


Which calls the getHomePageTiles method of my Resource class.
Here is the code for the Resource class and getHomePageTiles method.


class Resource {
public $id = null;
public $title = null;
public $summary= null;
public $url = null;
public $content = null;
public $category = null;
public $is_free = null; //????
public $is_featured = null;
public $is_favorite = null;
public $date_created = null;

public function __construct( $data ) {
if ( isset ( $data['id'] ) ) $this->id = (int) $data['id'];
if ( isset ( $data['title'] ) ) $this->title = $data['title'];
if ( isset ( $data['summary'] ) ) $this->summary = $data['summary'];
if ( isset ( $data['url'] ) ) $this->url = $data['url'];
if ( isset ( $data['content'] ) ) $this->content = $data['content'];
if ( isset ( $data['category'] ) ) $this->category = $data['category'];
if ( isset ( $data['is_free'] ) ) $this->is_free = (int) $data['is_free'];
if ( isset ( $data['is_featured'] ) ) $this->is_featured = (int) $data['is_featured'];
if ( isset ( $data['is_favorite'] ) ) $this->is_favorite = (int) $data['is_favorite'];
if ( isset ( $data['date_created'] ) ) $this->date_created = date("Y-m-d H:i:s");
}

public static function getHomePageTiles( $type ) {
global $DB_HOST;
global $DB_NAME;
global $DB_USERNAME;
global $DB_PASSWORD;
$conn = new mysqli( $DB_HOST, $DB_USERNAME, $DB_PASSWORD, $DB_NAME );
if (mysqli_connect_errno()) {
printf("Connection to the database failed: %s/n", $mysqli -> connect_error);
exit();
}
$sql = "SELECT * FROM resources WHERE category = ? ORDER BY position ASC LIMIT 4;";
if ($st = $conn->prepare( $sql )) {
$st->bind_param( "s", $type );
$st->execute();
$list = array();
while ( $row = $st->fetch() ) {
$resource = new Resource( $row );
$list[] = $resource;
}
$conn = null;
return $list;
} else {
printf("Errormessage: %s\n", $conn->error);
}
}


My Homepage.php file has the following code in it

<?php
foreach ( $results['learn'] as $learnTile ) {
print_r($learnTile);
?>
<div class="col-md-3 col-xs-6 featured">

<a href=".?action=viewResource&amp;resourceId= <?php echo($learnTile->id)?> ">
<img src="#" class="thumbnail img-responsive">
</a>
</div>
<?php } ?>


The code is pulling the correct number of Resource objects, but something is going wring, because my link (in homepage.php) is not pulling in the id from the Resource object.

So, to debug i've printed out ($learnTile) and am getting empty objects/arrays.

Resource Object ( [id] => [title] => [summary] => [url] => [content] => [category] => [is_free] => [is_featured] => [is_favorite] => [date_created] => ) Resource Object ( [id] => [title] => [summary] => [url] => [content] ...


Where am I going wrong? is my constructor not working? Clearly the Resource objects are pulling the null values from the original property definitions to null.
I've been stumped on this one for several days so any help / guidance is appreciated. Thanks!

Answer

There is never an array inside the $row. See the manual: php.net/manual/en/mysqli-stmt.fetch.php it returns a boolean only. You should bind your result when using prepare.