PHP understanding OOP Concepts - php

I'm just new to PHP and i cant understand why the code bellow doesn't works.
If i do the same code but not using class things works just fine.
<?php
class DAL
{
public $Conn;
public function __construct()
{
global $Conn;
$Conn = new PDO("mysql:host=localhost;dbname=football", "root","");
$Conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
}
}
class BLL
{
public function GetSeason()
{
$conn = new DAL();
$result = $conn->Conn->query("Select * from season");
print_r($result->fetchAll());
}
}
?>

If I understand right, DAL is Data access layer and BLL is Business logic layer.
Both usually represented not by one class or object, but rather contain objects that represent different levels of abstractions in your application.
Data access layer consists of Data access objects and Business logic layer consists of Business Objects. So you should have one Data access object for each Business Object. In general Data access objects should share one interface (i.e. should extend same Data access object abstract class):
abstract class DataAccessObject
{
protected $conn;
public function __construct($conn)
{
$this->conn = $conn;
}
abstract public function all();
abstract public function get($id);
abstract public function save($object);
abstract public function delete($object);
}
So with your example, the code can look like the following. Here is your season DAO:
final class SeasonDataAccessObject extends DataAccessObject
{
public function all()
{
$query = $this->conn->query('SELECT * FROM `season`');
$seasons = [];
foreach ($query->fetchAll() as $result) {
$seasons[] = $this->hydrate(new Season, $result);
}
return $seasons;
}
public function get($id)
{
// Execute select statement and hydrate result into
// Season Business Object.
// Should return instancs of Season.
}
public function save($season)
{
return null === $season->id
? $this->insert($season)
: $this->update($season);
}
public function delete($season)
{
// Execute delete statement.
}
private function hydrate(Season $season, $result)
{
// Fill $season attributes with values from $result.
}
private function update(Season $season)
{
// Execute update statement.
}
private function insert(Season $season) {
// Execute insert statement.
}
}
And here goes your season Business object:
abstract class BusinessObject
{
private $id;
public function setId($id)
{
$this->id = $id;
return $this;
}
public function getId()
{
return $this->id;
}
}
final class Season extends BusinessObject
{
// Some properties of Season and setters and getters for them.
}
And finally, you can use it all in your program:
$conn = new PDO('mysql:host=localhost;dbname=football', 'root', '');
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$seasonDAO = new SeasonDataAccessObject($conn);
$seasons = $seasonDAO->all();
print_r($seasons);
I guess you got the lingo from "Microsoft Application Architecture Guide" or somewhere else in the Microsoft world (your attributes naming also speaks for it:)). In the modern world, I guess Data access object is Repository and the Business object is Entity.
This is pretty advanced stuff that concerns not even OOP, but Object-oriented design. So you must understand OOP first, because as it was mentioned in the comments, now your code is procedural. Wrapping code in class doesn't make code object-oriented (at the end of the day, this is Object-oriented programming, not Class-oriented programming;))
So, please start with some tutorial on the subject of OOP in PHP (i.e. this one), and gradually you will get better in this.

Done!!!!!
Thank you guys so much!!!
class DAL
{
public $Conn;
public function __construct()
{
$this->Conn = new PDO("mysql:host=localhost;dbname=football",
"root","");
$this->Conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
}
}
class BLL
{
public function GetSeason()
{
$conn = new DAL();
$result = $conn->Conn->query("Select * from season");
print_r($result->fetchAll());
}
}

Related

PHP - Good design pattern for static database connection class

