Jump to content

How can I achieve this in OOP PHP the right way?


mds1256

Recommended Posts

 

Hi

 

Looking to create a web site using php OOP, I understand the concepts of objects and classes etc.

 

But I am wanting to achieve the following:

 

class for retrieving news articles on a website - so I have a news content box that contains around 5 news articles titles that are links to the main articles.

 

 

How would I do this in regard to methods?

 

 

I am thinking:

 

 

functions.php

 


<?php

class functions
{
public static function dbConnect()
{
	mysql_connect('localhost', 'user', 'pass');
	mysql_select_db('database');
}
}


?>

 

 

news.php

 

<?php

class news
{
public function getNews()
{
	$query = mysql_query("select * from news limit 5");
	return $query;
}
}

?>

 

 

index.php

 

<html>
<?php require_once('functions.php'); require_once('news.php'); ?>
<body>
<?php
functions::dbConnect();
$news = new news();
$newsresultset = $news->getNews();

while($row = mysql_fetch_assoc($newsresultset))
{
echo $row['title']."<br />";
}


?>
</body>
</html>

 

 

 

 

 

Is the above the best way to create and use the methods or is there a better way?

 

Thanks

 

 

 

 

 

 

 

 

I understand the concepts of objects and classes etc

 

No, you don't. Compare the below versus your code.

 

class NewsArticles {
    private $db;
    public function __construct(PDO $db) {
        $this->db = $db;
    }
    public function listLatest() {
        return $this->db->query('SELECT * FROM news LIMIT 5');
    }
}

 

$articles = new NewsArticles($pdoInstance);

foreach ($articles->listLatest() as $article) {
    echo $article['title'];
}

 

And ALWAYS separate your presentation (HTML) from your business logic.

 

$smarty = new MySmarty;
$articles = new NewsArticles($pdoInstance);
$smarty->assign('articles', $articles->listLatest());
$smarty->render('template.tpl');

 

template.tpl

<html>
<body>
{foreach $articles as $article}
    {$article.title}
{/foreach}
</body>
</html>

 

Or using PHP as a template engine:

<html>
<body>
<?php foreach ($articles as $article): ?>
    <?=$article; ?>
<?php endforeach; ?>
</body>
</html>

 

 

The above is much cleaner then:

 

<html>
<?php require_once('functions.php'); require_once('news.php'); ?>
<body>
<?php
functions::dbConnect();
$news = new news();
$newsresultset = $news->getNews();

while($row = mysql_fetch_assoc($newsresultset))
{
echo $row['title']."<br />";
}


?>
</body>
</html>

It would be neat to call DB as global

 

global $db;

 

since you would need db for many different classes and methods, and it's a pain in the but to put them in the constructor all the time.

 

Or design an abstract class to extend the db object from.

It would be neat to call DB as global

 

global $db;

 

since you would need db for many different classes and methods, and it's a pain in the but to put them in the constructor all the time.

 

Or design an abstract class to extend the db object from.

 

just...no

I agree it is a pain sometimes, but it's the correct way to do it.

Never use the global keyword.

OT: And by that we mean ALL globals! Even superglobals like _GET and _POST unless the class has been specifically written to deal with them like a HttpRequest class. There are better alternatives than using the 'global' keyword AND not having to pass the db instance with every instantiation, it's called: Dependency Injection and you can find a few good packages on github, I favor those by Fabien Potencier but there are others.

 

Basically they allow you to get an instance of an object without having to worry about passing all the required arguments, something like this (from my earlier example):

 

$smarty = $container['smarty'];
$articles = $container['newsarticles'];
$smarty->assign('articles', $articles->listLatest());
$smarty->render('template.tpl');

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.