Manager classes for Objects - php

Moving from C#/C++ to PHP OOP has proven a bit problematic as I am not sure it is standard to design the code layout in the same manner. As that is the case, I am curious if the following would be considered problematic or wrong when it comes to PHP.
CDeviceManager class (1 initiated)
CDevice class
Keep a private array of CDevice in the CDeviceManager class
Use public methods to fetch devices, search devices, etc.
The most problematic question however is populating each CDevice from a MySQL Database. Would it be safe to include my Database class directly into CDeviceManager and Populate CDevice Array in CDeviceManager Construct?
A lot of what I have read says it is smart to separate the business logic from the view, where I feel this method would do just that. I have not seen many other projects that appear to use this approach though, why I am worried I may be missing something.

It would be best to separate your business logic from data storage system. I recommend using dependency injection to get your job done. The exact implementation would depend on your needs (and project size), but to get an idea here's would be what I would do:
class CDeviceManager
{
private $db; //holder for your database
private $cdevices = array();
//more properties here
public function __construct(Database $db)
{
$this->db = $db; //database connection has now been injected into your class
}
//more methods here
}
Then somewhere along the line when you create your CDeviceManager object you can inject the database connection.
$cdm = new CDeviceManager( new Database(...) );
Your Database class would likely be a wrapper for PDO or MySQLi or whatever database API you would want to use. You could also go farther and have CDeviceManager implement some kind of interface that relate to various CRUD functions in your database. Best part though, is you can test this a whole lot easier because now you can swap out your database connection with a mock/test database so you don't inadvertently screw up your production database.
$cdm = new CDeviceManager( new MockDatabase(...) );
or
$testdb = new TestDatabase(...);
$cdm = new CDeviceManager( $testdb );
So yes, in the end it is good to separate the database connection from your domain models. Some recommend going even farther and making sure that your domain models are completely ignorant to the storage mechanism in general, this way you could be flexible on your storage system/persistence layer. E.g:
$cdm = new CDeviceManager( new FileRetriever() ); //Maybe you are storing stuff in a flat file
Hope that helps clear things up a little bit.

Related

OOP object models, best practice [duplicate]

I'm not new to PHP or programming at all. But recently I was thinking about website programming in PHP and how easier it was before the OOP. Anyway, I prefer OOP than the old procedural style.
I want to implement a website but it seems I always have to use a global or a static variables. And I'm starting to wonder, how can I do it without those?
Anyway, what I'm talking about is having a class for each "component" of the website.
For example if it was an url shortener website it would be: links, members, database.
What I'm talking about is way more complicated, at least 8 classes.
Anyway, my current approach is the following:
$database = new Database(...);
$links = new Links($db);
$users = new Users($db);
Anyway, for example I want to get all the links a user posted by its ID, I need to use both links and both users components.
Is there any other way I could do this? Any other approach? except passing them as constructor parameters.
You should have the following components:
Business objects, which model and express one particular "thing" in your app:
class Link { ... }
class User { ... }
These don't "do" anything, they're just there to formalise your data structures. These objects have getter and setter methods to get and set individual attributes, which are also validated there:
public function setUrl($url) {
if (!/* validate the URL here*/) {
throw new InvalidArgumentException("$url is not a valid URL");
}
$this->url = $url;
}
Minimum required data is part of the constructor. This ensures your data integrity application-wide. It allows you to assert that when you have an instance of Link, the data expressed by it is minimum valid data for a link.
A database link. Only the bare necessary thing to connect to a database, nothing more, nothing less. A raw PDO or mysqli object will do just fine.
A data-object mapper, which takes a database link and knows how to store business objects in the database and how to retrieve them:
class LinkStorage {
protected $db;
public function __construct(PDO $db) {
$this->db = $db;
}
}
This class has all the various methods of how to retrieve things from your database:
public function getById($id) {
$stmt = $this->db->prepare('SELECT ... FROM ... WHERE id = :id');
$stmt->execute(compact('id'));
if (!$data = $stmt->fetch()) {
throw new RuntimeException("Record with id $id does not exist");
}
return new Link($data['url']);
}
You can have all sorts of different queries encapsulated this way, e.g.:
/**
* Returns all links by a particular user.
* #param User $user
* #return Link[]
*/
public function getAllFromUser(User $user) {
...
}
The usage is then simple:
$db = new PDO(...);
$linkStorage = new LinkStorage($db);
$userStorage = new UserStorage($db);
$user = $userStorage->getById($id);
$links = $linkStorage->getAllFromUser($user);
This kind of code would then be encapsulated in a service class, which holds all the possible "actions" you can do in your app. registerUser(array $data), getLinksOfUser($id), newLinkFromPostData(array $data) etc.
What I've just described is basically the model portion of an MVC-style application. The other two parts would be controllers which call the service methods, and views which output data retrieved from service methods. This approach keeps responsibilities separate and isolated and allows you to put higher-level logic and functionality together like building blocks. Business objects are the lowest building block, their structure needs to be solid and well defined for the rest to work. Data-object mappers just concern themselves with putting those objects into the database and getting them back out again. Services then put all this together in various complex ways and make things happen.
You shouldn't have any cyclic dependencies with this, as responsibilities are well separated. Your individual dependencies may still be somewhat complex. If it becomes too cumbersome to instantiate classes, you'll want to look into Factories:
$factory = new Factory;
$userStorage = $factory->newUserStorage();
All the complexity of instantiation is encapsulated in this factory. One step further are dependency injection containers, who you can configure in, for example, an XML file to specify which class depends on what, and then the DI container will take care of it for you.
I was thinking about website programming in PHP and how easier it was
before the OOP
Well, stick to procedural then. If it is easier to write a well written website in a procedural or functional way then opposed to the ojbect-oriented way. Stick ti what you are used to. OO isn't better then functional. It's just a different approach.
the public void main() in php
In the lanuage Java every piece of software we write has a single entry point. The public void main() method. This method fires up the entire application and passes in the arguments provided on startup. It is also the only exit point in the application. the application ends in this method (unless it crashes).
In php, there is no single entry point. We have a bunch of files that run some scripts that do some more stuff and then somewhere along the line another script decides to return stuff and die();
Dependency injection and how IoC libraries can help
When using dependency injection, it becomes a real pain in the a$$ when creating objects and passing arround the correct instance of a class. We start solving this problem with ugly solutions: Singleton, globals, statics, ... Making our software more and more tightly coupled and harder to maintain.
Inversion of Control can help here. there are some really greate articles on the webz.
You can use autoloading in PHP for a better solution:
http://php.net/manual/en/language.oop5.autoload.php

Looking for a way to handle/approach PHP OOP websites

