3

It seems all my classes I create are filled with methods that contain MySql queries. I decided to take a shot at decoupling. Below I have my base class Customer, and my repository class CustomerRepository that's passed to the constructor if needed. The methods are basic, the save method in customer calls the create method in CustomerRepository for example. The customer class is now a little more readable but at what cost? I coded an entire other class just to do the MySql query that I could have put in the create method in the Customer class to begin with. I'm struggling to find a real world example of decoupling that will work in this scenario as it pertains to a work project. The examples I've found such as here, Proper Repository Pattern Design in PHP? (although fantastic), seem to be overly complex. My question(s) is: am I decoupling correctly? and is decoupling even necessary when the real world requires quick and somewhat dirty code to achieve the business goal as quickly as possible?

<?php

/*
 CRUD
 create, read, update, delete
*/

class Customer {

    public $CustomerRepository;

    public $id;
    public $first_name;
    public $last_name
    public $email;
    public $phone;

    public function __construct( CustomerRepository $CustomerRepository = null ) {
        if( !is_null( $CustomerRepository ) {
            $this->CustomerRepository = $CustomerRepository;
        }
    }

    public function save() {

        return $this->CustomerRepository->create( 
            $this->first_name, 
            $this->last_name, 
            $this->email, 
            $this->phone 
        );

    }

    public function find() {

        return $this->CustomerRepository->read( $this->id );

    }

    public function edit() {

        return $this->CustomerRepository->update( 
            $this->first_name, 
            $this->last_name, 
            $this->email, 
            $this->phone,
            $this->id
        );

    }

    public function remove() {

        return $this->CustomerRepostitory->delete( $this->id );

    }

    public function populate( $id ) {

        $customer = $this->find( $id );
        $this->id         = $customer['id'];
        $this->first_name = $customer['first_name'];
        $this->last_name  = $customer['last_name'];
        $this->email      = $customer['email'];
        $this->phone      = $customer['phone'];

    }

}

class CustomerRepository {

    private $Database;

    public function __construct() {
        if( is_null( $this->Database ) {
            $this->Database = new Database();
        }
    }

    public function create( $first_name, $last_name, $email, $phone ) {

        $this->Database->query( 'INSERT INTO customers( first_name, last_name, email, phone ) 
            VALUES( :first_name, :last_name, :email, :phone )' );
        $this->Database->bind( ':first_name', $first_name );
        $this->Database->bind( ':last_name', $last_name );
        $this->Database->bind( ':email', $email );
        $this->Database->bind( ':phone', $phone );

        return $this->Database->getLastID();
    }

    public function read( $id ) {

        $this->Database->query( 'SELECT * FROM customers WHERE id = :id LIMIT 1' );
        $this->Database->bind( ':id', $id ):

        return $this->Database->single();

    }

    public function update( $first_name, $last_name, $email, $phone, $id ) {

        $this->Database->query( 'UPDATE customer SET 
            first_name = :first_name,
            last_name  = :last_name,
            email      = :email,
            phone      = :phone WHERE id = :id' );
        $this->Database->bind( ':first_name', $first_name );
        $this->Database->bind( ':last_name', $last_name );
        $this->Database->bind( ':email', $email );
        $this->Database->bind( ':phone', $phone );
        $this->Database->bind( ':id', $id );

        return $this->Database->execute();
    }

    public function delete( $id ) {

        $this->Database->query( 'DELETE FROM customers WHERE id = :id LIMIT 1' );
        $this->Database->bind( ':id', $id ):

        return $this->Database->execute();

    }

}
6
  • 2
    have a look at ORMs, e.g. Active Record, Data Mapper, and frameworks that use them. If you want to exercise in designing your own ORM, there is nothing wrong with it, just an extra work. Commented Jan 22, 2016 at 2:20
  • I have checked those out. I've also used Doctrine, which was neat, but they all still seem to go back to the same issue, overkill. Commented Jan 22, 2016 at 3:02
  • @Naterade Doctrine is powerful and flexible and might have a high learning curve. I suggest you try something like this: SpotORM — there is nothing overkill about it. Commented Jan 22, 2016 at 3:57
  • well, yes, it's overkill in a same way as using OOP for showing a simple list of customers. Just get your sql results, implode with <br> and print away) Commented Jan 22, 2016 at 4:06
  • @vitr I never said anything about showing a simple list of customers. It a simplified example of a more complex class that runs a complex eCommerce subscription engine. The point was to get basic decoupling advice to work into a larger system. No need to italicize your comments and be sarcastic, nobody attacking your ego. Commented Jan 22, 2016 at 4:17

1 Answer 1

1

As everyone already suggested here you need to implement ORM. See this question to choose: Good PHP ORM Library?

If you still don't want to use ORM you will need to implement the same thing by itself, this will take more time than using ready-to-go ORM. You could implement Unit of work (http://martinfowler.com/eaaCatalog/unitOfWork.html ) and Repository (http://martinfowler.com/eaaCatalog/repository.html) patterns to build you own ORM.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.