Is this good practice for encapsulation in PHP? - php

For instance i have class say that runs MySQL query and i want to encapsulate this class.
class SqlQuery {
private $database_connection_obj;
public function __construct($dbh) {
$this->$database_connection_obj = $dbh;
}
public function runQuery($query, $params) {
//run query implementation...
}
}
Encapsulation and information hiding means that i want to close direct access to class methods so function runQuery() should not be public so i make it private and add method exacuteQuery() with sole purpose to pass data to private function runQuery().
What is the practical use of doing so, because at the end it works exact same as code above.
Should there be some sanitation of input data done in public method before its passed to private method or why write this extra code at all?
class SqlQuery {
private $database_connection_obj;
public function __construct($dbh) {
$this->$database_connection_obj = $dbh;
}
public function exacuteQuery($external_query, $external_params) {
$this->runQuery($external_query, $external_params);
}
private function runQuery($query, $params) {
//run query implementation...
}
}

The main idea is to make classes look like black boxes, meaning that an outsider (namely, another class or function holding an instance of the class) has no idea how it works internally. It's abstract to them.
The internal workings of the query are of no importance to the class holding the query and calling ->run(), it only cares about the query running, not necessarily how or where it runs.
Note that a query specifically is quite the low level abstraction, it's relatively close to making direct calls to standard library functions/objects. But given that low level abstraction, you can make higher level abstraction.
For example, a UserStore, that internally uses SqlQuery objects to get and set User objects into the database. A class using UserStore isn't aware that UserStore is using SqlQuery objects internally, it just knows that it's an object that can save and retrieve User objects.
This sort of "hiding away" and "encapsulating" actually gives you a lot of power, because now classes can use other classes without depending on specific implementation details. If tomorrow you'd like to change the way you store Users, you just make a change to the UserStore class, as long as it has the same public API, the rest of your application wouldn't even be aware that something changed.

Given details has no difference, but it depends upon work. I use it much times when i have to make a function which cannot be access directly but only by the method for its use. It optimize the code and deny access outside the code. Otherwise any one can alter the parameters which can be harmful.

Related

PHP Class variables between instances

