SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Member stevepop's Avatar
    Join Date
    Mar 2004
    Location
    Lagos, Nigeria
    Posts
    13
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Help needed for OOP Newbie

    I am a newbie to OOP having been coding in PHP4 procedural approach. I have been given a project in my office to develop a web based staff appraisal application and I have chosen to use OOP. I have read some books and I think I understand some basic concepts of OOP. I really need some help in the design of this project along OOP lines.

    The flow is simply this; A subordinate, logs on to the application, his ID fetches his personal info from the database (name, location, dept, etc) he enters further information and submits the form. On submission, his supervisor recieved an email notifying him of a pending appraisal. The supervisor logs in and calls up the staff profile. He inputs his rating, adds his comments and submits. An email is sent back to the subordinate who must agree or disagree with the supervisor input, once this is done, the appraisal goes to the dept head who adds a comment before sending it to either a higher person or the Human resources department, if no one is higher up in that department.

    I am thinking of the following classes;

    Appraisee Class
    Supervisor class
    DB class
    Email Class

    I am having a problem with being able to define the attributes and methods of the classes and whether these classes are even adequate based on what I have described above

    I will really appreciate anyone who can give me ideas to help

    Thank you

  2. #2
    SitePoint Enthusiast lix0r's Avatar
    Join Date
    Feb 2006
    Location
    Norway
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, it looks like you have good idea about what classes you should include in this project. I would start making an outline of all the classes, this way you'll see if you have all the needed classes and methods.

    For the methods, you could analyze the text you wrote for all the actions the different "operators" have to do, and make methods which performs these actions. For instance, the approval of input, sending mails and so on. From here you will probably see what properties/variables the different classes will need.

    So just dive into it! OOP can be pretty intimidating at first, but when you get familiar with it, I bet you're going to love it

  3. #3
    SitePoint Addict rvdavid's Avatar
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi there,

    Apologies in advance, I was a little sleepy when i wrote this, so it may be a little all over the place

    Quote Originally Posted by stevepop View Post
    I am a newbie to OOP having been coding in PHP4 procedural approach. I have been given a project in my office to develop a web based staff appraisal application and I have chosen to use OOP. I have read some books and I think I understand some basic concepts of OOP. I really need some help in the design of this project along OOP lines.

    The flow is simply this; A subordinate, logs on to the application, his ID fetches his personal info from the database (name, location, dept, etc) he enters further information and submits the form. On submission, his supervisor recieved an email notifying him of a pending appraisal. The supervisor logs in and calls up the staff profile. He inputs his rating, adds his comments and submits. An email is sent back to the subordinate who must agree or disagree with the supervisor input, once this is done, the appraisal goes to the dept head who adds a comment before sending it to either a higher person or the Human resources department, if no one is higher up in that department.

    I am thinking of the following classes;

    Appraisee Class
    Supervisor class
    DB class
    Email Class

    I am having a problem with being able to define the attributes and methods of the classes and whether these classes are even adequate based on what I have described above

    I will really appreciate anyone who can give me ideas to help

    Thank you
    I can relate to your having problems early in your attempt to pick up OOP. I apologise for giving a vague answer, I'll give you some insight as to how to decipher what attributes and methods a certain class would have.

    Attributes
    Attributes also known as properties are basic parts of an object this defines what an object is and holds reference to parts that it is made of.

    So let's take for example an Email class.

    Class: Email

    A couple of questions then come to mind:
    - what is an email made of?
    - what can an email do?

    what is an email made of?
    An email is made of the following "attributes"

    Attributes
    - Sender Email address.
    - Sender Name
    - Recipient
    - Recipent Name
    - Send Method
    - Subject
    - Message
    - Headers (additional headers)
    - CC
    - Bcc

    what can an email do?
    An email posseses the following "methods"

    Methods
    - Send
    - Attach file
    - Add CC
    - Add Recipient
    - Add BCC
    - Numerous accessors and mutators for it's properties (although this is open for debate).

    Having said that, perhaps the best place for you to start at would be using other people's OOP packages. For instance, phpMailer is a really sturdy email package which was suggested to me by kyber a while ago.

    Also, there is some good advice on this site, take a look around as the OOP journey has been travelled by many others before you.

    If you ignore some of the misguided commentary and "pokes in the dark" from the OP There is some awesome advice coming from some of the PAD regulars.

    If you haven't already done so, then check out this post by harry, some very good resources can be found here - at least it was good to me when I was learning anyway.

    I hope this grass roots type theory aids you in your quest for answers.

    Once you get your head around that, then you take some time out to look at your db. Part of the definition of attributes can be acquired simply by looking at your database structure (if it's properly normalised).

    You could map a database schema into objects (domain objects) and potentially be halfway there.

    For example, reading the brief description of what you're planning to do, I could imagine that you'd have a database with tables like employee and appraisal.

    While in an effort to build tools for your application, you could have objects like email and a db abstraction class.

    It may also help you a little if you try a different angle and look at objects as products of requirements. I might reword your description a little however, I find that using "common nouns" or just nouns in general (such as employee instead of apraisee) is a little more helpful in analysis.

    Let's break down what you have so far, I'll highlight some words that jump out at me, mind you not all of these are relevant, but it would point us to the right direction in finding what classes we need to provide and what attributes a class could have.

    Quote Originally Posted by requirements
    An employee, logs on to the application, his ID fetches his personal info from the database (name, location, dept, etc) he enters further information and submits the form. On submission, his supervisor recieved an email notifying him of a pending appraisal. The supervisor logs in and calls up the staff profile. He inputs his rating, adds his comments and submits. An email is sent back to the employee who must agree or disagree with the supervisor input, once this is done, the appraisal goes to the dept head who adds a comment before sending it to either a higher person or the Human resources department, if no one is higher up in that department.
    Classes:
    Employee - I see an employee as a generic description for someone who works for your/your client's company be it supervisor or regular employee.
    personal info: name, additional info (further information) etc
    email address: since they will be emailed.
    type: normal or supervisor

    Look at your db and try mapping that... You'll also have an appraisal class... comments, ratings... etc.

    HTH

    Regards,

  4. #4
    SitePoint Member stevepop's Avatar
    Join Date
    Mar 2004
    Location
    Lagos, Nigeria
    Posts
    13
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you rvdavid and lix0r for your encouragement and confidence building replies to my post.

    I have learnt a lot from your comments and have started working on the project. I however got stuck somewhere and I am hoping you can help me out.

    I already have a DB class in place where I can connect to my oracle database and fetch data. So now when I employee logs into his profile, he can view his information which exists in the database. I have two files for this as follows;

    <?php
    //File: dblink.php
    //Authentication values for connecting to Oracle Database
    $user="myooptab";
    $paswd = "myooptab";
    $conn = "(DESCRIPTION=
    (ADDRESS_LIST=
    (ADDRESS=(PROTOCOL=TCP) (HOST=localhost) (PORT=1521)))
    (CONNECT_DATA=(SID=myoracledb) (SERVER=DEDICATED)))";

    ?>

    <?php
    Class dbconn {
    var $user;
    var $paswd;
    var $db;
    var $conn;
    var $query;

    function dbconn($user,$paswd, $db)
    {
    $this->user = $user;
    $this->paswd = $paswd;
    $this->db = $db;
    $this->ConnToDb();
    }

    function ConnToDb()
    {
    if(!$this->conn = @OCILogon($this->user, $this->paswd, $this->db))
    {
    $err = OCIerror();
    trigger_error('Could not establish a connection: ' . $err['message']);
    }
    }

    function query($sql)
    {
    if(!$this->query = @OCIParse($this->conn, $sql))
    {
    $err = $err = OCIerror($this->conn);
    trigger_error('Failed to parse SQL query: ' . $err['message']);
    return false;
    } else if(!@OCIExecute($this->query)){
    $err = OCIError($this->query);
    trigger_error('Failed to execute SQL query: ' . $err['message']);
    return false;
    }
    return true;
    }

    function fetch()
    {
    if(!OCIFetch($this->query)){
    return false;
    }
    return $this->query;
    }
    }
    ?>

    ON the profile page, I include the two files above and fetch the data with the following;
    <?php
    require_once 'dblink.php';
    require_once 'dbconn2.php';
    $db = new dbconn2($user, $paswd, $conn);
    $sql = "select * from employee";
    if($db->query($sql)) {
    $row = $db->fetch();
    if($row)
    {
    echo oci_result($row, 'COLNAME');
    }
    ?>

    My problem now is how create methods to update/delete records. Do I have to create these methods in the dbconn class or do i create another class for this? I am really stumped here. What I want is something like this;

    if (submit button is set)
    {
    connect to the database
    update the table with new values
    }

    I did try to create another class but I think I had problems comunicating with the two classes and also the point where the files above are included. I will really appreciate your help. Thanks a lot.

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You would use a separate class

    What you need to do, is to encapsulate that knowledge, the knowledge being to create and update/delete a record. The class which does this would need to know about your database, so you'd pass the connection into the class via the contructor.

    An example of what you are looking for would be an Active Record, to begin with...

    PHP Code:
    abstract class QRecord implements QRecord_Interface {
            protected 
    $db null;
            
            public function 
    __constructQConnection_Interface $db ) {
                
    // passed via concrete implementation
                
    $this -> db $db;
            }
            
            public function 
    insert() {
                
    // ...
            
    }
            
            public function 
    update() {
                
    // ...
            
    }
            
            public function 
    delete() {
                
    // ...
            
    }
            
            public function 
    get() {
                
    // ...
            
    }
            
            
    // ...
        

    Then your concrete implementation would inherit from your abstraction. The class method *::get(); basically returns a row based on an ID,

    PHP Code:
    $record = new QProduct_Record$db );
    $record -> id 'SCH1000';
    $record -> get();
    // ...
    $record -> price '12.99'// new price
    $record -> update(); 
    There are a number of implementations of the Active Record using PHP, so Google to see what you can find; There are other alternatives of course, but the Active Record is more or less, suitable for nearly all tasks.

    It's pretty flexible in my view.

  6. #6
    SitePoint Addict rvdavid's Avatar
    Join Date
    Nov 2006
    Location
    Australia
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi there,
    I did try to create another class but I think I had problems comunicating with the two classes and also the point where the files above are included. I will really appreciate your help. Thanks a lot.
    You are right in creating a separate class - It is one of the basic principles of proper OOP that a class does one thing and does it well. It shouldn't be asked to do too many things as this would make it too omnipotent. So omnipotent in fact that it blurs separation.

    If you were going to pile on methods for each additional feature that requires CReating, Updating and Deleting records in an application context, what if you needed to CRUD records from other tables? you'd then need to add a method for that too, then another, then another.

    So with this in mind, let's have a look at what DR L Proposes - the Active Record Pattern.

    A common definition of an Active Record pattern is a class which represents a single row/record in a db table.

    As DR L demonstrated an active record has a set API and would use your $db object to execute queries.

    As a concrete example for you to follow however, I'll use a single concrete class to demonstrate what an active record does and how it lends itself as a solution to your problem - "how (to) create methods to update/delete records".

    Let's take for example adding an employee to the database. (just so that it doesn't get too nitpicky with properties etc, let's just make believe that your employee db table consists of employee_id, profile, firstname, surname, email fields). I'll only do the insert method as it's pretty much the same principle from that point forward.

    The Employee Active Record.
    PHP Code:
    // active record
    class Employee
    {
            var 
    $_db null;
            var 
    $_table 'employee';
            
            function 
    Employee($db) {
                
    // Like a tool (perhaps a hammer), the Employee Active Record uses the DB object passed in as our intention is to use it to "hammer in" our "nail-like queries" into the database.
                
    $this ->_db $db;
            }
            
            public function 
    insert() {
                
    $sql "INSERT INTO `{$this->_table}` (<whatever fields)
                          VALUES (
                                 
    $this->_db->escape($this->firstname), 
                                 
    $this->_db->escape($this->surname), 
                                 
    $this->_db->escape($this->email), 
                                 
    $this->_db->escape($this->profile)";
                return 
    $this->_db->query($sql);
            }
            
            public function 
    get() {
                
    // ...
            
    }
            
            
    // ...
        

    Using the Active Record
    PHP Code:
    // read requested operation
    if (isset($_POST['submit'])) {  // usually I'd use a request object but for the sake of simplicity I'll grudgingly use the $_POST Super Global.

         // set up the active record.
         
    $activeRecord = new Employee(new dbConn('user','password''review_company');
         
    $activeRecord->firstname $_POST['firstname'];
         
    $activeRecord->surname$_POST['surname'];
         
    $activeRecord->email $_POST['email'];
         
    $activeRecord->profile $_POST['profile'];

         
    // save to database.
         
    $activeRecord->insert();

    This is only a demonstration of active record btw, I didn't really dive too deep into the active record pattern as I skipped it in favour of a Table Data Gateway (this is out of the scope of your question so I'll keave it there). Some people actually create the fields as properties/members on the active record class.

    So to conclude, I agree with DR L's recommendation on active record.

    Instead of

    if (submit button is set)
    {
    connect to the database
    update the table with new values
    }
    We did
    if (submit button is set)
    {
    create a new instance of db and use it to create a new instance of EmployeeActiveRecord
    Set the Active Record up
    Insert, Update or Delete the active record.
    }
    HTH

    Regards,
    Last edited by rvdavid; May 11, 2007 at 16:49.

  7. #7
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    // ...
    public function insert() {
                
    $record = array();
                foreach( 
    $this -> columns as $column ) {
                    if( 
    $this -> $column ) { 
                        
    $record[] = $this -> $column;
                    }
                } 
                
    $sql vsprintf$this -> insertStatement(), 
                    
    array_map'mysql_real_escape_string'$record ) );
                    
                
    $rs $this -> conn -> fetch$sql );
                if( 
    $error $rs -> isError() ) {
                    throw new 
    QDb_Exception$error );
                } 
    You can populate your concrete class with the database columns as I do, which gives you some more flexibility. If there are defaults that you wouldn't like to be included in $sql then leave their class property NULL.

    If you have data coming in from $_GET et al what I do is to pass the Request indirectly to the class instance, via a number of filters... Your name convention therefore can be different in the form, than what you have in your database schema; If there are default columns, typically there are, then the filters would be the layer in which the defaults are added, prior to reaching the specific Active Record implementation...

    PHP Code:
    $adapter = new ... ( $record = new ... ( $request ) );
    $adapter -> addFilterQFilter_Hash_MD5'password' ) ); // new password so hash it
    $adapter -> addFilterQFilter_Date_Now'timestamp' ) ); // add datetime
    // ... etc 


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •