SitePoint Sponsor

User Tag List

Results 1 to 22 of 22
  1. #1
    SitePoint Member
    Join Date
    Oct 2003
    Location
    constance, germany
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Post Building an application using the MVC-pattern

    Bonjour.

    Based on the article and the example files (see http://www.phppatterns.com/index.php...leview/19/1/1/) provided by HarryF from phppatterns.com, I want to build my first application using the MVC pattern.

    Basically, I think that I understood the given example, which provides methods to display (tables of) products. But now I want to extend the application; e.g. I want to add product categories; meaning that there are several categories to which the products belong. Would I now create a new Model/View/Controller - "set", called "CategoryModel" and so on, or would I integrate this into the ProductModel?

    Can anyone (HarryF? ) give me some hints how to extend the example in that way?

    Thanks!

  2. #2
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm.... I'm still learning MVC myself though going by what your asking I'd have to say that you'd be more interested in applying your data, ie Products and their categories to the MODEL Layer ?

    You'd then imply a DAO Layer to be accessed and used by your MODEL Layer ?

    Your CONTROLLER Layer would then use what model you have in your MODEL Layer and pass this over to the VIEW Layer once the CONTROLLER has done it's stuff [what ever you need to do to the data] with the MODEL ?

    That's the way I look at it anyway, from what I've read about MVC and what's been discussed here at Site Point Forums yes ?

    Hope this has helped you...

  3. #3
    SitePoint Zealot
    Join Date
    Sep 2003
    Location
    Melbourne, Victoria, Australia
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I too am new to this, but I'll give it a shot! ...

    It really depends on what you want to do. If you want to add a category attribute to each product then you do this in the ProductModel because it's an attribute of the product.

    If you want to manage a list of categories, then you need to build yourself a new CategoryModel, Controller & View.

    You should be able to retrieve your products and have in each line, it's category (or even sorted by the category, etc.) without having to implement another model\controller.

    I think! ...

  4. #4
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just did a talk for the PHP User Group Switzerland with a simpler example of MVC here: http://wact.sourceforge.net/presenta...HPUGCH/?page=8

    Check pages 9 to 11 for PHP code...

  5. #5
    SitePoint Member
    Join Date
    Sep 2003
    Location
    Lyon, France
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I got a question about this example HarryF => I assume you would have a News class but I don't see what's inside. For instance, do you have a delete method in the News class to delete news or do you have another specific class to delete news (NewsEraser for example)?

  6. #6
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's where things get tricky. The example is meant purely as the simplest MVC demo I could come up with and perhaps the moment you ask that question, the example is already inadequate, if you want a well structured, nicely abstract application. For starters, if you're headed this way, you'd probably have a seperate object for connecting to the database, rather than doing so within the NewsReader...

    Once you start talking about a seperate News class though, you start introducing ideas of having some kind of domain model. The big problem is how you connect this type of object oriented design to a relational database. Martin Fowler in PoEAA spends alot of time on this subject and suggests a number of alternative ways to approach the problem. In other words I can't give you a right answer.

    Here's one way it could be done (hacked together off the top of my head);

    PHP Code:
    <?php
    class NewsReader {
        var 
    $db// Stores database connection resource
        
    var $result;
        function 
    NewsReader() {
            
    // Connect to database
            
    $this->db = & mysql_connect(DB_HOST,DB_USER,DB_PASS);
            
    mysql_select_db(DB_NAME,$this->db);
        }

        
    /**
        * Get the top 10 news items by date
        */
        
    function & findLatestNews () {
            
    $sql "SELECT      *
                    FROM        news
                    ORDER BY    date_published
            DESC
                    LIMIT       0,10;"
    ;
            
    $this->result = & mysql_query($sql,$this->db);
        }

        
    /**
        * Get a single news item
        */
        
    function & findNewsItemById ($id) {
            
    $id mysql_escape_string($id);
            
    $sql "SELECT      *
                    FROM        news
                    WHERE id ='
    $id';";
            
    $this->result = & mysql_query($sql,$this->db);
        }

        function & 
    read() {
            
    $row mysql_fetch_array($this->result,MYSQL_ASSOC);
            if ( 
    $row ) {
                
    $item = & new NewsItem($db);
                
    $item->populate($row);
                return 
    $item;
            } else {
                @
    mysql_data_seek($this->result,0);
                return 
    false;
            }
        }
    }

    class 
    NewsItem {
        var 
    $db;
        var 
    $row;
        function 
    NewsItem(& $db) {
            
    $this->db = & $db;
        }
        function 
    populate($row) {
            
    $this->row $row;
        }
        function 
    getId() {
            return 
    $this->row['id'];
        }
        function 
    getTitle() {
            return 
    $this->row['title'];
        }
        function 
    getDate() {
            return 
    date('H:i:s d-m-Y',$this->row['date']);
        }
        function 
    getBody() {
            return 
    $this->row['body'];
        }
        function 
    getAuthor() {
            return 
    $this->row['author'];
        }
        function 
    create() {
            
    $row array_map('mysql_escape_string',$this->row);
            
    $sql "INSERT INTO
                        news
                    SET
                        title='
    {$row['title']}',
                        date='"
    .time()."',
                        body='
    {$row['body']}',
                        author='
    {$row['author']}';";

            return 
    mysql_query($sql,$this->db);
        }
        function 
    update() {
            
    $row array_map('mysql_escape_string',$this->row);
            
    $sql "UPDATE
                        news
                    SET
                        title='
    {$row['title']}',
                        date='"
    .time()."',
                        body='
    {$row['body']}',
                        author='
    {$row['author']}'
                    WHERE
                        id='{row['id']}';"
    ;
            return 
    mysql_query($sql,$this->db);
        }
        function 
    delete() {
            
    $row array_map('mysql_escape_string',$this->row);
            
    $sql "DELETE FROM
                        news
                    WHERE
                        id='
    {$row['id']}';";

            return 
    mysql_query($sql,$this->db);
        }
    }
    ?>
    To use it, you might have;

    PHP Code:
    $reader = & new NewsReader();

    $reader->findLatestNews();

    while ( 
    $item = & $reader->read() ) {
        echo ( 
    $item->title() );

    Also to update an item you might have (this is just example - the NewsItem class needs to have a better API for modifying / checking the contents of a row)

    PHP Code:
    $reader = & new NewsReader();

    $reader->findNewsItemById(3);

    $item = & $reader->read();

    $item->row['date'] = time();

    $item->update(); 
    But again I stress, that's only one way to do it.

  7. #7
    SitePoint Member
    Join Date
    Sep 2003
    Location
    Lyon, France
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok thanks. That's more or less how I planned to design it.

  8. #8
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Your CONTROLLER Layer would then use what model you have in your MODEL Layer and pass this over to the VIEW Layer
    Then this is wrong yes ? Well, to begin with I did use the Model Layer to begin with though it was pointed out in one thread that it was the Controller that interacted with the View Layer ?

    Umm... Some mis-information from some one I think ?

    Looking at Harry's Presentation and the one I posted the other day over at Oracle I'm going to revert back to the way I was doing things before I took to the suggestion from that thread.

    Shame I cannot remember who pointed out my original script [Model/View] was wrong...

  9. #9
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi Harry...

    Can you help me out?

    I am after a pulling, compiled (to PHP) template engine. The data pull is vital because we have pages that need to paint while data is being calculated. This can take 60+ secs. The templates should be XML compliant (so that we can change templating system if it doesn't work out).

    Do I have to write my own?

    yours, Marcus.

    Edit: OK, just looked at WACT again and see that it has custom tags with some kind of compilation mechanism. I'll have to have a play .

    p.s. For an anti MVC view take a look at teh Naked Objects framework (it's for Java). Very thought provoking.
    Last edited by lastcraft; Oct 9, 2003 at 17:13.
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  10. #10
    SitePoint Addict
    Join Date
    Aug 2002
    Location
    Ottawa, Ontario, Canada
    Posts
    214
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by HarryF
    Just did a talk for the PHP User Group Switzerland with a simpler example of MVC here: http://wact.sourceforge.net/presenta...HPUGCH/?page=8

    Check pages 9 to 11 for PHP code...

    Clicking the above link:
    Code:
    WARNING:
    
    fopen("/home/groups/w/wa/wact/htdocs/presentations/200310_PHPUGCH/templates/compiled/presentation.html", "wb") - Permission denied 
    • /home/groups/w/wa/wact/wact/framework/template/fileschemes/simpleroot/compilersupport.inc.php line 110
    Cheers,
    Keith.

  11. #11
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Got that as well Though the link does work as I've just finished reading it yersterday

    Try and try again I wonder ?

  12. #12
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Whoops - been playing with the server - it's back up now.

    Can you help me out?

    I am after a pulling, compiled (to PHP) template engine. The data pull is vital because we have pages that need to paint while data is being calculated. This can take 60+ secs. The templates should be XML compliant (so that we can change templating system if it doesn't work out).
    The only pure pull template engine I've seen in PHP is with eZ publish 3.x, but I doubt very much that it's going to suit your needs and (right now) the template markup is not XML based.

    That said - I think WACT is your man, so to speak. Right now, some of the WACT tag syntax is HTML-like (badly formed XML) but you don't have to use the non-conforming tags and it's very easy to re-configure as this example demonstrates: http://wact.sourceforge.net/examples/?dir=dotnet . Also I'm $this close to porting the template compile to HTMLSax (the current compiler is regex based and hard to modify - at least for me) - with that done, it should be no problem to support HTML and XML.

    So in other words, with some fine tuning which is already in progress, WACT templates can be well formed.

    As to your problem, ignoring any well formedness issues for a moment, I think it should be very easy to implement.

    The <list:list /> tag ( see here) will be what you need. It expects to be provided a data set which conforms to the DataSpace Interface for accessing a single "row" of data, as well as the Iterator to step through the rows. You may need to have a slightly modified version of the list, which calls PHP's flush function after each iteration.

    To modify it, you'll need to find this file, which is a compile time component. Insert, between lines 58 and 59, the following;

    PHP Code:
    $code->writePHP('flush();'); 
    There's more about developing components here as well as how the architecture works here.

    The only issue will be have an web services client (I believe that's what you're doing) which is smart enough to connect / make request only when iteration starts then beginning spitting out data before it's recieved the complete response. You'll need to implement the DataSpace and Iterator interfaces as mentioned. For inspiration, Jeffs MySQL RecordSet may help (note, before you're put off, those function calls at the start are obsolete in the latest versions, replaced with a gateway class to the database drivers, but the API docs haven't caught up yet).

    Isn't it nice to have a (fairly) well documented Open Source project Now all it needs is a release (not far off).

  13. #13
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    p.s. For an anti MVC view take a look at teh Naked Objects framework (it's for Java). Very thought provoking.
    One other thing. I've seen people saying the event model of ASP.NET is actually an alterative to struts style MVC.

    In other words that have stuff like (interpreted in PHP);

    PHP Code:
    if ( $Page->isPostback() ) {
        
    // The page was posted

    Which (IMO) is no different to;

    PHP Code:
    <?php
    if ( count ($_POST) > ) {
        
    // The page was posted
    }
    ?>
    They also a way to connect up page elements to call back functions e.g.;

    You have a template like;

    Code:
    <input type="submit" onClick="myCallback" id="myButton">
    You can then define a callback like;

    PHP Code:
    <?php
    function myCallback (& $sender$args) {
       
    // Do something
    }
    ?>
    In some ways it's nice but in others it's pretty dumb. It requires a form be aware of it's own state (i.e. it can compare itself to how it was on the page before submission) to know when it's been used, which is achieved with an encrypted hidden field (there's already decrypters out there which will no doubt help hacking ASP.NET apps...).

    In other words, it's basically the same as struts but a little more hidden. Where it's dumb is demonstrated nicely here;

    http://aspnet.4guysfromrolla.com/dem...gDataGrid.aspx

    Click on the next / prev links and watch how the URL changes... oh wait.... the URL didn't change. So how are you going to send someone a link to page 4, for example? SOAP already got slapped around by the REST argument - having a SOAP listener capable of many methods, all using a single URL misses the whole point of URLs.

    Compare that with the WACT presentation system I knocked up, using Jeffs pager component, which allows me to identify a single page with a URL: http://wact.sourceforge.net/examples...dex.php?page=3

    In WACT, it would be farily easy to implement an event model like ASP.NET but whether it's worth it is another question. First there'll likely be a significant overhead in processing the event related code - right now WACT is very fast. Second it's more likely to confuse and (if it's required to use it) will reduce WACTs flexibility - right now you could probably replace, say, Smarty with WACTs templating engine in some application, without having to change anything else.

    Anyway...

  14. #14
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    there's already decrypters out there which will no doubt help hacking ASP.NET apps...


    And who do we have to thank for .NET ? Yep, Microsoft

    Now, isn't this typical of Microsoft to develop dumb huh ?

  15. #15
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I probably shouldn't say that being able to de-crypt the hidden field automatically means you've hacked the app. Thing is I can imagine it lulling people into a false sense of security and performing less checks as a result. It's an uninformed view - I'm just naturally suspicious of anything that comes from the browser.

  16. #16
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm just naturally suspicious of anything that comes from
    ... Microsoft

  17. #17
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by HarryF
    The only pure pull template engine I've seen in PHP is with eZ publish 3.x, but I doubt very much that it's going to suit your needs and (right now) the template markup is not XML based.
    The real requirement is simplicity. All the other code will be written as a result of implementing the system as web services. It is only the template compiler we need.

    Quote Originally Posted by HarryF
    That said - I think WACT is your man, so to speak.
    I am going to look at it pretty soon. Right after wire frames and Haxml .
    The front runner is an in house design still, as we are only really after a simple custom tag solution rather than a complete framework.

    Quote Originally Posted by HarryF
    The <list:list /> tag ( see here) will be what you need.
    Placing a callback in an iterated widget was what I was thinking. My spec. is really being able to do a simple progress bar by feeding the page JavaScript method calls until the main result is ready.

    Quote Originally Posted by HarryF
    which is a compile time component.;
    The compile time component system is outstanding.

    Quote Originally Posted by HarryF
    The only issue will be have an web services client (I believe that's what you're doing)
    The app. is fast becoming seriously N-tier, but in fact the actual reason is that we have a huge quantity of full text data to search live. Even specialist engines take their time with our data requirements.

    Quote Originally Posted by HarryF
    Isn't it nice to have a (fairly) well documented Open Source project Now all it needs is a release (not far off).
    And the code is clean and easy to read. How are you doing recruiting test writers? (I am not volunteering, although I did an update to the HtmlSax).

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  18. #18
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It is only the template compiler we need. [...] as we are only really after a simple custom tag solution rather than a complete framework.
    That's the other reason against eZ publish and for WACT. You can use just the template engine and next to nothing else - it can be used in a Smarty-like manner, simple using replacement variables, e.g.;

    Code:
    <h2>{$title}</h2>
    {$table}
    PHP Code:
    <?php
    $Page 
    = & new Template('example.html');
    $Page->set('title','This is an example');

    $table = <<<EOD
    <table>
    <tr>
    <!-- etc etc -->
    </table>
    EOD;

    $Page->set('table',$table);
    The list tag saves alot of work though. What you could do is make use of the ArrayDataSet which allows you to build the data structure yourself, like this. That will mean some minor mods to the list compile time component, to allow you to add data to it while iteration is in progress.


    Alternatively, this should be doable without modifying the list at all - you just need the class from which $wsRecordSet is created (below in the example).

    To implement the call back, you could use the DataSetDecorator.

    First a template;

    Code:
    <list:list id="WSResponse">
    <table>
    <caption>Web Service Response</caption>
    <list:item>
    <tr>
    <td>{$Col1}</td>
    <td>{$Col2}</td>
    </tr>
    </list:item>
    </table>
    </list:list>
    And the example;

    PHP Code:
    // A call back function
    function myCallBack() {
        echo ( 
    'Be patient; its coming...');
    }

    // A record set object which implements DataSpace and Iterator
    // interfaces - uses your existing web services client
    $wsRecordSet = & WSCM::NewRecordSet('articles.getLatest');

    // The decorator, counting the incoming rows of data;
    class WSDecorator extends DataSetDecorator {
        function 
    next() {
             static 
    $rowcount 0;
             if ( 
    $rowcount == 10 ) {
                  
    $rowcount 0;
                  
    call_user_func('myCallBack');
             } else {
                  
    $rowcount++;
             }
             
    parent::next();
        }
    }

    // Apply the decorator
    $wsDecorator = & new WSDecorator($wsRecordSet);

    // Load the template
    $Page = & new Template('wsresponse.html');

    // Get the list as a runtime object
    $WSResponse = & $Page->getChild('WSResponse');

    // Register the decorator
    $WSResponse->registerDataSet($wsDecorator);

    // Show the page
    $Page->display(); 
    WACT really is more of a toolkit than a framework (as it says on the packet). Think that alot of what it does will end up getting implemented as part of the core of PHP in the near future (there's talk of implementing something ADO.NET record sets like at an engine level for example - what WACT does with a PHP class).

    Anyway - nuff of the "hard sell".

  19. #19
    SitePoint Zealot
    Join Date
    Sep 2003
    Location
    Melbourne, Victoria, Australia
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question

    This Q is in regards to MVC so I thought I'd place it in here.

    Using a FrontController pattern, take the following url as an example:
    Code:
    index.php?do=someCommand&foo=bar&me=I
    The URL is often made up of information from a config style file and\or data delivered from the model.

    My question: Where would you put code that constructed the URL of a link - Model, View or Controller?

    To me, the View seems logical but I've found instances where I need to use an if() statement or similar to determine URL components. My feeling is that this clutters the View with too much unecessary code that really relates to the application and not the display functions.

    Controller looks like the next best thing. Only problem here is when you have a list of items to iterate through you do it once here, and then again in the View to print them out!

    Lastly, we have the Model. Definitely not the obvious choice (IMO).

    I am keen to hear some thoughts on this.

    Cheers,
    Af.

  20. #20
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would have to assume that URLs such as that are part of the VIEW ? The reasoning behind this as I see it is that the actual A HREF Links themselves are part of the User Interface no ?

    Unless, how else would the user be able to a certain degree, control the UI ? I wouldn't worry too much about it though; I leave all my A HREFs in the HTML and it ain't broke... Yet

  21. #21
    SitePoint Zealot
    Join Date
    Sep 2003
    Location
    Melbourne, Victoria, Australia
    Posts
    115
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks and I totally agree with you there.

    Distinct from the actual rendering of the A HREF, what about the decision making around which command to call etc.? Espec. when these are related to the MODEL itself (eg. I'm an event and therefore you have to action me using xyz command) Is this more controller then view?

    I've been looking at template enginges far too long! :/ Seems like these engines imply that you should have very little (if none at all) code in the VIEW. I guess what you're saying here is that code which determines and runs the UI is obviously acceptible.

    Cheers,
    Af.

  22. #22
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess what you're saying here is that code which determines and runs the UI is obviously acceptible.
    Yes, Presentation Logic as Harry has shown in his recent presentation; For testing, I have PHP embedded in HTML which it could be said to be Presentation Logic as the script builds navigation tabs ?

    If your in doubt remember that if the PHP used as is with HTML needs to do more than READ then that PHP shouldn't be in the HTML;

    By READ I mean more than simply to read in variables from objects for example, or arrays yes ?

    This is how I see it anyway

    Is this more controller then view?
    I would think the Controller Layer ?


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
  •