I have a "static" class which connects to database and has various functions. The current base layout is as follows:
class DB {
private static $con;
private function __construct() {};
private static function init() {
if(is_null(self::$con) {
// Initialize database connection
}
}
public static someMethod1() {
self::init();
// Do stuff
}
public static someMethod2() {
self::init();
// Do stuff
}
public static someMethod2() {
self::init();
// Do stuff
}
}
My intention is to be easily be able to call these methods as: DB::someMethod1(). However, as you can see, I am having to cehck for initialization at every method beginning. Is this a good coding practice? Is there a better design pattern available? Initially I thought of builder pattern but that doesn't really fit here in my opinion.
It looks like you are trying to ensure that there is a single instance of your DB class AND also that the instance is available as a single, globally available constant.
I'd recommend separating those two concerns in order to simplify the implementation.
First, I'd focus on getting the database access object right. Plain objects are simpler to test and inject as dependencies than static functions. For example,
class DBThing
{
private $con;
public static function build()
{
return new static('theconnection');
}
function __construct($con)
{
$this->con = $con;
}
public function someMethod1()
{
echo "someMethod1: $this->con\n";
}
public function someMethod2()
{
echo "someMethod2: $this->con\n";
}
public function someMethod3()
{
echo "someMethod3: $this->con\n";
}
}
Gives you an object you can easily test and replace with alternate implementations if needed.
Second, I'd focus on the object lifecycle and making it discoverable in the application.
If you're really OK with a single instance and the global state that implies, then something like this gets you close to the interface you asked for in your original post.
$DB = DBThing::build();
$DB->someMethod1();
$DB->someMethod2();
$DB->someMethod3();
In general, I discourage global state but I'd have to know more about your application to know if it's appropriate in your case.
I just wrote a simple db class for a coding test. Take a look at how I used here: https://github.com/TheRealJAG/Valuation-Vision-Full-Stack-Test/blob/master/classes/db.php
class DB
{
private static $instance = null;
private $db;
private $host = '';
private $username = '';
private $password = '';
private $database = '';
private function __construct()
{
$this->db = new mysqli($this->host, $this->username, $this->password, $this->database);
if ($this->db->connect_error) {
throw new Exception("Connection to the mysql database failed: " . $this->db->connect_error);
}
}
public static function connection()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance->db;
}
}
I'm 100% sold on the approach, but with the time I had for the test this is what I wrote. My biggest concern was that I only had 1 db connection open.

PHP - Classes inheritance and combining with another class

I want to write something inheriting classes in the structure of the 3 levels. Abstract example of such.
couriers_list -> courier -> courier_name
class couriers_list {
// I'm searches courier_name of the database and reference to the class of courier_name found in database
public function show_courier() {
return $this->xxx();
}
}
class courier extends couriers_list {
// Function for the courier
// Probably it would interface or abstraction
}
class courier_name extends courier {
// Methods of accurately courier eg. Calculation associated with the delivery
// Here each courier would separate file php eg. ups.php
public function xxx() {
return 'xxx';
}
}
$k = new couriers_list();
echo $k->xxx();
I don't think I can extends courier to courier_list, because I don't have access to methods descendants. From the outside, I would like to refer only to the class couriers_list, and she has to take the info from the database and take methods resulting from courier_name.
How to put this problem to organize object?
Your class Courrier should be an interface since it used to define the way your Courrier should be used
interface CourrierInterface
{
const CLASS_NAME = __CLASS__;
public function getName();
public function getPrices();
public function XXX();
public function calculateDelivery($from, $to);
/** these are just example add here all the method that define a courier */
}
Then for each courrier you have, you should implements de CourrierInterface
class UpsCourrier implements CourrierInterface
{
private $name;
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function XXX()
{
// do something
}
}
I don't think the CourrierList should know about the database but just need to contains all the courrier object you have.
Here i used the project
https://github.com/yvoyer/collection
in order to manage the collection (TypedCollection class), it allows to control the type of class you want in your collection (here courrierInterface), but you can use an array if you want it much simple.
I create two XXX method, one for a specific courrier (since its a list) and another for apply to all the list. I don't know your need so take what you need
class CourrierList
{
/**
* TypedCollection
*/
private $courrierList;
public function __construct()
{
// i prefer to use a collection class that valid my type instead of an array, your choice!
$this->courrierList = new TypedCollection("CourrierInterface");
}
public function addCourrier(CourrierInterface $courrier)
{
$this->courrierList->add($courrier);
}
public function removeCourrier(CourrierInterface $courrier)
{
$this->courrierList->removeElement($courrier);
}
protected function getCourrierByName($courrierName)
{
$closure = function (CourrierInterface $courrier) use ($courrierName) {
return $courrier->getName() == $courrierName;
};
return $this->courrierList->filter($closure)->toArray();
}
// since its a list, you must be able to select your courrier to execute the XXX() method
public function XXXByName($name)
{
$courrier = $this->getCourrierByName($name);
$courrier->XXX();
}
// if you prefer to apply to all your courrierList just do
public function XXX()
{
foreach ($this->courrierList as $courrier) {
$courrier->XXX();
}
}
}
Since i don't think the CourrierList should know about the database, you can create a factory that does fetch the data in your db and create all the courriers. Here dbConnection is your choice, pdo etc... i just made an example, find the good way to make query.
class CourrierListFactory
{
private $dbConnection;
public function __construct(DbConnection $connection)
{
$this->dbConnection = $connection;
}
public function createCourrierList()
{
$results = $this->dbConnection->query(".....")->getResults();
$courrierList = new CourrierList();
foreach ($results as $result) {
$courrier = null;
switch ($result['name']) {
case 'ups':
$courrier = new UpsCourrier();
break;
case 'fedex':
$courrier = new FedexCourrier();
break;
/** and so on ... */
default:
// maybe throw exception if courier is not handle
}
$courrier->setName("....");
/** prepare your object here */
// add the courrier to the list
$courrierList->addCourrier($courrier);
}
return $courrierList;
}
}
Finally its how you use all of this, first create a dbCOnnection, then build your list, then you can acces
$dbConnection = new DbConnection();
// the factory allows you to separate the database from the List class and may be to generate
// your list in an other way later (using apis, etc...)
$factory = new CourrierListFactory($dbConnection);
$courrierList = $factory->createCourrierList();
$courrierList->XXX(); // apply to all
$courrierList->XXXByName("ups"); // apply just to ups courrier

PHP OOP best practices or how to code right?

I'm trying to learn how to properly code PHP OOP.
This is where I'm running into issues.
I created several classes that extend main Application class and I want to make things work properly.
I have main file that's index.php that looks like this:
include_once('classes/Application.php');
include_once('classes/Configuration.php');
include_once('classes/Database.php');
$app = new Application;
$config = new Configuration;
$db = new Database;
var_dump($app->db_connected);
var_dump($db->db_connected);
$db->connect($config->dbhost, $config->dbuser, $config->dbpass, $config->dbname);
var_dump($app->db_connected);
var_dump($db->db_connected);
The output is:
1. bool(false)
2. bool(false)
3. bool(false)
4. bool(true)
My main application file looks like this:
class Application {
public $db_connected = false;
}
And my Database class looks like this:
class Database extends Application {
function connect($dbhost, $dbuser, $dbpass, $dbname) {
if(!$this->db_connected) {
mysql_connect($dbhost, $dbuser, $dbpass) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$this->db_connected = true;
}
}
}
So the question is, why would line #3 of the output of index.php display false? The db_connected property has been overridden in Database class and set to TRUE, but it still returns false.
Although when accessed directly from Database class instance it shows TRUE correctly. What's the deal here?
Also when does the class EXTEND command occurs? Whenever parent class' instance is created or I have to manually create instance of the child class?
It seems you are reaching for the concept of of a static variable all instances of a class share the same static variable so using the new twice will not be an issue.
You can see the code on ideaone.
// your code goes here
class Application {
static $db_connected = false;
}
class Database extends Application {
function connect() {
if(!static::$db_connected) {
static::$db_connected = true;
}
}
}
$app = new Application;
$db = new Database;
var_dump(Application::$db_connected);
var_dump(Database::$db_connected);
$db->connect();
var_dump(Application::$db_connected);
var_dump(Database::$db_connected);
Your comment make me think you are looking for a better pattern all together. I would like to throw out some key principles namely OCP and LSP SOLID.
In this case you would avoid having Application being an instance of Database but instead use dependency injection. Here is the refactored code.
class Database {
private $db_connect = false;
public function connect () {
if(!$this->db_connect) { /* do connection */ }
}
}
class Application {
private $db;
public function setDatabse(Database $db) {
$this->db = $db;
}
public function getDatabase() {
return $this->db;
}
}
$db = new Database;
$app = new Application;
$app->setDatabase($db);
$app->getDatabase()->connect();
This line is your hint
Although when accessed directly from Database class instance it shows TRUE correctly. What's the deal here?
You have 2 instances. Above you are checking $db instance which you connected with, and then you print from $app which was never connected. They are separate entities, one is connected one is not.
Extend occurs as soon as the file is loaded, read by the php interpreter, this happens regardless of ever using the class.
Extend is called from the child and inherits everything form the class it extends. So if you call a child method in the parent, well you are doing it backwards. It goes one way, Prent -> Child.
I would use Dependance injection for the database, then you can reuse it's code.
Like this:
//parent class
class Application {
//holds a reference to the Database class
protected static $db_conn = false;
public function __construct($db){
self::$db_conn = $db;
}
}
//child class of Application
class Application2 extends Application {
public function getSomething($id){
return self::$db_conn->getbyId($id) ;
}
}
//separate utility class
class Database{
static $conn;
public function __construct( $dbhost, $dbname, $dbuser, $dbpass, $dbname) {
static::$conn = mysqli_connect($dbhost, $dbuser,$dbpass,$dbname);
}
public function getbyId( $id ){
..code to get stuff by id using $conn - previous connection ...
return $result;
}
}
$db = new Database("myhost", "myuser", "mypassw", "mybd");
$app = new Application2( $db );
$app->getSomething(1);
//create another app with the same database connection, this is the value of injecting it.
$second_app = new Application2( $db );
See you can reuse database over and over, you can replace it without changing the code in Application as long as the calls for the functions of the Database class don't change. Each thing is responsible for it's own business.
This is called separation of concerns.
Inheritance is good, when it's needed. You might have an basic application for free users of you're services and then extend that with a premium application for paid members. Sense they paid they get all the free functionality, but also the premium stuff to.
In my example above the database is something they both need, as well as other things will probably use this. Such as a login system may need a database connection, payment system might, a shopping cart might. These are all separate objects, they don't / nor should they extend off of one Master Class, that's a bad idea. Keep them separate.
STATIC
I seen mention of the :: static object operator. My example is a bit flawed when using the static property protected static $db_conn = false;
$app = new Application2( $db );
$second_app = new Application2( $db ); //assigning db 2x is not needed.
The reason for :: and the -> normal way. Is that static :: is shared across all instance of a class, and -> is just this instance of the class. I had assigned the $db class to a static variable 2 times a better way would have been like this.
//parent class
class Application {
protected static $db_conn = false;
//separate method then construct.
public function connect($db){
self::$db_conn = $db;
}
}
//we'll keep the rest of the code the same here.
$db = new Database();
$app = new Application2();
$app->connect( $db );
$second_app = new Application2();
$second_app->getSomething(1);
Now in this example $second_app never ran it's connect method. But because the first $app did and because the static for the database variable protected static $db_conn. Now all classes that have extended the Application class have a database connection. This is what static does. It's value is shared across all instance of the class. So when you see :: think all class instance and when you see -> think only this class instance. It's actually one thing I love about php, makes it so much easier to keep track of then in some other languages.
Not to confuse you but the other use of the :: is not actually needing an instance at all. Assume you have a Config class like this.
class Config{
static $db = 'hello';
static $items = array('one' => 'item 1' );
private __construct(){} // no construction allowed
static function getItem( $which ){
return self::$items[$which];
}
}
Now without ever creating an instance of the class by calling new Config() , you can simply.
echo Config::$db;
// prints hello
echo Config::getItem('one');
// prints 'item 1'
This is quite use full for config type classes. Where they are an empty shell just used to store data in and you don't need an object for them, essentially a way to keep things organized. So tying this in to the previous examples
$db = new Database(Config::$myhost, Config::$myuser, Config::$mypassw, Config::$mybd);
In your case best OOP practice is to use Mediator pattern. Concrete Mediator will be Application class:
class ApplicationBase {
private $db;
private $cfg;
public function setDb(Database $db) {
$this->db = $db; return $this;
}
public function setConfig(Config $cfg) {
$this->cfg = $cfg; return $this;
}
}
class Application extends ApplicationBase {
public function getDsn() {
return $this->cfg->getDsn();
}
public function getDbUser() {
return $this->cfg->getDbUser();
}
public function getDbPass() {
return $this->cfg->getDbPass();
}
public function getConnection() {
return $this->db->getConnection();
}
}
class AppComponent {
protected $app;
public function __construct(Application $app) {
$this->app = $app;
}
}
class Config extends AppComponent {
private $dsn;
private $dbuser;
private $dbpass;
// ... getters and setters
}
class Database extends AppComponent {
private $connection;
private function connect() {
$this->connection = new PDO(
$this->app->getDsn(),
$this->app->getUser(),
$this->app->getPass()
);
}
public function getConnection() {
if (null === $this->connection) $this->connect();
return $this->connection;
}
}
class Model extends AppComponent {
protected $table;
// Model stuff here
}
class Content extends Model {
public function getNews() {
$db = $this->app->getConnection();
return $db->query("SELECT * FROM $this->table LIMIT 5")->fetchAll();
}
}
Such architecture will be enough for simple, clean-looking applications and classes will be ready for easy unit-testing:
$app = new Application();
$cfg = new Config($app);
$db = new Database($app);
$app->setDb($db)->setConfig($cfg);
$content = new Content($app);
$news = $content->getNews();