Recently I have starting trying to do more OOP based programming as I know it's way better than procedural programming but I have a probably simple question. If I want to implement a "tasks" class where each tasks has a title, description, how far completed it is and who submitted it. I have the following code to create the class:
class Tasks
{
public $title;
public $description;
public $completionPercent;
public $contact;
public function __construct($title, $description, $completionPercent, $contact)
{
$this->title = $title;
$this->description = $description;
$this->completionPercent = $completionPercent;
$this->contact = $contact;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCompletionPercent()
{
return $this->completionPercent;
}
public function getContact()
{
return $this->contact;
}
public function setTitle($title)
{
$this->title = $title;
}
public function setDescription($description)
{
$this->description = $description;
}
public function setCompletionPercent($completionPercent)
{
$this->completionPercent = $completionPercent;
}
public function setContact($contact)
{
$this->contact =$contact;
}
}
My question is if I create a tasks and then access it later as in close the browser and then come back to it a few days later when I have an update to it how do I store it and re-access it. I understand databases and use them very often in my current sites I am using to learn but I don't see how storing the information from the class in the database would be logical when I assume you could just skip the class and utilize the database. I read that you could serialize or store XML/json in a file and access the class that way but again I don't see why you would need the class if you could just read a file into an array and use it that way. I know OOP is important but I am still just trying to get it down to where I can start using classes regularly so that I can get familiar with them and progress as a programmer. I am sure there is plenty of reading out on the net about his but I just keep finding stuff on storing class variables in session variables which is not exactly what I want. Let me know if there is something I can clarify, I know when I first make the class I would do something like $task1 = new Task(...); but after closing my browser and logging back in I am not able to still access $task1 correct? I cannot just do $task1->getTitle(); so how do I re-initialize the class?
Classes and objects help you organise your code and logic into self contained units. That is all. And that is very important. It does not address the issue of storage or anything else.
Yes, you would still store the data of the object in the database, and then read again from the database and create an object instance again.
input → new Task(..) → store object data in database
read data from database → new Task(..) → display on website
Why is this better than working with arrays from the database directly? Because it allows you to organise your code better. Even if the object's lifetime is just a fraction of a second, within that fraction all the code that uses the object can be written much more elegantly and most of all type safe, because it is clearly defined what that object looks like. An array is an untyped grab bag of stuff which is hard to work with the more complex your application becomes. Especially refactoring code which uses only arrays is very very hard.
You are right, you need to store such information somewhere, and right place for that is db. So, question is: why you need to use and create class "Task" if you can directly save it in db. Because you want to build application based on "classes and objects", so not to use procedural programming, as you said. Therefore, you need to use objects and create classes for everything in order to have fully OO application.
So, your application should be based on classes/objects and this is what you and some other developers will work with. Now you just need to save this data from that object into the database. That means, you need introduce some additional layer for this. One very nice is Doctrine ORM. It does mapping and translate your object into db. Usually each class has its own table in db and each field in the class has its own column in db (this is only for classes which need to be saved in db)
The point is, that you can easily use objects in your application like any other objects without knowing how they should be saved in db (or somewhere else). Only what you need to do is:
$task->save();
and that's it. That task will be saved in db.

Do interfaces just DESCRIBE what implemenations need to do?

I'm just learning about PHP's interfaces as I have never really used them before, but as I understand it they are only a interface, as they are called, to kind of uphold how classes that implement them are structured?
So for example, if you wanted to make two different classes for two different databases you could do:
class mysql {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...and that would technically be the same as:
interface database {
public function connect() {
}
public function getData() {
}
}
class mysql implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB implements database {
public function connect() {
// code here
}
public function getData() {
// code here
}
}
...am I right? It's just that using an interface it makes sure you don't go doing something like the below and hence not being able to change databases easily?
class mysql {
public function connect_mysql() {
// code here
}
public function getData() {
// code here
}
}
class mongoDB {
public function connect_mongo() {
// code here
}
public function getData() {
// code here
}
}
Is that pretty much the reasoning behind them?
What the interface does is it standardises what your code can rely on, and at the same time decouples that from a specific implementation. Wow, that sounds complicated. It's easier to illustrate it from the perspective of a user of interfaces:
function (MyDatabaseInterface $db) {
$db->connect();
$db->getData();
}
Type hints are a big part of using interfaces. This function declares that its argument must be an instance of MyDatabaseInterface, in other words, any object that implements MyDatabaseInterface. It is entirely up to you what specific object that is, as long as it implements MyDatabaseInterface. And since in MyDatabaseInterface you have specified the methods connect() and getData(), you can be sure that any object being passed in has these methods and that you can call them.
The other way around, have a look at this function:
/**
* #return MyDatabaseInterface
*/
function foo() {
...
}
It is irrelevant what this function does internally, but it declares that it will return an object of type MyDatabaseInterface, in other words some object that implements MyDatabaseInterface. When you call it, you know what you can rely on:
$bar = foo();
$bar->connect();
$bar->getData();
This function may return an instance of mysql or of mongoDB, it is none of your concern. You simply stick to what was declared in the interface and your code will work regardless of what specific object you get.
An interface literally defines the interface between code. It defines what methods code can safely call on other code, without tying down the specifics to specific classes. Your specific objects could define a ton more methods than are defined in the interface; an interface does not declare a class structure. A class could implement several interfaces at once, meaning it implements all the methods of all the interfaces; each individual interface would then just represent a subset of all the possible methods that could be called on an object.
You should describe specific "tasks" or "abilities" which can be accomplished in an interface, not "classes". It's a good sign if your interface names end with "-able", like Iterable. A class can then implement several interfaces and thereby describe all the things it "can do". You can then require function arguments with a certain "ability" at specific points, as shown in the example code above. This isolates and decouples parts of code from one another, which makes your code more flexible, reusable and adaptable to change.
For a useful real world scenario, imagine a larger development team which is working on a large project. There are several sub-teams, each responsible for a different part of the application. They all sit down together and come up with a general plan. At some point, the code of these separate teams needs to interact with each other. They can define these interfaces upfront:
"I'll need to call some method on your code that gives me the user credentials."
"OK, then you'll need to give me some object from which I can get the foobar."
"Then over here we'll have to talk to Joe's component to send the baz data."
...
They can define the different methods they will need to talk to each other in an interface before any code has been written, then go off and do their own thing. They can rely on code which hasn't even been written yet, because they already decided on what the interface will look like. They can even substitute the real code with mock objects for the time being while Joe is still hammering out his real code, then simply switch it in later with whatever Joe comes up with. And all those techniques are useful even if you're just working by yourself.

multiple functions is one big function in PHP?

so I'm writing DataBase class which will be an encapsulation layer between PHP Controller and MySQL View.
interface iDataBase {
public function drug($action, $drug);
public function company($action, $company);
public function activeIngredient($action, $activeIngredient);
}
At First I thought of making all setters and getters seperate like getAllDrugs(), updateDrug(), removeDrug(), getForUpdate(), getDrug() and so one, but then I realised that I was polluting database interface with too much functions, plus this is a very small-scale version, I'm considering adding much-more classes and much more functionality. So, instead of using a lot of function I just setteled for 3. $action will determine what kind of thing does user want to do with certain class. so, for now, possible actions are these: "add", "getAll", "getForUpdate", "update", "remove"
but these functions masked by $action have different things to do, so their their return result is different and second argument can also be different.
Is my solution a good practice? I'm sure many of you had the same problem, how did you solve it? Are there any possible problems?
P.S. Drug, Company, ActiveIngredient are all classes
A function should have clearly defined, narrow responsibilities with clearly defined, minimalist return types. If you start to create "god functions" which do everything and the kitchen sink depending on what arguments you pass, you're going heavily into the territory of hard to maintain spaghetti code. You do not want a function that does A and returns B if you pass it X, but does C and returns D if you pass it Y etc...
It is a good idea to start concrete and generalize over time as you see similar patterns emerge. So, create the methods you actually need:
public function findUserById($id)
public function findUserByEmail($email)
public function updateCompanyName($id, $newName)
If you find you have shared code between these functions, unify the code behind the scenes to keep it DRY:
public function findUserById($id) {
return $this->find('SELECT * FROM user WHERE id = ?', $id);
}
public function findUserByEmail($email) {
return $this->find('SELECT * FROM user WHERE email = ?', $email);
}
protected function find($query, $arg) {
...
}
Don't start the other way around, thinking you "only need X,Y and Z" which seem similar enough to be unified into one method, then later finding out there are small differences between X, Y and Z and littering your code with special cases for each. That just leads to functions which are either ginormous or so general they basically do nothing on their own.
What you are likely looking for is called a TableDataGateway (emphasis mine):
A Table Data Gateway holds all the SQL for accessing a single table or view: selects, inserts, updates, and deletes. Other code calls its methods for all interaction with the database.
This means you will have one generic database adapter, for instance a PDO object. You inject this into your various TDG's. The TDG's then use that adapter to CRUD data from the database.
Example
class CompanyTableGateway
{
private $dbAdapter;
public function __construct(DBAdapter $dbAdapter)
{
$this->dbAdapter = $dbAdapter;
}
public function create($name, $street, $whatever)
{
$this->dbAdapter->exec( 'INSERT INTO companies …' );
}
public function findById($id)
{
return $this->dbAdapter->exec(
sprintf('SELECT * from companies where id = %d', $id)
);
}
// more methods …
}
If you have multiple of these Gateways, you can abstract the general CRUD logic into an Abstract class and then extend the concrete Gateways from it.
You will then use a TableModule or similar other object to call the methods on the individual Gateways.
The never ending discussion of Separation of Concerns vs Single Responsibility Principle.
Separation of Concerns (SoC) – is the process of breaking a computer program into distinct features that overlap in functionality as little as possible. A concern is any piece of interest or focus in a program. Typically, concerns are synonymous with features or behaviors.
http://en.wikipedia.org/wiki/Separation_of_concerns
Single Responsibility Principle (SRP) – every object should have a single responsibility, and that all its services should be narrowly aligned with that responsibility. On some level Cohesion is considered as synonym for SRP. http://en.wikipedia.org/wiki/Single_responsibility_principle
Try to get the best of both, and model your classes accordingly.
What I would recommend you doing is do a global database class, which controls the basic input / output of the database, and then extend this down to each table.
An example of this could be a Users table. What you can do to this table is
Create
Update
Delete
You will then extend the Super Database Class, with a Users Class, which will have getters and setters for each function you want to have, ie:
class Users extends DatabaseClass {
public function update ( $params )
{
// Make the code for an update, and let the SuperClass execute the code.
...
}
public function add ( $params )
{
...
}
public function delete ( $params )
{
...
}
}
This will allow you to later, easily add more functionality to the Users table, and optimize queries specifically for the table/data you're using.

PHP5 OOP Class Structure

I know there are loads of questions on this, I have done quite a bit of reading. I'd like to ask this in context of my project to see what suggestions you may have.
I have quite a large web application with many classes, e.g. users and articles (which i consider to be the main classes) and smaller classes such as images and comments. Now on a page, lets say for example an article, it could contain many instances of images and comments. Makes sense right? Now on say an articles page I call a static method which returns an array of article objects.
That's the background, so here are the questions.
Since building a large amount of the app I came to realise it would be very useful to have a core system class containing settings and shared functions. There for I extended all of my classes with a new core class. Seemed relatively simple and quick to implement. I know CodeIgniter does something similar. I feel now though my app is becoming a bit messy.
Question Is this a good idea? Creating an instance of core is exactly what I want when calling an instance of an article, but what about when i'm creating multiple instances using the static method, or calling multiple images or comments on a page. I'm calling the core class unnecessarily right? Really it only needs to be called once per page (for example the constructor defines various settings from the database, I don't want to this every time, only once per page obviously), but all instances of all classes should have access to that core class. Sounds exactly like I want the singleton approach, but I know that's a waste of time in PHP.
Here's an idea of what my code looks like at this point. I've tried to keep it as simple as I can.
class core {
public function __construct(){
...define some settings which are retrieve from the database
}
public function usefulFunction(){
}
}
class user extends core {
public function __construct(){
parent::__construct();
}
public function getUser($user_id){
$db = new database();
$user = /* Get user in assoc array from db */
$this->__setAll($user);
}
public static function getUsers(){
$db = new database();
$users = /* Get users from database in assoc array from db */
foreach($users as $user) {
$arrUsers[] = new self();
$arrUsers[]->__setAll($user);
}
return $arrUsers;
}
private function __setAll($attributes) {
foreach($attributes as $key => $value)
{
$this->__set($key, $value);
}
}
public function __set($key, $value) {
$this->$key = $value;
}
}
The other issue I'm having is efficiently using/sharing a database connection. Currently each method in a class requiring a database connection creates a new instance of the database, so on a page I might be doing this 5 or 10 times. Something like the dependency injection principle sounds much better.
Question Now if i'm passing the instance of the DB into the new user class, i know I need something like this...
class user{
protected $db;
public function __construct($db){
$this->db = $db;
}
... etc
}
$db = new database();
$user = new user($db);
... but when I want to run the static function users::getUsers() what is the best way to gain access to the database instance? Do i need to pass it as a variable in each static method? (there are many static methods in many classes). It doesn't seem like the best way of doing it but maybe there isn't another way.
Question If extending all of my classes off the core class as suggested in part 1, can I create an instance of the DB there and access that some how?
Question I also have various files containing functions (not oop) which are like helper files. What's the best way for these to access the database? Again i've been creating a new instance in each function. I don't really want to pass the db as a parameter to each one. Should I use globals, turn these helper files into classes and use dependency injection or something different all together?
I know there is lots of advice out there, but most info and tutorials on PHP are out of date and don't ever seem to cover something this complex...if you can call it complex?
Any suggestions on how to best layout my class structure. I know this seems like a lot, but surely this is something most developers face everyday. If you need any more info just let me know and thanks for reading!
You asked in a comment that I should elaborate why it is a bad idea. I'd like to highlight the following to answer that:
Ask yourself if you really need it.
Do design decisions for a need, not just because you can do it. In your case ask yourself if you need a core class. As you already have been asked this in comments you wrote that you actually do not really need it so the answer is clear: It is bad to do so because it is not needed and for not needing something it introduces a lot of side-effects.
Because of these side-effects you don't want to do that. So from zero to hero, let's do the following evolution:
You have two parts of code / functionality. The one part that does change, and the other part that is some basic functionality (framework, library) that does not change. You now need to bring them both together. Let's simplify this even and reduce the frame to a single function:
function usefulFunction($with, $four, $useful, $parameters)
{
...
}
And let's reduce the second part of your application - the part that changes - to the single User class:
class User extends DatabaseObject
{
...
}
I already introduced one small but important change here: The User class does not extend from Core any longer but from DatabaseObject because if I read your code right it's functionality is to represents a row from a database table, probably namely the user table.
I made this change already because there is a very important rule. Whenver you name something in your code, for example a class, use a speaking, a good name. A name is to name something. The name Core says absolutely nothing other that you think it's important or general or basic or deep-inside, or that it's molten iron. No clue. So even if you are naming for design, choose a good name. I thought, DatabaseObject and that was only a very quick decision not knowing your code even, so I'm pretty sure you know the real name of that class and it's also your duty do give it the real name. It deserves one, be generous.
But let's leave this detail aside, as it's only a detail and not that much connected to your general problem you'd like to solve. Let's say the bad name is a symptom and not the cause. We play Dr. House now and catalog the symptoms but just to find the cause.
Symptoms found so far:
Superfluous code (writing a class even it's not needed)
Bad naming
May we diagnose: Disorientation? :)
So to escape from that, always do what is needed and choose simple tools to write your code. For example, the easiest way to provide the common functions (your framework) is as easy as making use of the include command:
include 'my-framework.php';
usefuleFunction('this', 'time', 'really', 'useful');
This very simple tow-line script demonstrates: One part in your application takes care of providing needed functions (also called loading), and the other part(s) are using those (that is just program code as we know it from day one, right?).
How does this map/scale to some more object oriented example where maybe the User object extends? Exactly the same:
include 'my-framework.php';
$user = $services->store->findUserByID($_GET['id']);
The difference here is just that inside my-framework.php more is loaded, so that the commonly changing parts can make use of the things that don't change. Which could be for example providing a global variable that represents a Service Locator (here $services) or providing auto-loading.
The more simple you will keep this, the better you will progress and then finally you will be faced with real decisions to be made. And with those decisions you will more directly see what makes a difference.
If you want some more discussion / guidance for the "database class" please consider to take a read of the very good chapter about the different ways how to handle these in the book Patterns of Enterprise Application Architecture which somewhat is a long title, but it has a chapter that very good discusses the topic and allows you to choose a fitting pattern on how to access your database quite easily. If you keep things easy from the beginning, you not only progress faster but you are also much easier able to change them later.
However if you start with some complex system with extending from base-classes (that might even do multiple things at once), things are not that easily change-able from the beginning which will make you stick to such a decision much longer as you want to then.
You can start with an abstract class that handles all of your Database queries, and then constructs them into objects. It'll be easy to set yourself up with parameterized queries this way, and it will standardize how you interact with your database. It'll also make adding new object models a piece of cake.
http://php.net/manual/en/language.oop5.abstract.php
abstract class DB
{
abstract protected function table();
abstract protected function fields();
abstract protected function keys();
public function find()
{
//maybe write yourself a parameterized method that all objects will use...
global $db; //this would be the database connection that you set up elsewhere.
//query, and then pack up as an object
}
public function save()
{
}
public function destroy()
{
}
}
class User extends DB
{
protected function table()
{
//table name
}
protected function fields()
{
//table fields here
}
protected function keys()
{
//table key(s) here
}
//reusable pattern for parameterized queries
public static function get_user( $id )
{
$factory = new User;
$params = array( '=' => array( 'id' => $id ) );
$query = $factory->find( $params );
//return the object
}
}
You'll want to do your database connection from a common configuration file, and just leave it as a global variable for this pattern.
Obviously this is just scratching the surface, but hopefully it gives you some ideas.
Summarize all answers:
Do not use single "God" class for core.
It's better to use list of classes that make their jobs. Create as many class as you need. Each class should be responsible for single job.
Do not use singletones, it's old technique, that is not flexible, use dependecy injection container (DIC) instead.
First, the the best thing to do would be to use Singleton Pattern to get database instance.
class Db{
protected $_db;
private function __construct() {
$this->_db = new Database();
}
public static function getInstance() {
if (!isset(self::$_db)) {
self::$_db = new self();
}
return self::$_db;
}
}
Now you can use it like db::getInstance(); anywhere.
Secondly, you are trying to invent bicycle called Active Record pattern, in function __setAll($attributes).
In third, why do you wrote this thing in class that extends Core?
public function __construct(){
parent::__construct();
}
Finally, class names should be capitalized.

php static functions vs instance functions, basics

I'm trying to learn when static functions should be used, and have had a difficult time finding an answer my questions. I am creating a class User, which is related to a class Group. If I have a user id and I want to get a user object from that, is it better to do something like
$existingUser = User::get($userId);
where the class is defined like this
class User()
{
public static function get($id){
$user = new User();
return $user->findById($id);
}
public function findById($id) {
//find and populate user object
}
}
or
$existingUser=new User();
$existingUser->findById($userId);
where the class is defined like this
class User()
{
public function findById($id) {
//find and populate user object
}
}
What about if I were to write a function which returns an array of Group objects based on a user id?
class User()
{
//stuff
$groupArray = Group::getAllByUserId($this->getId())
//stuff
}
or
class User()
{
//stuff
$group = new Group();
$groupArray = $group->findAllByUserId($this->getId());
//stuff
}
The second method creates an empty group object which is never used. Does it matter?
Am I misunderstanding the concept of static? I know it is useful for not having to instantiate a class, so if the function instantiates one anyway, does that kind of defeat the purpose? If so, what would be an example of when a static function would be used?
Anything else I should be considering in this over simplified example?
You don't need a static function int he case you show above.
Static functions are really just global functions with a namespace.
Use them when the global state of the application needs to be controlled, or if multiple copies of the function lead to inonsistant results.
Callbacks sometimes need to be static, especially if they are passed as a string.
I'm trying to learn when static functions should be used
Oh, it's so simple: never.
To understand it, read:
http://www.objectmentor.com/resources/articles/ocp.pdf
http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
I find a good rule of thumb is thinking "If I don't have a [class-name], would I expect to be able to call [method-name]?"
If I don't have a user, would I expect to be able to call findByID?
Probably not. This is one of the exceptions I come across; a "load" or a "save" method sometimes makes sense to be static.
A perfect example of when to use non-static methods is (most methods in) a Database class - you should always have a database object before you try to run a query on it.
An example of when to use a static method would be a "helper" class, essentially a collection of handy functions. Say you have some methods that help you output HTML, you might have HTML::image(), HTML::url() and HTML::script(). On these, you shouldn't need a HTML object to create an image, URL, and so on.
As for stopping multiple copies of objects being created (one argument for using static methods), you should use a Singleton pattern instead (Google it) to ensure only one copy of the object ever exists.
You should probably check out this question on Active Record vs data mapper:
https://stackoverflow.com/questions/2169832/data-mapper-vs-active-record
One take from this question is that static methods on the class for loading/saving aren't really the core functionality of the class in most cases. Further, storing and loading is a kind of abstract concept that is separate from your class objects in most cases.
Isa "user" a data storage and retrieval object? In most cases, no, it is a person represented in your system that has various properties and functions. When you start tying the persistence of that object into the object, you break encapsulation and make it harder to maintain the code. What if next week you want to load your users out of memcache? It's hardly relevant to if a user can have some property or functionality.

Categories