SitePoint Sponsor

User Tag List

Page 1 of 5 12345 LastLast
Results 1 to 25 of 136

Hybrid View

  1. #1
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How much OO is too much?

    Until now, I use proecedural functions to divide all my code into functions. Sure, i had a few classes such as database class, form validation, etc which I would reuse again and again, but for the code used in 1 script only, i used procedural functions to divide the code.

    E.g if there was a script used to add users to the database: its processing would be like this:

    PHP Code:
    <?php
    if (isset($_POST['submit']))
    {
     
    validate();
     
    addUser();
     
    sendActivationEmail();
     
    displayConfirmation();
    } else {
     
    showForm();
    }
     die;
    ?>
    But now I want to change the way I code and use classes even for normal/ single scripts. For example, instead of the previous processing method, i want to use something like:

    PHP Code:
    <?php
    $userAdder
    =&new UserAdder;
    if (! 
    $userAdder->isSubmitted())
    {
     
    $userAdder->validate();
     
    $userAdder->add();
     
    $userAdder->sendConfirmationEmail();
     
    $userAdder->displayConfirmation;
     
    } else {
     
    $userAdder->showForm();
    }
    die;

    ?>
    I know there is no technical advantage of doing this.. but I want to do it simply because I enjoy OO coding more than procedural.

    Do any of you guys also make your scripts this way? Are their any potential disadvantages of this method?

  2. #2
    throw me a bone ... now bonefry's Avatar
    Join Date
    Nov 2004
    Location
    Romania
    Posts
    848
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Actually, that code in OOP goes something like this:
    PHP Code:
        $myUser = new User();
        
    $myUser->addOnInsertListener($mailer);
        
        if (
    $form->isSubmitted() && $form->isValid()) {
            
    $myUser->populate($form->getMap());
            
    $myUser->insert();
            
    $requestDispatcher->forward('showUser'$myUser->ID);
        } 

  3. #3
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    but you got my point dude

  4. #4
    011110010110000101111001 jabird's Avatar
    Join Date
    Aug 2004
    Location
    U.S.
    Posts
    593
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been learning PHP for some time now. I've never taken a single OOP tutorial though. But for some odd reason, it is comming extremely natural to me. This begin in mid-coding of my CMS. But when I get done with a stable version, I'm going to rewrite ALOT of it to OOP... I should have thought of it a long time ago. but now everytime I want to change a menu... I have to change it EVERYWHERE... that gets complicated...

    So in version 2.0.0 it will go from the big huge bulky code to:
    $jbcms->showMenu();

    I think it'd be a great idea for you too...
    ~Jabird
    Jabird.com
    If I were binary... I'd be all 1's for you.
    BBCode trouble?

  5. #5
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    which CMS is that?

  6. #6
    011110010110000101111001 jabird's Avatar
    Join Date
    Aug 2004
    Location
    U.S.
    Posts
    593
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    JabirdCMS

    My CMS.... It's by no means pretty... and its mostly procederal (sp?).
    ~Jabird
    Jabird.com
    If I were binary... I'd be all 1's for you.
    BBCode trouble?

  7. #7
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jabird
    JabirdCMS

    My CMS.... It's by no means pretty... and its mostly procederal (sp?).
    I've got some ideas for a PHP style mix of procedural and OO code which could turn into a framework. If they work well with the app I'm working on at the moment, I might try the "extract the framework" dance

    Douglas
    Hello World

  8. #8
    Awesome Addict
    Join Date
    Mar 2004
    Location
    Toronto, Canada
    Posts
    326
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by digitman
    I know there is no technical advantage of doing this.. but I want to do it simply because I enjoy OO coding more than procedural.
    Totally with you on this one ... sure, I may not be able to reuse it but it's a lot cleaner and I enjoy (*shiver*) doing it.

  9. #9
    SitePoint Wizard
    Join Date
    Jul 2004
    Location
    Minneapolis, MN
    Posts
    1,924
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I feel that even though long time PHP gurus advocate against using OOP to group functions, it still helps out in your code. It is kind of like each object represents an idea or concept.

    Although it doesn't match up with the purpose of OOP, it does make programming much easier. I've done it myself in the next version of a CMS that I'm writting now.

  10. #10
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by charmedlover
    I feel that even though long time PHP gurus advocate against using OOP to group functions, it still helps out in your code. It is kind of like each object represents an idea or concept.
    Well, one could certainly argue that it's not OOP if you use objects only to group functions. Sure, it can help, but it's not "object oriented" by the least. :)

  11. #11
    SitePoint Addict
    Join Date
    May 2005
    Posts
    255
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by charmedlover
    I feel that even though long time PHP gurus advocate against using OOP to group functions, it still helps out in your code. It is kind of like each object represents an idea or concept.

    Although it doesn't match up with the purpose of OOP, it does make programming much easier. I've done it myself in the next version of a CMS that I'm writting now.
    It's pretty much the only thing you can do until PHP has proper namespace support, actually.

    Also, it's not anything unique. It's called a singleton. It's a useful design pattern. The only people I've ever heard complaining about singletons are those who've never designed a real-world application.

  12. #12
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Etnu
    It's pretty much the only thing you can do until PHP has proper namespace support, actually.

    Also, it's not anything unique. It's called a singleton. It's a useful design pattern. The only people I've ever heard complaining about singletons are those who've never designed a real-world application.
    Grouping functions in a class to simulate namespaces has nothing to do with singletons.
    Furthermore, let me be one of those never-designed-a-real-world-application-people and state that the singleton pattern is overrated, I prefer the "Highlander principle": you pull out an ancient sword, very convincingly shouting "There can be only one!" and behead anyone daring to make more than one instance of such a class
    Per
    Everything
    works on a PowerPoint slide

  13. #13
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The code posted in the first post of this thread is not OO code. There is no difference between the first code and the second except the second code will be slower. If you just want to use classes to namespace you might as well just prefix your fuction names with "userAdder_" and make a real library out of it. Nothing wrong with that except the fact that even in procedural coding you would not create a library that: validates the request, writes to a database, sends email, and displays HTML. Bundling poorly structured code in a class does not magically apply structure.
    Christopher

  14. #14
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    even in procedural coding you would not create a library that: validates the request, writes to a database, sends email, and displays HTML. Bundling poorly structured code in a class does not magically apply structure.
    Thanks for the criticism.. now, make it constructive critisism and also tell me what would be the right way to structure this code, then?

  15. #15
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This code is a little forced, but hopefully you get the idea.
    PHP Code:
    if ($request->get('submit') == 'Submit') {
    // should filter here too
        
    $validator = new Validator();
        
    $validator->addRule('username', new UsernameRule());
        
    $validator->addRule('password', new PasswordRule());
        
    $validator->addRule('password2', new matchRule('password'));
        
    $validator->addRule('email', new EmailRule('password'));
        if (
    $validator->isValid($request)) {
            
    $user = new User();
            
    $user->setUsername($request->get('username'));
            
    $user->setPassword($request->get('password'));
            
    $user->setEmail($request->get('email'));
            if (
    $user->insert()) {
                
    $template = new Template('emails/NewAcctEmail.txt');
                
    $template->set('username'$request->get('username'));
                
    $template->set('password'$request->get('password'));

                
    $ActivationEmail= new Email();
                
    $ActivationEmail->setMessage($template->render());
                
    $ActivationEmail->send($request->get('email'));

                echo 
    $view->displayConfirmation($request);
            } else {
                echo 
    $view->displayError($user->getErrorMsg());
            }
    } else {
         echo 
    $view->showForm($request);

    Christopher

  16. #16
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's another way to divide the responsibilities.

    I've used three classes: a User, a Request and a Notifier.

    The User class is an ActiveRecord which is used to save data to a database. It will only let itself be saved to the database when it is valid, it validates itself when you try and save it and returns false if it cannot be saved. The constructor takes an associative array which correspond to fields in the database*.

    Here, this array comes from the Request class. The Request class holds the keys to the $_GET and $_POST data, removing magic quotes and other helpful things.

    The Notifier is responsible for sending emails, and uses an associative array to fill in the email templates.

    PHP Code:
    $user = new User($request->get_params());
    if (
    $user->save()) {
      
    $notifier->deliver_signup_for($user->get_params());
      
    $this->redirect_to('show'$user->get_id());
    } else {
      
    $this->render($user->get_params());

    That code would end up in a fourth Controller class, which would be able to handle redirects, and pass on render calls to the View layer. The User class keeps a note of any validation problems it has when you try and save it, or ask if it is valid ($user->is_valid()). This data can be read by the View to render error messages and warnings about form validity.

    Regads,
    Douglas

    * Because it is just an array, the data can come from anywhere. It is simplest if it can come directly from the Request, but you might like to do other processing on the data first, for example by setting default values for some fields if they were not in the Request originally.
    Hello World

  17. #17
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Imagine you have a function library which lets you write this...

    PHP Code:
    $email parse_template('emails/NewAcct.txt'$_REQUEST);

    send_email($email$_REQUEST['email']); 
    Then replace the function paramaters with setters on objects...

    PHP Code:
    $template = new Template('emails/NewAcct.txt');
    $template->set_data($_REQUEST);

    $email = new Email;
    $email->set_message($template->parse());
    $email->set_email($_REQUEST['email']);
    $email->send(); 
    And lets split that big, bad array up into more setters and getters...

    PHP Code:
    $template = new Template('emails/NewAcctEmail.txt'); 
    $template->set('username'$request->get('username')); 
    $template->set('password'$request->get('password')); 

    $ActivationEmail= new Email(); 
    $ActivationEmail->setMessage($template->render()); 
    $ActivationEmail->setEmail($request->get('email'));
    $ActivationEmail->send(); 
    oops... so all this object oriented stuff comes down to using global classes instead of global functions?

    I don't think so.

    Regards,
    Douglas
    Hello World

  18. #18
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    Imagine you have a function library which lets you write this...

    PHP Code:
    $email parse_template('emails/NewAcct.txt'$_REQUEST);
      
      
    send_email($email$_REQUEST['email']); 
    You conveniently left out the validation part, didn't you
    Per
    Everything
    works on a PowerPoint slide

  19. #19
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    To me there are so many things to think about when coding. Sometimes a OO is the best approach, other times procedural code using functions pertaining to what you are doing is better, then procedural code without a function call is sometimes better than anything you could think up! While OO will give cleaner code than procedural code the root of the trouble is not one or the other, it is each way that you may do something.

    I'll give you example...

    In the never ending battle to build the fastest most resource friendly services you will undoubtedly fight with the question 'what is the better way of doing something'. If you do, you know settlings for what others do is the wrong approach to take! Why, because never is one method or function, even core language functions always the best way of doing things! Only testing will prove what is truly better to use!

    I myself have not jumped aboard the PHP OO train just yet as OO in PHP is still young and has many concerns for bottlenecking. Unless your serializing your objects I don't see where in all cases it is the smart way of doing everything, but like I said it does work in some places in coding but it will never be that 'use it every where' type of thing!

    printf

  20. #20
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by been
    You conveniently left out the validation part, didn't you
    Well, as you can see from the first code sample I posted, I don't think you should have a validation object in that part of the application. It should only try and save the User to the database, and return error messages from the User if it doesn't work. That's where the OO comes in (IMO), that you simply don't have to worry about the technicalities of validating the User class outside the User class. I shouldn't have to worry about that.

    The validator code itself looks fine to me, it is just that it is in the same place you would put procedural functions* to check the validity of the request, rather than taking advantage of using objects and hiding it away.

    * Just to proove I'm not talking hot air, the functions could look like this:

    PHP Code:
    $errors = array();
    validate_username ($errors$request'username');
    validate_password ($errors$request'password');
    validate_match    ($errors$request'password''password2');
    validate_email    ($errors$request'email');

    if (!
    $errors) {
      
    // do something ...

    The advantage of OO code is that if you can encapsulate that validation in the User class, so you don't need to duplicate the above validation each time you want to save a User object, you can just run it with $user->save();

    Edit: and just to hammer it home, that could be $user->save(), $account->save(), $post->save(), $article->save(), whatever you like, it would have the same $anything->save() interface. That's polymorphism, and you loose it if you make the validation external to the thing being saved.

    As an aside, I wouldn't want explicit UsernameRule or PasswordRules, I'd rather more generic IssetRule and LengthRule classes. You could always use custom ones, but those strike me as a better base set to have.

    Regards,
    Douglas
    Last edited by DougBTX; Aug 3, 2005 at 11:22.
    Hello World

  21. #21
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This thread has progressed faster than I've been following it, but just wanted to reply to Douglas' post (#24)...
    Quote Originally Posted by DougBTX
    The advantage of OO code is that if you can encapsulate that validation in the User class, so you don't need to duplicate the above validation each time you want to save a User object, you can just run it with $user->save();
    While I think we are both agreeing on the fact that syntactic validation is a good candidate for reuse, I wouldn't put it (the syntactic validation code) in the business object: Going on with the $user->save() example, we could say that a 'user' can be saved in different contexts.

    For example: a user signup and an update of a user record. To do those things, data has to come from outside of the application and in both cases that sort of data will be different, you cannot put all syntactic validation in the business object, IMHO, it would bloat it. Also, putting some basic validation outside of the object, would make it more unaware of the context in which it is saved, which I regard as a good thing.

    There are of course rules, which do belong to the business object (ex: a user must be over 18, ...) and they should go in there, or we'd be left with pretty useless domain classes But I very much feel that there's a difference; one is about validating user input, the other is about making sure that an object doesn't go in an invalid state. This is some of the stuff that has gotten me to think (well, just a little bit) about a PHP contract tool by the way.


    Edit: and just to hammer it home, that could be $user->save(), $account->save(), $post->save(), $article->save(), whatever you like, it would have the same $anything->save() interface. That's polymorphism, and you loose it if you make the validation external to the thing being saved.
    Sorry, but I fail to see how one would lose polymorphism?

    As an aside, I wouldn't want explicit UsernameRule or PasswordRules, I'd rather more generic IssetRule and LengthRule classes. You could always use custom ones, but those strike me as a better base set to have.
    Totally agreeing on the generic rules, I'd assemble them in different Validators and have $validator->validate($something); (which is why I fail to see how you'd lose polymorphism)
    Last edited by been; Aug 4, 2005 at 05:49. Reason: polymorphism instead of polymophism ;)
    Per
    Everything
    works on a PowerPoint slide

  22. #22
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by been
    syntactic validation
    I think we are comming from totally different angles on this, can you explain what you mean by "syntactic validation"?

    Quote Originally Posted by been
    one is about validating user input, the other is about making sure that an object doesn't go in an invalid state.
    Can you explain the difference? From my perspective, those two things are really the same, because user input changes the state of objects. If that new state is invalid, I can spit errors back at the user.

    Quote Originally Posted by been
    Sorry, but I fail to see how one would lose polymophism?

    Totally agreeing on the generic rules, I'd assemble them in different Validators and have $validator->validate($something); (which is why I fail to see how you'd lose polymophism)
    Does that mean you have a User and a UserValidator? Or do you just have a generic Validator which you initialize when you need it like in Chris's example?

    Taking "the" example for polymophism:

    PHP Code:
    class Circle {
        
        function 
    Circle($radius) { ... }
        
        function 
    area() {
            return 
    PI $this->radius $this->radius;
        }
        
    }

    class 
    Square {
        
        function 
    Circle($length$breadth) { ... }
        
        function 
    area() {
            return 
    $this->length $this->breadth;
        }
        
    }

    $shape = new Circle(42); 
    And later, when you want to find the area, we use polymophism:

    PHP Code:
    echo $shape->area(); 

    If we take the area calculation outside of the Shape classes, much like talking the validation outside of the User class, you end up these two classes:

    PHP Code:
    class Circle {

        function 
    Circle($radius) { ... }

    }

    class 
    Square {
        
        function 
    Square($length$breadth) { ... }
        
    }

    $shape = new Circle(42); 
    Then, when we want to find the area, you need these classes:

    PHP Code:
    class CircleAreaCalculator {

        function 
    calculate($circle) {
            return 
    PI $circle->radius $circle->radius;
        }

    }

    class 
    SquareAreaCalculator {

        function 
    calculate($square) {
            return 
    $square->length $square->breadth;
        }

    }

    class 
    Calculator {

        function 
    setCalculator($calculator) { ... }

        function 
    calculate($shape) {
            return 
    $this->calculator->calculate(shape);
        }


    and this code to calculate the area:

    PHP Code:
    $calculator = new Calculator();
    $calculator->setCalculator(new CircleAreaCalculator()); //**
    echo $calculator->calculate($shape); 
    The line I've marked with ** is the problem line. If we assume that due to polymophism, $shape could either be a Circle or a Square, then we can't know whether we need a CircleAreaCalculator or a SquareAreaCalculator, but we have to write down one of the two, so we can't have polymophism.

    The trick would be to pass a $shape_area_calculator along with $shape ... and rather than passing two variables you might like to make it into one variable, just to make life easier ... so you might have $shape->area_calculator instead ... but then you only ever need to access it through $shape->area() so lets make $shape->area_calculator private ... and then you notice that you've got a bunch of infrastructure code you don't need anymore .. you trim it down ... then you are back at the code at the top of this post.

    Well, that's how I see it working out

    Later,
    Douglas
    Hello World

  23. #23
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DougBTX
    oops... so all this object oriented stuff comes down to using global classes instead of global functions?
    I agree and said the example was a little forced when I posted it. You could just use the email() function there (and I often do). I have always said that you could code fine PHP procedurally unlike the OOP purists. However those middle lines are not really what the example is trying to show. My goal was to present small single use object that work together.
    Quote Originally Posted by printf
    To me there are so many things to think about when coding. Sometimes a OO is the best approach, other times procedural code using functions pertaining to what you are doing is better, then procedural code without a function call is sometimes better than anything you could think up! While OO will give cleaner code than procedural code the root of the trouble is not one or the other, it is each way that you may do something.
    I think you misunderstand OO. In PHP, OO is a way to design and orgranize you code for flexiblity and testablity. It is not just about using the class statement everywhere. There are still calls to functions and critical sections look very similar and perform the same.
    Quote Originally Posted by printf
    I myself have not jumped aboard the PHP OO train just yet as OO in PHP is still young and has many concerns for bottlenecking.
    PHP4 was released in May 2000 so I don't know about "young", and I would bet that your "bottlenecking" is more theoretical than real.
    Christopher

  24. #24
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    I agree and said the example was a little forced when I posted it. You could just use the email() function there (and I often do). I have always said that you could code fine PHP procedurally unlike the OOP purists. However those middle lines are not really what the example is trying to show. My goal was to present small single use object that work together.
    Yea, we probably share something there. Seems like an inherant mistake to me to have a "single use object", because if you only need to use it once, why bother with an object? There are only a few cases where I only ever need some code once though

    Douglas
    Hello World

  25. #25
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think people that replied to me are missing my point. So this time I will make it very clear so you understand what I was trying to say!

    PHP has a easy learning curve, so people tend to only do what is absolutely necessary to perform a task that they wish to do. Look at the thousands of script you can buy or get for free. Some are very dangerous, most others have terrible logic, basing most of their coding on core functions when other core functions are faster and more resource friendly for what they are trying to do! Why does this happen, because people don't take the time to understand that reinventing the wheel is important for bringing better logic to the over all design!

    So using the OO way and still writing terrible logic will do nothing but have people believe you understand what you are doing when you don't which will just create more dangerous scripts to learn from for free on the Internet! Sure you might call me cynical, but following coding standards is principle that very few people live by and the others that don't follow those standards tend to make up their own which only tells me they think they know more than what they really do!


    So use what ever you want to use. But you should start asking your self this...

    'Is what you just copied or wrote truly the best way to do what you want done'

    You can be sure it will never be the best until you try to do it many different ways, and even asking for help may open your eyes to other ways that you have not ever learned!

    Quote Originally Posted by Thomas A. Edison
    I have not failed. I've just found 10,000 ways that won't work.


    printf


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
  •