Hand rolling an ORM Class -- Singleton, Static Parent,?

I'm writing a web reporting extension to a data warehouse my company purchased. The data warehouse is data-model neutral, and has tables storing the table relationships and metalayer data for the fields. This makes it pretty easy for me to write a basic ORM class, which is what I'm trying to do. It all works, but...
My ORM class holds the PDO instance, the fields for the table (used as a whitelist), and metalayer info for the fields. It also has convenience functions for mapping the table relationships (generates the FROM / JOIN clauses) and mapping the filters supplied from the web (generates the WHERE clause).
The SELECT clause is generated in child classes of the ORM, based on the model requested. When the page loads, there are several models that need to be built. Obviously, I only need one instance of the ORM (like a monostate), but I would like each child class to inherit the properties and convenience functions of the ORM -- without redoing the parent class' queries each time a child class is instantiated.
The singleton pattern may fit here, but I'm finding it difficult to subclass a singleton. And I just can't seem to get static properties to work right.
I think I'm close but I'm either missing something or making this too difficult. I'm now considering dropping the properties into a thin class and extending from there while mixing the convenience function in with traits. I've seen similar questions for this topic, but haven't come up with a definite solution.
I'm not at work, but this is a simplified example of the code that should give you the gist of what I'm trying to do.
Class ORM {
protected $conn;
protected $fields;
protected $relations;
protected $table;
protected $sql;
public function __construct ($view, $database) {
$this->conn = new PDO(...$database...);
$this->table = $view;
$this->getFields();
$this->getRelations();
}
private function getFields () {
//select fields from metalayer where table = $table;
//$this->fields = $result;
}
private function getRelations () {
//select relations from relations where table = $table;
//$this->relations = $result;
}
protected function mapTables ($tables) {
// $this->sql = "FROM $this->table";
// foreach ($tables as $table) {
// $this->sql .= "LEFT JOIN $table ON $relations[$table]['key1'] = $relations[$table]['key2'];
}
protected function mapFilters ($filters) {
// $this->sql = "WHERE 1=1";
// foreach $filters as $filter {
// $this->sql .= "AND ($filter['field'] = $filter['criterion1'] OR ...criterion2, etc.)
}
}
Class ExampleModelDAO extends ORM {
public function __construct($view, $database, $params) {
parent::__construct($view, $database);
// parse params
parent::mapTables($tables);
parent::mapFilters($filters);
}
public function get() {
// Prepend $this->sql with SELECT statement specific to model
// Query database and return model
}
}
First off, your orm/model shouldn't know anything about the database. There are a million ways to do this but I would start with a simple database class that offers some additional functionality on top of pdo but completely independent from anything else. This will also allow you to do direct database access without requiring the need for a model as well as allow you to create models that are database independent. For maximum flexibility you want to look into the adapter pattern and data mapper. However, to keep it simple, here is a very basic example (without an adapter or data mapper) of mapping a model to a data store.
<?php
class DB extends PDO {
public function __construct() {
try {
parent::__construct(/* db info */);
} catch (Exception $e) {
// handle the error
}
}
public function read() {
// read from database
}
public function write() {
// write to database
}
// etc...
}
So your database class will have some simple crud operations. Then your orm can interact with this class like so...
<?php
class ORM {
public function __construct() {
$this->db = new DB();
}
public function find($options) {
return $this->db->read($options);
}
public function save($data) {
return $this->db->create($data); // or update()
}
// etc...
}
This should be enough to get you going. Also, rather than using a singleton pattern for your database, if you don't manage your connections externally, you could use a simple modified registry type pattern (note this isn't a true registry)
<?php
class DB extends PDO {
protected static $instances = array();
public function __construct() ...
public static function get($name) {
if(! isset(self::$instances[$name]) {
self::$instances[$name] = new self();
}
return self::$instances[$name];
}
}
class ORM {
public function __construct() {
$this->db = DB::get('connection1');
}
}
There are better ways to do this but I will leave that up to you.

OO PHP where to reference singleton class?

I am going to use singleton classes to manage both DB connections and references to application settings.
It seems a little messy to have to use the following code in every method in order to access the db class.
$db = DB::getInstance();
Is there a more efficient way of going about it?
Any advice appreciated.
Thanks
I often use the Registry pattern, where this behavior occurs as well. I always set a instance variable in the constructor of my models to point to the Registry entry;
class Registry {
private static $_instance;
private $_registry;
private function __construct() {
$_registry = array();
}
public static function getInstance() {
if (!Registry::$_instance) {
Registry::$_instance = new Registry();
}
return Registry::$_instance;
}
public function add($key, &$entry) {
$this->_registry[$key] = &$entry;
}
public function &get($key) {
return $this->_registry[$key];
}
public function has($key) {
return ($this->get($key) !== null);
}
}
Model example;
class MyModel {
private $_db;
public function __construct() {
$this->_db = Registry::getInstance()->get('dbKey');
}
/* Every function has now access to the DAL */
}
Instantiation example;
$dal = new Db(...);
Registry::getInstance()->add('dbKey', $dal);
...
$model = new MyModel();
$model->doDbStuff();
Another approach is to always pass the reference as a parameter to each constructor.
Of course I only use this behavior when most of the methods in my model use the reference, if only a few (one or two) methods have use of the reference, I call the Registry/Singleton like you showed.
It is not messy. This is an intended behavior of Singletons. And, actually, this is just one line of code. Do you wish to make it even more compact? :)
My preferred method is to create a Base class which all the classes that need db access descend from. Base calls the singleton(s) in its constructor. All its children call their parent constructor. e.g.:
class Base {
protected $db;
public function __construct(){
$this->db = DB::getInstance();
}
}
class Achild extends Base {
protected $var1;
public function __construct($arg){
parent::__construct();
$this->var1=$arg;
}
}
I know what you mean... hate that ::getInstance() stuff! So go and use static methods:
class DB {
private static $db;
public static function getInstance() {
if(!self::$db) {
self::$db = new DBconnector();
}
}
public static function query($query) {
return self::$db->query($query);
}
}
Usage is much nicer:
$result = DB::query('SELECT whatever;');
And if you use PHP 5.3 you can write a __callStatic similar to this, to forward all the method calls to the object:
public static function __callStatic($method, $args) {
call_user_func_array(array(self::$db, $method), $args);
}
And to make me happy, add an __autoloader so that you can access DB without any worries any time!

Categories