SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 28
  1. #1
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Location
    Sweden
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Concrete and complete ultra simple MVC example

    Hi, I don't know of any "code snippet/comment" part here on Sitepoint. I hope I'm not violation any rules.

    Warning! This is a long post so for you with little patience just scroll down to the code and take a look at what can/should be done differently.

    If you are nice to comment the code. Please don't mind small issues, mention them ("take a look at the method for querying the datbase" or something) if you want to (it will probably help later) but remember that it is the MVC part that's critical for me. With an "MVC base" I can then take a look at the code I've written just to get it working.

    I've been trying to learn MVC for a while and I think(!) I get most of the large picture. Though I do miss concrete exemples that actually perform a complete action (http request -> presentation). I could ask for someone to write an example that actually could be used more or less right away, but I figure it's better manner to present something of my own. If I'm totally lost I would of course appreciate a complete example, otherwise please just comment on my code.

    I hope that this (eventually) can cover that lost part between theoretical pages like http://www.phpwact.org/pattern/model_view_controller and abstract code examples like the sticky in this part of the forum.

    Maybe some of you think that the examples are just perfect but I don't. I honestly think that there is a gap that needs to be filled, at least in my head.

    I will present the code in a "line of execution" so you can follow every file/action from HTTP request to presentation. There are some parts I'm not sure about and I'm sure it's far from perfect. It works though!

    The (abstract?) databse connection will be presented in the end.

    Here we go, I hope I won't forget anything.

    index.php
    PHP Code:
        include("inc/definitions.php");
        include(
    "inc/Database/MySQL.php");
        include(
    "inc/View/View.php");

        switch(@
    $_GET['page']) {
            case 
    "news":
                include(
    "inc/Command/NewsCommand.php");
                
    $command = new NewsCommand();
                
    $command->execute();
                break;
            default:
                include(
    "inc/Command/AboutCommand.php");
                
    $command = new AboutCommand();
                
    $command->execute();
                break;
        } 
    The call is for news (no news id specified).

    NewsCommand.php

    PHP Code:
    class NewsCommand {
        function 
    execute() {
            include(
    "inc/Model/NewsModel.php");
            
            
    $news = new NewsModel();
            
            if(isset(
    $_GET['newsid']))
                
    $news->setSpecificNews($_GET['newsid']);
            else
                
    $news->setStandardNews();
                
            
    $view = new View("news.tpl.phtml");
            
    $view->render($news);
        }

    Now we need the NewsModel

    NewsModel.php
    PHP Code:
    class NewsModel {
        function 
    setStandardNews() {
            
    $db MySQL::getInstance();
            
    $db->doQuery("SELECT Title,Text,Nick,Date FROM news ORDER BY NewsID DESC LIMIT 5");
            
    $newsResult = array();
            while(
    $result $db->fetch_assoc()) {
                
    $news["title"] = $result['Title'];
                
    $news["content"] = $result['Text'];
                
    $news["user"] = $result['Nick'];
                
    $news["date"] = $result['Date'];
                
    array_push($newsResult,$news);
            }
            
    $this->news =  $newsResult;
        }

        function 
    setSpecificNews() {
            
    $newsid $sys->secure($_GET['newsid']);
            
    $newsResult $db->result("SELECT Title,Text,Nick,Date FROM news WHERE NewsID = ".$newsid."");
            
    $this->news $newsResult;
        }
        
        function 
    getNews() {
            return 
    $this->news;
        }

    Now we are moving to the View

    View.php
    PHP Code:
    class View {
        function 
    __construct($template,$title=title,$description=description,$keywords=keywords) {
            
    $this->template     $template;
            
    $this->title         $title;
            
    $this->description     $description;
            
    $this->keywords     $keywords;
        }
        
        function 
    render(&$model="") {
            include (
    "inc/html/template/".$this->template);
        }

    The view calls for a template.

    news.tpl.phtml
    PHP Code:
    <?php
        
    include("inc/html/header.phtml");
    ?>
    <h1>News</h1>
    <dl id="news">
        <?php foreach($model->getNews() as $k => $news):?>
            <dt><span class="floatLeft"><?php echo $news["title"];?></span><span class="sf floatRight"><?php echo date("Y:m:d",$news["date"]);?></span></dt>
            <dd>
                <?php echo $news["content"];?>
            </dd>
            <dd class="user">
                <?php echo $news["user"];?>
            </dd>
        <?php endforeach;?>
    </dl>

    <?php
        
    include("inc/html/footer.phtml");
    ?>
    I'm gonna leave the header and footer out of this

    For databse connection I use Databse.php and MySQL.php take a look.

    Database.php
    PHP Code:
    abstract class Database {
        
        abstract function 
    __construct($host$username$password$database);
        
        abstract public static function 
    getInstance();
        
        abstract function 
    connect();

    MySQL.php
    PHP Code:
    include("inc/Database/Database.php");

    class 
    MySQL extends Database {

        private static 
    $instance;
        
        function 
    __construct($host,$user,$password,$database) {
            
    $this->host            $host;
            
    $this->user            $user;
            
    $this->password        $password;
            
    $this->database        $database;
            
    $this->connect();
        }
        
        function 
    connect() {
            if( !
    $db mysql_connect($this->host,$this->user,$this->password) )
                echo 
    "Could not connect to database";
            elseif( !
    mysql_select_db($this->database$db) )
                echo 
    "Could not select database";
            else
                
    $this->db $db;
        }
        
        public static function 
    getInstance($host='HOST'$username='USERNAME'$password='PASS'$database='DATABASE') {
            if(!isset(
    self::$instance)) {
                
    $c __CLASS__//This gets the class name of the current class
                
    self::$instance = new $c($host$username$password$database);
            }
            return 
    self::$instance;
        }
        
        function 
    doQuery($string) {
            
    $this->query mysql_query($string) or print(mysql_error());
            return(
    TRUE);
        }
        
        function 
    fetch_assoc($query "") {
            if(
    $query != "") {
                
    $this->query mysql_query($query);
            }
            
    $result mysql_fetch_assoc($this->query) or print(mysql_error());
            return(
    $result);
        }
        
        function 
    result($query "",$position 0) {
            if(
    $query != "")
                
    $this->query mysql_query($query);
            
    $result mysql_result($this->query,$position);
            return(
    $result);
        }
        
        function 
    num_rows($query "") {
            if(
    $query)
                
    $this->doQuery($query);
            return(
    mysql_num_rows($this->query));
        }
        

    For those of you who read everything and are willing to help, thank you so much. I'm in a situation where I feel I have read tons of articles and looked many examples but still don't get the whole thing. It feels like this is my last shot in the world of MVC.

    Thanks in advance!

  2. #2
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    United Kingdom
    Posts
    208
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What are the parts that you think aren't perfect? The coding aside the important part of MVC is there, that is, the separation between model and view. The code could certainly be tidied up but thats what refactoring is all about.

    I'd consider creating some abstract classes for Command and View, and also have the Command return the View object to index.php rather than the View displaying itself.

  3. #3
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AbraKadabra
    index.php
    PHP Code:
        switch(@$_GET['page']) {
            case 
    "news":
                include(
    "inc/Command/NewsCommand.php");
                
    $command = new NewsCommand();
                
    $command->execute();
                break;
            default:
                include(
    "inc/Command/AboutCommand.php");
                
    $command = new AboutCommand();
                
    $command->execute();
                break;
        } 
    *BEEP* ERROR #137: Don't Repeat Yourself. As it is, you'll also have to touch index.php every time you wish to create a new page. I suggest changing to something that checks if there is a Command that could respond to a given page request.

  4. #4
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    include("inc/definitions.php");
        include(
    "inc/Database/MySQL.php");
        include(
    "inc/View/View.php");

        switch(@
    $_GET['page']) {
            case 
    "news":
                include(
    "inc/Command/NewsCommand.php");
                
    $command = new NewsCommand();
                
    $command->execute();
                break;
            default:
                include(
    "inc/Command/AboutCommand.php");
                
    $command = new AboutCommand();
                
    $command->execute();
                break;
        } 
    I feel the same way about switch as I do about the regular suggestion to use CoR for front controllers -- its clunky. Below is a very basic example, but I think it shows the idea of a Front Controller that generates the file and class names. It obviously needs to be refactored to add an error handling scheme. The first step would be to move the mapping code out because it needs to be accessed several places.
    PHP Code:
    $action = isset($_GET['page']) ? preg_replace('/[^a-zA-Z0-9]/'''$_GET['page']) : $default_action;
    $class_name $action 'Command';
    $file_name 'inc/Command/' $class_name '.php';
    if (
    file_exists($filename)) {
        
    $command = new $class_name();
        if (
    method_exists($command'execute')) {
           
    $command->execute();
        } else {
           
    // handle error here
        
    }
    } else {
        
    // handle error here

    But a Front Controller is not actually part of MVC (but does often occur in MVC implementations).

    My question would be how could you make a base Controller class that NewCommand could inherit that would move the busy-work into a common class that all Controller Commands could use?
    Christopher

  5. #5
    SitePoint Zealot
    Join Date
    Oct 2004
    Location
    naperville
    Posts
    189
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'd feel better about you handing a ViewHelper with just the data needed instead of the actual model to the View.

  6. #6
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I would also separate your SQL from the class(es) that require them. The benifit of this is that the class that uses the SQL shouldn't be concerned as such, what that SQL is; It basically means that you can easily replace SQL for MySql with Postgre more easily, and without making any changes to your scripts.

    For example,

    PHP Code:
    // ...
    function setStandardNews() {
            
    $db MySQL::getInstance();
            
    $db->doQuery("SELECT Title,Text,Nick,Date FROM news ORDER BY NewsID DESC LIMIT 5");
            
    $newsResult = array();
    // ... 
    Instead I would have something like this

    PHP Code:
    function setStandardNewsIStatement $statement ) {
            
    $db MySQL::getInstance();
            
    $db->doQuery$statement -> standardNewsSql() );
            
    $newsResult = array();
    // ... etc ... 
    The $statement::standardNewsSql(); would return the SQL as expected. So you at a later date, change from MySql to Postgre, you change the $statement class and nothing more - the API you have to communicate with the database of course, would therefore have to be consistent over your choice(es) of database vendor

    But it makes your life easier at the end of the day, doesn't it.

  7. #7
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Location
    Sweden
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am so glad that the basic MVC seemes to be allright. That was my main goal to start with.

    I will look into (and probably change) all the things mentioned except maybe the switch. I'm gonna change it but I think I'm gonan use a string with "accepted" files and different strings for different things.

    Simplified, a string for each folder (each part of website) to get better structure. I don't want it all in one place.

    I'm not sure of how the abstract classes for command and view would look like, but I'll think it over.

    The repeating of $command->execute(); is a perfect example of the flaws in this early and basic MVC example. But thanks anyway, I'm going to change it.

    The SQL comment from DR Livingstone is perfectly clear and I think I agree. I hav enot looked into how much extra work (and methods to organize) that would cause. I think it depends a little on how you are planning the future for the site. A universal e-commerce system for sale might need it, but maybe not pages more like hobby porjects. I do understand the advantages in being able to easily move between databases though.

    Quote Originally Posted by Super Phil
    I'd feel better about you handing a ViewHelper with just the data needed instead of the actual model to the View.
    I'm not sure about what u mean except that u don't like when I pass the actual model as it is. How could I do it differently? Do you mean that I should create a new class that just contains the info from the model? Isn't that going to cause a lot of extra classes and thus cost more then it gives?


    Thanks for all the input. I will keep on working and I might even be cocky enough to post a later "version" to give a simple and concrete example for all those who are new to MVC. I know I'm far from an expert, but as I said I miss that part on all tutorials/articles I've read. It's better with something than nothing, right? We will see how much time I have.

    More suggestions are still very welcome!

  8. #8
    SitePoint Zealot
    Join Date
    Aug 2002
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AbraKadabra
    The SQL comment from DR Livingstone is perfectly clear and I think I agree. I hav enot looked into how much extra work (and methods to organize) that would cause. I think it depends a little on how you are planning the future for the site. A universal e-commerce system for sale might need it, but maybe not pages more like hobby porjects. I do understand the advantages in being able to easily move between databases though.


    I'm not sure about what u mean except that u don't like when I pass the actual model as it is. How could I do it differently? Do you mean that I should create a new class that just contains the info from the model? Isn't that going to cause a lot of extra classes and thus cost more then it gives?
    i think you have these two bits the wrong way round, I would disagree with the comments from Dr Livingstone and agree with passing an object to the view, although i believe in a different implementation to a view helper.

    Creating a new SQL object for each database assumes that each database server uses a different sql-like language for queries, they don't, the majority infact use sql so there is no problem here*, using a statement class is abstraction for abstraction's sake and a massive waste of time in my opinion.

    passing a view helper to the view is also a waste of time (instead of the view knowing about the data you now have a view helper which knows about the data?), it just makes each view a view+a view helper. however, one thing about this is right, the view shouldn't really know anything about the data it is using, so why not pass it an iterator/queryiterator/fileiterator/arrayiterator/something else similar that can be re-used across many many views so instead of a view being a view+view helper it's simply a view+one class from a standard library that all views can use.

    $0.02


    *i know some have their own extentions to the sql syntax however the majority of web apps are going to be simple select/insert/update etcetc.

  9. #9
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    using a statement class is abstraction for abstraction's sake and a massive waste of time in my opinion.
    Maybe as suggested, for smaller applications, this may well be overkill I suppose, but not so for other reasons; If the SQL changes it's self, then the classes that utilise a IStatement class, don't change at all, but it's the statement class that would change.

    From a maintenance and a refactoring point of view, it's a lot easier just to do the refactoring externally from the class that uses IStatement. Some people require more than simple CRUD as well, which I think should be taken into consideration

    Also, the reason you want to use a ViewHelper, is that the ViewHelper would be called for, for presentation logic that you don't want in a View; In a lot of cases, it's difficult to implement request specific presentation logic within a View anyways - I know from experience btw - so you need to use a ViewHelper to govern that logic.

    Once the ViewHelper has been executed, what it does is to return the formatted output all ready for insertion by the View; The Model goes to the ViewHelper, so the View doesn't even know about it - Which leaves the View to do it's real job of managing the template.

    Add,

    You might want to spend more time constructively learning design patterns, rather than negatively denouncing them as a waste of time; You are not helping anyone.

  10. #10
    Umm. PHP Guru....Naaaah jaswinder_rana's Avatar
    Join Date
    Jul 2004
    Location
    canada
    Posts
    3,193
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    I would also separate your SQL from the class(es) that require them. The benifit of this is that the class that uses the SQL shouldn't be concerned as such, what that SQL is; It basically means that you can easily replace SQL for MySql with Postgre more easily, and without making any changes to your scripts.
    What is easier?

    Changing the SQL when database is changed??
    OR
    Having a class which generates SQL statement depending on the database type currently in effect (mentioned in configuration file liek $cfgArr['db']['type'])?? Not sure, if that is what you call "Data Mapper".
    ---------------------------
    Errors = Improved Programming.
    My Site

  11. #11
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you know for the lifetime of the application that the database will not change, then my thoughts are redundant I suppose, but on the other hand, if there is any doubt, then abstracting the SQL gives more flexibility.

    As to how you implement those $statement classes, their usage is loosely based on configuration as you suggest, but a Factory could easily be used to return an instance of the required class in any case...

    With PHP5s Reflection API you could even generate those classes dynamically, and cache them as well, so concerns of too many classes are resolved, no?

  12. #12
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Location
    Sweden
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Also, the reason you want to use a ViewHelper, is that the ViewHelper would be called for, for presentation logic that you don't want in a View; In a lot of cases, it's difficult to implement request specific presentation logic within a View anyways - I know from experience btw - so you need to use a ViewHelper to govern that logic.

    Once the ViewHelper has been executed, what it does is to return the formatted output all ready for insertion by the View; The Model goes to the ViewHelper, so the View doesn't even know about it - Which leaves the View to do it's real job of managing the template.
    Sorry but I'm still not sure of what the ViewHelper would really do to help. As it is now, the view calls for a method in the Model that returns formatted output. In my example it returns an array of news. I can't see what a helper could do it better.
    Im sensing that you mean that it would help for cases where it's not as easy as returning an array, am I correct? In case I am, do you have a good example?
    Otherwise Im lost, is it just because the view shouldn't talk/get info directly from the model?
    I thought the task of the Model was to collect, manage and format data for the view to present. Isn't that what I'm doing?

    On the SQL discussion I still stand for what I wrote in my previous post. I think Dr L's comment could be good, the question for me is if it's worth the trouble. Maybe it is, I have still not an opinion in my case.

    A different question. How do you handle static content and/or "side pages"? By that I mean login, navigation menu etc.

    If the content is static (a menu for example), do you just include "menu.tpl.phtml"?

    If it contains some kind of logic do you use the same procedure with controller, model and view?

    For example it could be the login part where a form is presented if user is not logged in and some info/links if user. Another example would be a small info box with "latest posts on forum" and a need for database contact.

    Spontaneously it feels a bit overkill, but maybe it's not?

    Finally, where do you place this? is it in the "header"/"footer" or do you implement it in the "main templates" (new.tpl.phtml for example)?

    I really appreciate all the comments, thank you!

  13. #13
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A lot of these questions were covered in the Skeleton threads. You might want to take a look at the Skeleton threads or download my fork here. It has mappers for generated, lookup and static HTML. There is a reasonable Front Controller implementation with an Intercepting Filter wrapper that can optionally be used. It also implements Request/Response objects (and Service Locator) which you have not touched upon yet and that solve problems like freeing you from the header/footer style page building. The intent of the code is to give people ideas and have a codebase that people can adapt to their needs. There are some examples, but unlike a framework the code is not meant to be used as is.

    I have often thought that a base MVC Controller class would be a handy thing to have. Something that would implement an abstract/base form of your NewsCommand. It would be what frameworks sometimes call an Action class. I think like the Skeleton Front Controller, you should be able to pass it a Mapper for loading the Model and View (or multiple Ms and Vs?) that way different schemes could be implemented (e.g. generated, lookup, etc.).

    You would probably find the code interesting as it shows some ways to implement questions you are asking. Actually, as you seem to have the MVC division down pretty well, if you hack up something interesting like you have above it might be helpful to others to integrate it and some examples into the Skeleton code. Ezku also has a separate fork of the code done in a slightly different style that would give you great ideas as well.
    Christopher

  14. #14
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A Model is a container for your data in question, and the logic - business logic, not presentation logic - that is concerned with that data. A Model is only concerned with the data, and nothing more; There are no formatting at all within a Model.

    That is why we have a ViewHelper - it separates the formatting away from the main View

    A good example of a ViewHelper would be the one from my 'Design Patterns' thread,

    http://www.sitepoint.com/forums/showthread.php?t=248721

    Which I hope helps you understand more? Doing a search on this forum may help as this pattern has picked up some discussion.

    If it contains some kind of logic do you use the same procedure with controller, model and view?
    Yes, I do. For me, I found that the Composite pattern helps to glue various parts of a page together, s each Composite manages each part in turn - again, try doing a search on this forum, as there has been a lot of discussion on this pattern.

    PHP Code:
    // here is an example,
    $page = new PageHandler();
    $page -> attach$header = new HeaderHandler() );
    $header -> attach( new SearchBoxHandler() );
    $page -> attach$body = new BodyHandler() );
    $body -> attach( new ShowNewsHandler() /* list news items */ );
    $page -> attach( new FooterHandler() );
    // ... 

  15. #15
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Location
    Sweden
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    arborint I will look into that and I do think it can help me (I glanced through the zip) BUT the big but is that the zip file contains sooo many files. I'm not saying it's bad code or that it's not very good for some people. But that is just what I would call a non-simple example. Simple code snippets for each task (or a few at a time) would make it so much easier and faster to learn.
    I will look into it though it is a little late in Sweden now.
    Thank you.


    Dr Liv. The Helper really feels like overkill. Is it really commonly accepted to do it that way? I may mix in some formatting in the model but isn't it a small thing when I get rid of the helper and a whole "step" in the process?
    Sometimes I get the feeling that people want to have a class for every little action they do.

    In Sweden we have a great word, "lagom". The dictionary says "enough, sufficient, adequate, just right" and I say not too much and not too little.
    I'm not propagating skipping all the classes (then we would have no MVC), but one has to draw a line somewhere.
    I'm not stupid though, if it is how it's done I might have to accept it and try to see the good side of it.

    The Composite stuff semes really good. I recognize it but I don't think I was really ready for that part when I read about it. I might be ready now though, thanks!

  16. #16
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AbraKadabra
    arborint I will look into that and I do think it can help me (I glanced through the zip) BUT the big but is that the zip file contains sooo many files. I'm not saying it's bad code or that it's not very good for some people. But that is just what I would call a non-simple example. Simple code snippets for each task (or a few at a time) would make it so much easier and faster to learn.
    I will look into it though it is a little late in Sweden now.
    Thank you.
    Actually part of the motivation for Skeleton was exactly what you are expressing. Take a look in the examples/misc folder for the simple controller examples. There are less than 10 files needed for each example and if you wanted to go minimal you could halve that. You first post has 7 files so I think Skeleton is in the style you will like. My feeling is that each request should need less than 20 files. I think the Front Controller only needs 5 files (Locator, Request, Response, ActionMapper and FrontController) to run but is by many accounts much more flexible than necessary.
    Quote Originally Posted by AbraKadabra
    The Helper really feels like overkill. Is it really commonly accepted to do it that way? I may mix in some formatting in the model but isn't it a small thing when I get rid of the helper and a whole "step" in the process?
    Sometimes I get the feeling that people want to have a class for every little action they do.
    I agree that ViewHelpers should be implemented when needed and not just as a standard piece. Most Views don't need help as the Model is straightforward.
    Quote Originally Posted by AbraKadabra
    In Sweden we have a great word, "lagom". The dictionary says "enough, sufficient, adequate, just right" and I say not too much and not too little.
    I'm not propagating skipping all the classes (then we would have no MVC), but one has to draw a line somewhere.
    I'm not stupid though, if it is how it's done I might have to accept it and try to see the good side of it.
    Again I agree with "lagom". It sounds like DRY and YAGNI rolled into one.
    Christopher

  17. #17
    SitePoint Zealot
    Join Date
    Aug 2002
    Posts
    180
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Maybe as suggested, for smaller applications, this may well be overkill I suppose, but not so for other reasons; If the SQL changes it's self, then the classes that utilise a IStatement class, don't change at all, but it's the statement class that would change.

    From a maintenance and a refactoring point of view, it's a lot easier just to do the refactoring externally from the class that uses IStatement. Some people require more than simple CRUD as well, which I think should be taken into consideration
    i do not think an a statement class aids you that much. i can see the benefits of keeping all of your sql in one place if that makes it easier for you to follow/understand. however, personally, i feel the downsides of having a seperate class vastly out-weigh the benefits in an application of any size.

    first of all, you have to consider the number of times you do actually require functionality other than CRUD that is not already covered by standard sql syntax.

    secondly, take into account that you might not be the person maintaining this code. this person is going to have an unpleasent job if they require more than an exact clone of your statement class for another db. also, if they want to change something they would have to track it down in your code and make sure they're not going to break the implementation with their changes, so why not have the sql there anyway.

    also, you may have to come back and maintain this code again at some point in the future and unless you remember exactly what you were doing any why you too are going to run into these problems.

    Also, the reason you want to use a ViewHelper, is that the ViewHelper would be called for, for presentation logic that you don't want in a View; In a lot of cases, it's difficult to implement request specific presentation logic within a View anyways - I know from experience btw - so you need to use a ViewHelper to govern that logic.

    Once the ViewHelper has been executed, what it does is to return the formatted output all ready for insertion by the View; The Model goes to the ViewHelper, so the View doesn't even know about it - Which leaves the View to do it's real job of managing the template.
    personally, i think the view should be used for the presentation logic, adding another class to deal with that is a level of abstraction that is not needed. KISS. On a side note: I would like to see an example, from your experience, where it was difficult to implement presentation logic in the view.

    Add,

    You might want to spend more time constructively learning design patterns, rather than negatively denouncing them as a waste of time; You are not helping anyone.
    i dont recall ever denouncing design patterns as a waste of time. design patterns are not a strict set of rules that must be followed to the letter. they are rough guidelines that aid you in making choices to develop better and more managable software. I am a huge fan of KISS and if something is abstract for the sake of it or adds a level of complexity that really isnt needed i believe it should be avoided.

    i know i am not the first person on this board to point it out, but your own view of your programming skills and knowledge is far greater than many other people believe it to be. this is not really the place for personal attacks, so as for your last comment, i hope to achieve my masters soon, when you have your phd in a computing related field come back to me and i'll be willing to talk.

  18. #18
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    also, you may have to come back and maintain this code again at some point in the future and unless you remember exactly what you were doing any why you too are going to run into these problems.
    I would have to say that is why we have documentation for. But documentation only helps so far I admit, but to ease the problem you have highlighted, you can limit the problem further by using logical structure in how you fetch those files.

    Another matter is that if at some point, the amount of classes exceed a reasonable amount of effort to maintain them, you can create the classes on the fly during an installtion cycle; That is the better option overall, but to actually develop a means to do so isn't easy.

    As for my skills and knowledge, I am aware that I do have some skills and knowledge, and I tend to think that I help other people as much as I can, maybe as much as the other regular members do, but I wouldn't go as far as too say that I'm the only talented person going about this forums.

    I'm not. As for education, and what all that entails, I don't need a Phd to determine if I can develop or not; I'm not educated to University level, and I have no interest in going down that route - I have no need to actually; I have free access to the biggest learning resource on the planet.

    Anyways, I wasn't getting personal, can we get back on topic?

  19. #19
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe as suggested, for smaller applications, this may well be overkill I suppose, but not so for other reasons;
    Another approach to suit both aspects of what I was talking about is to accommodate for easier refactoring at a later date, but at the same time, retain your original option is to use this for example,

    PHP Code:
    // ...
    public function findAll() {
    $stmt $db -> createStatement$this -> findAllStatement() );
    $rs $stmt -> execute();
    // ...
    }

    protected function 
    findAllStatement() {
    return 
    'select * from table order by ...';
    }
    // ... 
    You can therefore keep things as they are as above, but later you can pass in the IStatement class to the constructor as you would, and replace findAllStatement(); with this instead,

    PHP Code:
    protected function findAllStatement() {
    return 
    $this -> statement -> findAllStatement();

    That too minimises the impact on you during refactoring, I find; More suitable option when you inherit the class hierarchy from someone else

  20. #20
    SitePoint Member
    Join Date
    Jan 2006
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    SourceForge Project File Links...

    Quote Originally Posted by arborint
    A lot of these questions were covered in the Skeleton threads. You might want to take a look at the Skeleton threads or download my fork here.
    Hey, I just wanted to point out if you pull up this project via the Search and go to files...there aren't any. Only your direct download works. You might want to clean up this project to make sure people always pull the current version.

    Jason

  21. #21
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jasonvogel
    Hey, I just wanted to point out if you pull up this project via the Search and go to files...there aren't any. Only your direct download works. You might want to clean up this project to make sure people always pull the current version.
    It's not really a project, just collected demonstration code that I cleaned up a little. If you'd like to volunteer I'd be glad to make you release manager.
    Christopher

  22. #22
    SitePoint Member
    Join Date
    Jan 2006
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you have code that you recommend for login, user creation, and reset? I've seen some example on the web, but everyone says "..., but don't use this code for Production". Basically, I'm looking for login, ... code that uses some "best practices".

    I'm also trying to understand how to code pages to check for valid access..and redirect to login when not logged in.

    If you've got any pointers, I would really appreciate it.

    Thanks,
    Jason

  23. #23
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Location
    Sweden
    Posts
    31
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just want to say that I have looked into some more MVC, mostly the skeleton mentioned earlier, and I really can't figure out why the examples are so complex. I have no problems understanding other things in life (more than anyone) so I don't think I am all to blame for it.

    The skeleton suggested demands a lot of files to function. I had to copy about 20 files just to get the simplest example to work. Where is the pedagogy? I'm not balming anyone since no one asked to be my teacher, but the people who want to help should really think about how they help. If a guy wants to learn how to ride a bike, maybe you shouldn't start off with 100gears, full suspention etc etc. Just a plain bike with a green handle for right and a red one for left.

    I'm not expecting anyone to do this, I just wanted to let you know. Maybe there are better ways to help than sharing your own code that you use on websites. It's really nice and I can see that for you it might be the most "precious" you can give, but if the kid can't even find the pedal on the bike, he's not going to learn how to ride it.

    Personally I'm on the verge of giving up this MVC story. I have spent so much time in MVC without really getting any usefull results. It's kind of sad since I think I can see the potential in it. Maybe MVC is only for the ones who live for their coding (no offence, really). I don't know.

    Giving up isn't really my thing though, so maybe Ill re-ignite and something might click.

    Let's finnish off with a smile.

  24. #24
    SitePoint Guru thr's Avatar
    Join Date
    Jun 2003
    Location
    Sweden
    Posts
    664
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AbraKadabra
    I just want to say that I have looked into some more MVC, mostly the skeleton mentioned earlier, and I really can't figure out why the examples are so complex. I have no problems understanding other things in life (more than anyone) so I don't think I am all to blame for it.

    The skeleton suggested demands a lot of files to function. I had to copy about 20 files just to get the simplest example to work. Where is the pedagogy? I'm not balming anyone since no one asked to be my teacher, but the people who want to help should really think about how they help. If a guy wants to learn how to ride a bike, maybe you shouldn't start off with 100gears, full suspention etc etc. Just a plain bike with a green handle for right and a red one for left.

    I'm not expecting anyone to do this, I just wanted to let you know. Maybe there are better ways to help than sharing your own code that you use on websites. It's really nice and I can see that for you it might be the most "precious" you can give, but if the kid can't even find the pedal on the bike, he's not going to learn how to ride it.

    Personally I'm on the verge of giving up this MVC story. I have spent so much time in MVC without really getting any usefull results. It's kind of sad since I think I can see the potential in it. Maybe MVC is only for the ones who live for their coding (no offence, really). I don't know.

    Giving up isn't really my thing though, so maybe Ill re-ignite and something might click.

    Let's finnish off with a smile.
    I tend to agree with this, even tho I've passed the initial learning curve and can w/o any problem read the Skeleton-thread code and understand it fully.... When you start learning, well... It's damn hard. And yes I agree about your statement on the skeleton thread code. For someone just starting to learn... it's way, way, way to hard.


    Btw(Yes this is in swedish): Jag är också svensk, behöver du hjälp så lägg till mig på msn (thrthr@gmail.com), är online största delene av tiden jag sitter vid datorn.

  25. #25
    SitePoint Member
    Join Date
    Jan 2006
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AbraKadabra
    I just want to say that I have looked into some more MVC, mostly the skeleton mentioned earlier, and I really can't figure out why the examples are so complex. I have no problems understanding other things in life (more than anyone) so I don't think I am all to blame for it.
    Recently, I found http://www.onlamp.com/pub/a/php/2005...ro.html?page=1. Thus far, it seems to be about the best, illustrative example I've found thus far... at least regarding MVC. I'm still looking for a good user authentication example/tutorial.

    Thanks,
    Jason


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
  •