Hoping someone can help me with some sample code… I’m looking for the neatest way to write the class to power the following @while@ loop:
bc. $opml = new OPML_Parser;
$opml->load(’http://blo.gs/2650/mySubscriptions.opml’);
$opml->parse();
bc. while($blog = $opml->getBlog()) {
// Check if already entered in database. If so, update
if ($blog->exists()) {
$blog->update();
} else {
// If not, store it.
$blog->save();
}
}
How do I return an instance of a class for each blog? And keep track of them (so the while loop will exit correctly)? The only way I can think of is to put all the objects into an array, and then loop over it; but this doesn’t sound to be the correct way to do it.
5 comments ↓
bq. “The only way I can think of is to put all the objects into an array, and then loop over it; but this doesn’t sound to be the correct way to do it.”
Personally think that’s the right way to do it, but you can keep the array inside you OPML_Parser class e.g.;
class OPML_Parser {
var $blogs = array();
function getBlog() {
$blog = each ( $this->blogs );
if ( $blog ) {
return $blog['value'];
} else {
reset ($this->blogs);
return false;
}
}
}
The only downside with that is if you somehow end up with a value in the blogs array which is itself false.
There’s more discussion “here”:http://www.phppatterns.com/index.php/article/articleview/50/1/1/ by the way plus another iterator (which needs a do/while loop) that solves the issue of false values.
One other thought is you might consider only creating the instance of the Blog class when the getBlog method is called, the internal array $blogs itself containing arrays which store the data that needs to be put in a Blog object (”a factory method”:http://www.phppatterns.com/index.php/article/articleview/49/1/1/). This may have some performance advantages, depending on the problem.
Thanks Harry.
In this situation I think creating all objects at the beginning will be most efficient, as that means the database connection can be closed faster.
With things like database connections, is it best to pass a database object by reference into every class when instantiated; or use a singleton method to create/fetch the existing database connection in each class? I’m guessing it’s the latter, as that means the classes are more independent, and it saves writing
bc. $foo = new Bar($db);
always!
“With things like database connections, is it best to pass a database object by reference into every class when instantiated; or use a singleton method to create/fetch the existing database connection in each class?”
Don’t think there’s any right or wrong; many things come into play, first and foremost what you prefer to work with. One thing I do think is probably “wrong” is having a database object “pass through” another object which doesn’t need to use it, just so that it can to the object that really wants it.
Perhaps what works nicely is to use a singleton style for code which requires data but has another class do the work of fetching it for it. Better to have an example;
class ModifyAccountForm extends PostForm {
function init() {
// Get the db connection
$db = & DBManager::getConnection();
// Object for fetching Account data
$accData = & new AccountData(&$db);
$this->view = & new Template(’accform.tpl’);
// etc.
}
}
I’d replace
while($blog = $opml->getBlog()) {
with
$blogs = $opml->getBlogs();
foreach($blogs as $b) {
Write a new method getBlogs() just like getBlog() but returns an array of blog objects. This way should also save you quite a few queries.
Thanks John, that’s the way I’m doing it at the moment. While it might use more memory, and in “Harry Fueck’s”:http://phppatterns.com opinion not be so good because it involves looping over the results twice, it’s one heck of a lot easier to code!
Leave a Comment