I'm not new to PHP or programming at all. But recently I was thinking about website programming in PHP and how easier it was before the OOP. Anyway, I prefer OOP than the old procedural style.
I want to implement a website but it seems I always have to use a global or a static variables. And I'm starting to wonder, how can I do it without those?
Anyway, what I'm talking about is having a class for each "component" of the website.
For example if it was an url shortener website it would be: links, members, database.
What I'm talking about is way more complicated, at least 8 classes.
Anyway, my current approach is the following:
$database = new Database(...);
$links = new Links($db);
$users = new Users($db);
Anyway, for example I want to get all the links a user posted by its ID, I need to use both links and both users components.
Is there any other way I could do this? Any other approach? except passing them as constructor parameters.
You should have the following components:
Business objects, which model and express one particular "thing" in your app:
class Link { ... }
class User { ... }
These don't "do" anything, they're just there to formalise your data structures. These objects have getter and setter methods to get and set individual attributes, which are also validated there:
public function setUrl($url) {
if (!/* validate the URL here*/) {
throw new InvalidArgumentException("$url is not a valid URL");
}
$this->url = $url;
}
Minimum required data is part of the constructor. This ensures your data integrity application-wide. It allows you to assert that when you have an instance of Link, the data expressed by it is minimum valid data for a link.
A database link. Only the bare necessary thing to connect to a database, nothing more, nothing less. A raw PDO or mysqli object will do just fine.
A data-object mapper, which takes a database link and knows how to store business objects in the database and how to retrieve them:
class LinkStorage {
protected $db;
public function __construct(PDO $db) {
$this->db = $db;
}
}
This class has all the various methods of how to retrieve things from your database:
public function getById($id) {
$stmt = $this->db->prepare('SELECT ... FROM ... WHERE id = :id');
$stmt->execute(compact('id'));
if (!$data = $stmt->fetch()) {
throw new RuntimeException("Record with id $id does not exist");
}
return new Link($data['url']);
}
You can have all sorts of different queries encapsulated this way, e.g.:
/**
* Returns all links by a particular user.
* #param User $user
* #return Link[]
*/
public function getAllFromUser(User $user) {
...
}
The usage is then simple:
$db = new PDO(...);
$linkStorage = new LinkStorage($db);
$userStorage = new UserStorage($db);
$user = $userStorage->getById($id);
$links = $linkStorage->getAllFromUser($user);
This kind of code would then be encapsulated in a service class, which holds all the possible "actions" you can do in your app. registerUser(array $data), getLinksOfUser($id), newLinkFromPostData(array $data) etc.
What I've just described is basically the model portion of an MVC-style application. The other two parts would be controllers which call the service methods, and views which output data retrieved from service methods. This approach keeps responsibilities separate and isolated and allows you to put higher-level logic and functionality together like building blocks. Business objects are the lowest building block, their structure needs to be solid and well defined for the rest to work. Data-object mappers just concern themselves with putting those objects into the database and getting them back out again. Services then put all this together in various complex ways and make things happen.
You shouldn't have any cyclic dependencies with this, as responsibilities are well separated. Your individual dependencies may still be somewhat complex. If it becomes too cumbersome to instantiate classes, you'll want to look into Factories:
$factory = new Factory;
$userStorage = $factory->newUserStorage();
All the complexity of instantiation is encapsulated in this factory. One step further are dependency injection containers, who you can configure in, for example, an XML file to specify which class depends on what, and then the DI container will take care of it for you.
I was thinking about website programming in PHP and how easier it was
before the OOP
Well, stick to procedural then. If it is easier to write a well written website in a procedural or functional way then opposed to the ojbect-oriented way. Stick ti what you are used to. OO isn't better then functional. It's just a different approach.
the public void main() in php
In the lanuage Java every piece of software we write has a single entry point. The public void main() method. This method fires up the entire application and passes in the arguments provided on startup. It is also the only exit point in the application. the application ends in this method (unless it crashes).
In php, there is no single entry point. We have a bunch of files that run some scripts that do some more stuff and then somewhere along the line another script decides to return stuff and die();
Dependency injection and how IoC libraries can help
When using dependency injection, it becomes a real pain in the a$$ when creating objects and passing arround the correct instance of a class. We start solving this problem with ugly solutions: Singleton, globals, statics, ... Making our software more and more tightly coupled and harder to maintain.
Inversion of Control can help here. there are some really greate articles on the webz.
You can use autoloading in PHP for a better solution:
http://php.net/manual/en/language.oop5.autoload.php

Is separating MySQL code from PHP code a standard, common practice?

