...

View Full Version : Class inside a class



Dat
04-01-2010, 03:28 AM
I know this wont work but in a set of minds how can I get a class to be included inside a class? or how do i get a class to work inside a class?


class BlogPost
{
include ('database.php');
$db = new database;
}

MattF
04-01-2010, 03:33 AM
Initialise the database class before this one and pass it in when you initialise this class.



$blogpost = new BlogPost($db);

class BlogPost
{
private $database = '';

function __construct($database)
{
$this->database = $database;
}
}

Fou-Lu
04-01-2010, 04:34 PM
Initialise the database class before this one and pass it in when you initialise this class.



$blogpost = new BlogPost($db);

class BlogPost
{
private $database = '';

function __construct($database)
{
$this->database = $database;
}
}


This is how I'd do it as well. I try to limit object coupling as much as possible, so passing a parameter in makes the most sense.
What I can suggest (when you're OO skill is a little more advanced) is to interface whatever is being passed in. This allows you to guarentee (minus a bug, I won't go into that) that all methods are available in the given class. This only works for a more pure OO approach, where the parameter is also an object:


interface IStorage
{
public function connect(....);
public function select(....);
//....
}

class XMLFileDriver implements IStorage
{
public function connect(...)
{
// Open a file, maybe a domdocument, whatever
}
public function select(...)
{
// yeah, actually the dom would be great for selections
}
}

class BlogPost
{
private $database = '';

function __construct(IStorage $database)
{
$this->database = $database;
$this->database->connect(...);
}
public function getBlogPost($maybeAnIDHere)
{
$qry = $this->database->select(array('*'), 'Post', $maybeAnIDHere);
$sResult = '';
if ($qry)
{
$sResult = $this->database->fetch($qry); // Assume we have a fetch
}
else
{
$sResult = 'No match';
}
return $sResult;
}
}

$blogPost = new BlogPost(new XMLFileDriver('/path/to/XML.xml'));
print $blogPost->getBlogPost(1);


Does that make sense? Its a little trickier to follow, but in the above we made a storage device, using an XML file for this example, selected from it and returned the blogPost. Now the above is a completely incomplete representation, its mearly to show the idea of datatyping (or TypeHinting in PHP) to ensure that the IStorage interface has the connect, select and fetch methods. It doesn't matter at this point what the IStorage represents, it can be flat, XML, databases, stdin, whatever you want.


Also, I thought this was refering to nested classes when I read the title:


class A
{
class B
{
}
}

PHP does not support nested or inner classes.

Dat
04-15-2010, 08:35 PM
Is it wise for me to just simply use a global?

include ('crud');

$db = new database();

class BlogPost
{
global $db

}

Fou-Lu
04-15-2010, 08:50 PM
No, globals should only ever be used when the signature of a method cannot be changed.
PHP has the benefit of plain text interpreted code, but in a language like C with poor documentation thats using global variables, there is no easy way to determine what that variable name is supposed to be. And since global always requires that the names match, it makes it impossible to debug. Always avoid global unless absolutely necessary.

A situation where global is used where I would consider it valid is in set_error_handler. Say you want to log this to a file, but don't want to constantly open and close it when an error is created. Error handler signature for its function pointer is: int handler(int, string, [string, [int, [array]]]);. There is no way to add file handle into this function pointer, so the only option is to globalize it within the function you create itself.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum