SitePoint Sponsor

User Tag List

Results 1 to 10 of 10

Thread: OOP Articles / Site System

  1. #1
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    OOP Articles / Site System

    Hi, I apologise if this is not the right place. The question is related to the design but coding is also part of it.

    Just so you know I would say i'm a compitent PHP programmer, but I am just delving into classes. Yes they are confusing me more than I ever htought posisble. The more I read the worse it gets so I have some specific questions.

    I am making a site which I want to be OO'ed.

    I have had no problem making a DB class (passed to classes as a reference) with associated Result class (returned to the calling class as the new object). Even a site class and page class. What I am stuck with is my articles system.

    The page break up is:

    Categories : Lists the categories
    Articles : Lists the Articles (with category header / back to category links)
    Article : Displays the article (with back to category links)


    Originally my Articles class had the queries which returned a result and then I simply looped through the arrays as I did procedularily (mysql_fetch_array). This caused issues on the 2nd and 3rd page as I need the category data once the articles have looped. But by this time the result was empty.

    Then I thought a way to get around this (steming back to some uni Java work) would be to have a Category Class and an Article Class.

    However I am driving myself round the bend with how to best interface these results with the DB and the Articles Class which I originally made.

    I don't see how to use the new Category Class for instance on the page.

    $art->cat->getName();

    That is referencing an internal variable which is frowned upon. Even if I do do that where do I loop through the results. Do I pass the result class to the Category Class and the Article Class and let them handle themselves. i.e. Each class then has a NextRow() method (mysql_fetch_array).

    As you can probably tell I am so confused now I don't know what to think, some words of advice on actually using classes would be helpful. All tutorials show you how to use one or maybe two. But not how to have a class make up another class which uses a class....

    [As a note I am thinking back to a Java house building program. This had a house class, which was made of a rectangle class and a square class. Both of these classes were made of Line classes and the line class was made of point classes.] If this is an inappropriate model to base my articles system on then I will stop thinking about it

    Thank you so much for any insight into this design, I have wasted hours so far trying to fully understand it.

    Simon

  2. #2
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The best favor you can do yourself is to read the FrontController and ApplicationController threads. It'll get you familiar with MVC and other helpful patterns.

    And perhaps you should get acquainted with such principles as Inversion of Control and whatnot. There are a few threads on Dependency Injection here (use the search). They should prove useful.

  3. #3
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you I will do that now, it's the pointers I need because without them I don't know what to search for.

    If anyone else has anymore please elt me know.

  4. #4
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    United Kingdom
    Posts
    208
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm my opinion the various value objects for Article, Category etc shouldn't really do much. I would use an Iterator to hold the database resource and just pass that to whatever handles the display. A factory method might be useful to create the correct type of object from the resource. If you feel that this might become a large application then thinking about MVC would be a good idea.

    The Java example is a pretty good one, highlighting the KISS principle. The two threads mentioned however have some very useful stuff in, much more than will get said here.

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would use an Iterator to hold the database resource and just pass that to whatever handles the display.
    This is what I was thinking, but a bit more than that. You mentioned that you had a resultset which had expired after use, and this will happen again with the Iterator. What the Iterator does is just to give you a common Interface for collections and nothing more, so...

    What I would suggest is that create a class that has specific responsibiliites for what you want to do, ie To display an Article for example, and pass the Iterator into this 'Article' class, and then you can use the Iterator from there, indirectly.

    Then later, if you need the resultset for something else, just pawn the Iterator off to another class as required. If you find that you don't need to re-use the resultset after all, just create the Iterator it's self, from within the Article class on instantiation

    Hope this helps you out anyways?

  6. #6
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks everyone, but what exactly is an iterator. I assume it is a class that takes my result set and just returns the rows of data?

    Steming back to my Java example. To activate various member methods in the classes you had to but a reference to each one in the classes above it. So for a SetPointOne(), a reference to this would be in House, Triangle, basically passing the point all the way back to the class it is used in.

    Should I do this for my articles? It would, I think leave a lot of get / set methods in my article class which all basically go $this->cat->getCatName(); With the brunt of the code in $cat->getCatName(); Basically all the data I need would be accessible from the main Articles class. So you could use it in the class creation page as $art->getCatName(); instead of accessing the variable $art->cat->getCatName();

    In turn related to this should I, upon the return of the database results and on each iteration call the setCatName(); methods so that the Category Class basically stores the data and returns it. Therefore allowing category details to come from a result set, an array or even variables?

    I'll be honest I have read so much on all of this, including the above links, thank you. But I need to see a layout I think. So I will design here what I think should be present in my site. What I would like is comments on it. The thoey and design is currently not sinking in. I need to learn from making my damn class work

    Articles Index
    - $e : Error class handler (No problems, runs seperatley, works and is passed as a reference).
    - $art = new ArticleClass($e);
    - $art->GetArticles();

    Articles Class
    -- $res = new ResultSet(); From database query
    -- $data = $this->res->FetchRow();
    -- $cat = new CategoryClass();
    --- $this->cat->SetName($data['cat_name']);

    Articles Index
    Inside result loop (While $art->FetchRow()
    - $art->getCatName();

    Articles Class
    - getCatName();
    -- return $this->cat->getCatName();

    Category Class
    - getCatName();
    -- if (isset($this->CatName)) {
    -- return $this->CatName;
    -- }

    This is how I envisage my new structure.
    A) This seems like a lot of duplication of get / set methods.
    B) If I pass a new row of data as a new Category Class I will always have access to the data I want after I have iterated my articles.
    C) How would an iterator fit?
    D) Is this OOP design of any sort or do I need everything wrapped in a giant big handler class? Should my HTML be returned by templates inside classes rather than everything going back outside the class?

    As you can see I have over confused myself with reading all this. I just need to see how to start, but in a real world situation. Not the good old House() Has Doors() Has Windows() etc style.

    I really do appreciate your patience, the whole not understanding this thing is starting to infuriate me. Thank you

  7. #7
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks everyone, but what exactly is an iterator. I assume it is a class that takes my result set and just returns the rows of data?
    Yes and a bit more besides. To me, the Iterator is a common interface for collections, in a manner that you can easily access and iterator over a collection, which could be an XmlCollection for example, of an SqlCollection, or an ArrayCollection...

    To the script that uses the Iterator, it doesn't matter what the data is, so long as you can swap out the ArrayCollection for an XmlCollection without effecting the script that uses the Collection (in this case, via the Iterator, just that I call an Iterator a Collection instead, but both are the same).

    do I need everything wrapped in a giant big handler class?
    That sounds like your gearing towards some sort of God class and that is bad. A given class has a single responsibility and should have no more.

    Should my HTML be returned by templates inside classes rather than everything going back outside the class?
    Again, it falls back down to responsibility. I would have the results returned to the client script that uses your Articles, etc, and let that generate the results via HTML template, so in answer to your question, I'd return the data, and let something else handle that data.

    The classes in question do not need to know about HTML or UI

  8. #8
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok I think i've cracked it, but a comment on my implementation would be handy. Thanks Dr L (if you don't mind the abbreviation!). I am not 100% on the iterator so I will look that up some more. The information on the HTML is what I was thinking and what I have done so that's good.

    My implementation for the display of categories is as so:

    Main Page

    Create Articles Class
    Call The Query For Categories

    -------- Create a Result Set Class
    -------- Create a Category Class
    -------- Pass a row of data to the Category Class

    In the main page display Category Name by calling $art->getCatName() in the articles class

    ------- The articles class in turn calls $this->cat->GetName();

    Basically in Articles I have wrapper methods for those I use in the main calling page. These relate to methods in the Category Class where the data is manipulated as required.

    Is this wrapper method idea correct for this type of design? If not please do spill the beans, I really can't find any information on using classes like this.

    Thanks everyone I think you've seen me through providing this is right haha

    Simon

  9. #9
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    United Kingdom
    Posts
    208
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here is what I was thinking. A nice UML diagram would be best but I can't figure out ArgoUML right now.

    DrLivingstone and others feel free to nitpick
    PHP Code:
    /**
     * VO object holding article information
     * Pass an array to constructor
     */
    class Article
    {}
    /**
     * VO object holding category information
     * Pass an array to constructor
     */
    class Category
    {}
    /**
     * Iterator pattern implementation
     * Contains methods for manipulating a list
     * e.g. current(), num_rows(), rewind()
     */
    class Iterator
    {}
    /**
     * Base mapper class
     * Contains abstract methods for object relational mapping
     * e.g. write(), update(), delete()
     * perhaps contains a database abstraction object for querying
     */
    class Mapper
    {}
    /**
     * Specific mapper class for an article
     * Contains SQL for object relational mapping
     * implements abstract methods in Mapper
     */
    class ArticleMapper extends Mapper
    {}
    /**
     * Specific mapper class for a category
     */
    class CategoryMapper extends Mapper
    {}
    /**
     * Article validation
     * Contains a few methods for validating a new article
     * isValid() returns true if validation passed
     */
    class ArticleValidator
    {}
    /**
     * Factory class
     * for object creation
     */
    class Factory
    {}

    // article.php
    $cat_id = isset( $_REQUEST['cat'] ) ? $_REQUEST['cat'] : null;
    $art_id = isset( $_REQUEST['id'] ) ? $_REQUEST['id'] : null;

    $mapper = new ArticleMapper;
    // Discover what the request is
    if( $art_id )
    {
        
    $resource $mapper->findById$art_id );
    }
    elseif( 
    $cat_id )
    {
        
    $resource $mapper->findByCategory$cat_id );
    }
    else
    {
        
    // some default action
    }
    // Load the resource in the iterator
    $iterator = new Iterator$resource );
    // Display
    if( $iterator->num_rows() > )
    {
        while( 
    $article Factory::makeArticle$iterator->current() ))
        {
            echo 
    $article->getTitle();
            echo 
    $article->getBody();
        }
    }

    // add_article.php
    if( isset( $_POST['submit'] ))
    {
        
    // Build an article object from POST
        
    $article Factory::makeArticle$_POST );
        
    $validator = new ArticleValidator$article );
        
    // write the new article if it's valid
        
    if( $validator->isValid() )
        {
            
    $mapper = new ArticleMapper;
            if( 
    $mapper->write$article ))
            {
                
    // Redirect somewhere
            
    }
            else
            {
                
    // Some error occurred
            
    }
        }
    }
    // Display an HTML form 
    Last edited by Shrike; Aug 18, 2005 at 03:12.

  10. #10
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For simple UML sketching, try UMLet.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

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
  •