I've been told that it's a common practice to separate MySQL code from PHP code, is this true? Is this like a new coding standard? Are there any benefits of doing such?
Can someone direct me what are best coding practices (PHP/MySQL) when writing for masses (open source script for example).
Thanks!
Good question!
I've been told that it's a common practice to separate MySQL code from PHP code, is this true?
absolutely true!
Is this like a new coding standard?
and old old concept. there is no standard, but defacto exists
Are there any benefits of doing such?
many benefits
benefits from de-coupling between Layers.
when business logic is de-coupled from Presentation logic, if requirement changes you can change it easily.
so not only separate sql from php, also separate HTML code from php logic
using sqlMap
in the Java world there is MyBatis SqlMapper. This is very commonly used and this is what you want exactly if you are Java programmer.
But in PHP, hard to find something like MyBatis, the only thing I have found is PRADO http://www.pradosoft.com/
using ORM
ORM = Object Relation Map. http://en.wikipedia.org/wiki/Object-relational_mapping
This is also used. but i don't know there is ORM framework for PHP. if anyone knows, please let me know. #jszobody has suggested http://www.doctrine-project.org/projects/orm.html (Thanks)
thanks.
I've been told that it's a common practice to separate MySQL code from
PHP code, is this true?
I think, you are talking about Loose coupling, Separating your application logic in parts (Building a good architecture), so you can keep things organized, maintainable. Actually, this is too broad discussion and I may not properly describe everything but to answer your question, Yes, it's a good (recommended) practice and a design principle in software development.
In an application, the most important part is the domain/business logic, which serves the application and this should be kept separate from other logics, such as presentation logic (UI). For example, if your application, deals with creating of users, products then you may keep them in a separate place each one as an entity of your application. For example
User management
class User {
public function createUser()
{
// ...
}
}
Product management
class Product {
public function addProduct()
{
// ...
}
}
This are your business logic and you may use/call these from a separate class/place like
$user = new User;
$user->create();
Now, think about the data storage mechanism, if you create a new user, you may need to put all the information in a place, it maybe a database, a flat file or ccould be an xml file, so, what should you do in your createUser() function, you should use a data access layer between your data storage and business logic, which means, whatever data storage you use, you should not use any code in your createUser() function (business logic) directly, instead you access the data storage via another layer (DAL), for example, your createUser() function may look like something like this
class User {
protected $storage = null;
public function __construct($storage)
{
$this->storage = $storage;
}
public function createUser()
{
$userData = $_POST['first_name'];
$userData = $_POST['user_name'];
// more fields...
// data validation
$this->storage->save($userData);
}
}
Now, to create a user and save it in a database, you can use it like
$storage = new DbStorage();
$user = new User($storage);
Maybe, you want to use a flat file to store data instead of a database, no problem, just change the data storage, i.e.
$storage = new FileStorage();
$user = new User($storage);
Now, see the difference, Your save method doesn't know about storage mechanism, it just calls storage->save() and each storage has it's own save mechanism, things are organized, clean and easy to maintain, change the storage mechanism without making any changes in your code. So, it's like
Business Logic --> Data Access layer --> Data Storage
Here in data access layer, you should write code according to your storage mechanism, if you have a database as a storage then you write code according to that and in this case, your DbStorage may have it's own abstract database layer (different drivers for different Database, i.e. mysql, oracle etc), here ORM comes in action.
So, main thing is to keep things loosely coupled, which help you to build a clean and maintainable application. This is a little idea only. These links may help you
Separation of concerns
SOLID
Software design pattern
PHP - The Right Way
Data access layer
ORM
Update : I think I should add a bit about database abstraction layer's example
So, when you use a database for storage mechanism, you may use
$storage = new DbStorage();
$user = new User($storage);
But, this DbStorage should contain another layer for different types of databases, i.e. myaql, oracle etc. In this case, your DbStorage may look like this
class DbStorage{
protected $db = null;
public function __construct($database)
{
$this->db = $database;
}
public function save($data)
{
$this->db->insert($data);
}
}
To use it, you may use code like this
$config = array('hostname' =>'localhost', 'username'=>'root', 'password'=>'123456', 'database'=>'myDatabase');
$storage = new DbStorage(new MySqlDriver($config));
$user = new User($storage);
Or for another database engine, you may use
$config = array('hostname', 'username', 'password');
$storage = new DbStorage(new OracleDriver($config));
$user = new User($storage);
Now, your different database drivers may look something like this
class MySqlDriver(){
public $connection;
public $database;
public function __construct($config)
{
$this->connection = mysql_connect($config['hostname'], $config['username'], $config['password'], $config['database']);
mysql_select_db($db);
}
public function insert($data)
{
// code for insert (mysql)
}
}
For oracle you may have another class as OracleDriver
class OracleDriver(){
// ...
public function __construct($config)
{
// ...
}
public function insert($data)
{
// code for insert (oracle)
}
}
This is just an idea of database abstraction layer and in most cases, configuration for each database (MySqlDriver, OracleDriver) may contain in configuration file, i.e. database.php and it my contains array like
return array(
'mysql' => array(
'hostname'=>'localhost',
...
),
'oracle' => array(
'hostname'=>'localhost',
...
)
);
This is just a rough idea, you may find better examples online and there are lots of open source libraries to use in live projects.
Yeah, this is standard across many programming languages. Typically you would write stored procedures and have your php code leverage those to do the database work. This separation makes it easier to manage your code base and helps with maintenance and extensability.
Don't take this advise too literally.
Because there is no way to follow it.
As you can see, noone provided you with example script. That's quite a problem with this site. Too much knowledge I'd call it. And lack of practice.
So, It cannot be used as a rule of thumb. Using stored procedures, where you can do single primary-key based lookup, is just an overkill. And ORM cannot create whatever complex query for you. So, it's rather good intentions than "coding standard".
Yet there is a rule of thumb you can easily follow: never let your SQL and HTML to meet in a same file. This one is quite easy to follow and way more practical, because you have to change appearance more often than database backends.

PDO objects across classes

I'm looking for some feedback on the following:
I currently have two classes, which are being used in my PHP application.
A database connection class, which is currently using MySQL (but switching to PDO).
Another class (with several functions) which requires database functionality.
I'm looking for the best way to design this, I've read up on singletons (with very mixed reviews), read examples where objects were simply declared as new for each method (class functions), and examples where the connection was assigned to a private variable as part of a __constructor method for each class (then referenced with $this->).
So, how does everyone else do it? I hope you will be kind enough to perhaps give an example, and also welcome opinions on what others have read please.
I've got 2 separate classes, in two separate files. I want to keep clean code, reduce unnecessary overhead on the DB, and avoid anything that could be considered outdated (such as globals).
The Database class, which is responsible for connecting, should be the one connecting to the database, creating the new PDO instance, and saving it to a field in itself.
class Database {
private $pdo;
public __construct() {
$this->pdo = new PDO(...);
}
}
The second class, which doesn't care where the DB connection is from, it just needs it to work should be injected with the Database class:
class WorkerClass {
private $db;
public __construct(Database $db) {
$this->db = $db;
}
}
I've always created it in the __constructor and then used $this-> to get at it. This should work for your needs but I'd encourage you to play around with different styles and see what one works best.
I would NOT create a new object with new every time, unless you have a very good reason to.

PHP - mySQL DB class

I've seen how powerful OOP is in c++ so I started reading up on OOP for PHP. This made me want to revamp one of my sites so it would use OOP PHP to clean up the royal mess that it's in now. I already know the basic concepts of OOP, but I'm struggling a bit with applying it.
So far, all the sites I've seen that use OOP PHP have some sort of mySQL DB class. I can definitely see its benefits (cleaner code when you want to access something in the DB) but I'm not entirely sure how to set mine up. Here's what I'm wondering:
What are the first things I should do
when building this class from the
ground up? (How should this class be
set up? What's the idea behind that
structure? What does it look like
when set up like that?)
What kinds of methods should be in my
DB class? (What kind of functionality
should my DB class offer? SQL
Inserts? SQL Updates? plain ole' SQL
queries? What data should these
methods return?)
How do I determine when I need to add
a new method to the class?
How should I use those methods in my other code?
Thanks.
If you mean a class to connect to the database, prepare and run queries, use PDO (try "Writing MySQL Scripts with PHP and PDO" for a tutorial). If you mean a Data Access Object (DAO), which is a class (or classes) to function as a bridge between the database records and your application objects, try the data mapper or active record patterns. Note that the active record pattern is a little older and falling out of favor with some, so the articles about active record in PHP tend to be older and are a bit out of date.
Whatever pattern you apply, the four basic operations your class(es) should provide are create, read, update and delete (CRUD). Create and read return application objects, and update and delete can return values indicating success or failure.
Using the class(es) is fairly straightforward: whenever you need an object, use create or read rather than the object constructor. When to use update or delete depends on your business logic. For example, you may need to update whenever you're done with an object (i.e. when the object is destroyed). What's trickier is how an object or function gets a reference to DAOs. Reading Martin Fowler's article on dependency injection for a few different approaches.
Further reading:
Persistence Patterns
Practical PHP Patterns: Data Mapper
Implementing the Data Mapper Design Pattern in PHP 5
Implementing The Domain Model: Entries and Authors
Using the Active Record Pattern with PHP and MySQL
There are several ways to go about this, firstly you can "integrate" a system into a native system such as mysqli or you can go about creating your own system / structure from scratch using drivers.
With the first method your a little limited as you have to abide by the internal structure of the native API.
My personal approach is usually the second as i can create a driver based system and decide what native system to use depending on the host operating system and several other factors.
When creating a database API for your applications to run on you do not want it to be specifically for that application, you should be able to grab the libraries drop them into a new project and everything should work as expected, so making it abstract is the first issue we will have to get around.
The next obstacle is to make the code extendible, the programming world changes radically so we should be prepared for changes, although the code would only suffice for a few years, it would be beneficial if we thought about thus years and was prepared.
imagine if next week a new database layer was created that was 50x faster then the current mysql(i) layer that's integrated into PHP, you would want to switch to that api ASAP, thinking about these factors is always a good thought to have during the development stages.
Firstly we should decide on the structure, with traditional abstraction layers the code is usually all built into 1 large class file, this can be bad programming as it should be broken down into its purposes.
We should be separating the classes / objects so that they perform the task there specifically designed for.
We should have 1 global "controller" which would be the main Database Class, this would control all operations sent to and from the sub classes.
We would be designing for PHP 5.3 as minimum, so lets get started:
What i tend to do is create some pseudo code of what the end-result would be like, this way i will have an understanding of what should be implemented.
$Connection = new DatabaseConnectionDetails(array(
"hostname" => "localhost",
"username" => "root",
"password" => "n/a",
"charset" => "UTF-8",
"database" => "my_database",
"driver" => "MySQL",
));
$Database = Database::getInstnace($Connection);
$Query = $Database->Query("SELECT * FROM {?:table} WHERE id = {?:id}",array(
"table" => "posts",
"id" => 22
));
if($Query->Execute())
{
$Results = $Query->GetResults();
foreach($Results as $Result)
{
echo $Result->data; //trims, converts to int, returns;
}
}
This would be how I would like to connect to my database, so this is how I would start working with the base class
class Database
{
private static $_DBInstance;
public static function getInstance(IDatabaseConnectionDetails $ConnectionDetails)
{
if(self::$_DBInstance === null)
{
self::$_DBInstance = new Database($ConnectionDetails);
}
return self::$_DBInstance;
}
public function __construct(IDatabaseConnectionDetails $ConnectionDetails)
{
//We will come back to this.
}
}
Looking at the class above you will see that firstly it has a create instance (singleton) that would help in using the database throughout any application, you would also note that im specifically defining what parameters are required.
Keeping the above factors in place throughout the whole abstraction layer will make life much easier.
Let me just explain a little about the the directory structure, you would have to seperate the following class
Database
Query Classes
Interfaces
Drivers
Helpers
and I would go for a structure a little like so:
includes
DBAL
Database.class.php
DatabaseConnectionDetails.class.php
Drivers
Interfaces
Result
As stated above would require a IDatabaseConnectionDetails interface, the purpose of this is so that the separation of credentials and the main database are made, therefore the IDatabaseConnectionDetails has a primary role of looking after the users credentials.
class DatabaseConnectionDetails implements IDatabaseConnectionDetails
{
public $hostname = "localhost";
public $username = "";
public $password = "";
public $charset = "UTF-8";
public $driver = "mysqli";
public function __construct($params)
{
//Set Params here
}
}
Now the beauty of creating a class for your configuration was mentioned above, the extensibility of the class, for example:
class MyCustomConfig extends DatabaseConnectionDetails
{
public $hostname = "host.domain.tld";
public $username = "my_other_user";
public $password = "IJH87b&OTIT8fh";
public $driver = "mssql";
}
This way as the classes are interfaced you can send any class into the main database object, being custom or not as the interface allows you to be extensible.
Now the drivers that are required, you should note that each driver should be part of an driver interface, that forces a set of methods to be within the driver itself.
interface IDatabaseDriver
{
public function setConnectionDetails(IDatabaseConnectionDetails $ConnectionDetails);
public function connect();
public function escape($string);
public function query($string);
/*
all the methods here that will allow the main class can access, such as:
- next()
- prev()
- reset()
ect ect
*/
}
The main database class would then be able to load the correct driver depending on $Config->driver.
you would create generic functions in the Main Database Class that would mimic a typical database system such as fetchObject,fetchArray() etc, these methods would then use the driver object to select, prepare, sanitize the data and then return the results using another object/class such as QueryResult which would have a set a dedicated methods that are solely for the purpose of traversing a result set.
Hope you enjoyed this long read but should get you started with an idea in your head.
Regards:
Robert

Categories