SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 77

Hybrid View

  1. #1
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Lightbulb It's time to take the OOP plunge

    I've been focused on php for about 2 years now from an absolutely non-programming background. I think my procedural php is coming along ok, I have dealt with most typical functions of a php driven site... eg. user authentication, database integration, general security, file handling, emailing, image manipulation, and all those smaller things that make it all work.

    But I have this feeling that something better is just around the corner, and at my stage that must be OOP. I don't exactly want to change direction I just want to do the same stuff better.

    So I thought bugger it, I might as well take the plunge now and try OOP.

    The project in mind is basically a directory website with email marketing laid over the top. Procedurally I can and have previously done similar stuff so the only major challenge is the change in technique.

    Here's how I am thinking about approaching the project... allow me to wow you all with my caveman knowledge....

    Code Layout:
    Usually I have one or more functions files that contain all my common functions. Where a page requires something to happen, like retrieve a GET id or update a database row, I layout what I want to happen in a procedure at the top.
    eg.
    PHP Code:
    if (isset($_GET['action']))
    {
      
    $action $_GET['action'];
      if (isset(
    $_GET['id']))
      {
         
    $id = (int)$_GET['id'];
         
         switch (
    $action)
         {
            case 
    'delete':
            
    mysql_query("DELETE FROM table WHERE id = $id");
            break;
            
            
    // etc etc
         
    }
      } else {
        
    $output['error'][] = 'no id';
      }
    }
    // start html 
    The fundamental difference in OOP is that I have an object where the delete action is embedded in the class.
    PHP Code:
    if (isset($_GET['action']))
    {
      
    $action $_GET['action'];
      if (isset(
    $_GET['id']))
      {
         
    $id = (int)$_GET['id'];
         
         
    // lets say i'm changing a blog post
         
    $object = new post();
         
         switch (
    $action)
         {
            case 
    'delete':
            
    $object->deletePost($id);
            break;
         }
      } else {
        
    $output['error'][] = 'no id';
      }
    }
    // start html 
    For readability, I assume its worthwhile leaving some procedural stuff as I have done above, but importantly the main action is happening somewhere else.

    I am aware the goal is to completely separate code from content but I don't quite understand this in full.

    So for my directory system, some potential classes might be...
    - user
    - listing
    - article
    - comment (maybe as part of article)

    or basically any tangible element that will have associated behavior (functions).

    File Structure:
    I will hopefully find that the bulk of my functions.php will now be embedded in classes in classes.php.... this is essentially why OOP rocks because most of the code is all pointing to the same central engine room.

    Number of Lines:
    The major decrease should be a result of less repetition across various .php pages that do similar tasks. There should be less code embedded in the "webfront" pages and more going on in pure php pages.

    Shift in Logic
    My current logic is... "it makes sense to build heaps of functions because I often will repeat something and I can just call a function instead of re-writing the procedure."
    For example one of the most recent functions was
    PHP Code:
    function checkRecord($field$value$table)
    {
        if (
    mysql_result(mysql_query("SELECT COUNT(id) FROM $table WHERE $field = '$value'"),0) > 0)
        {
            return 
    true;
        } else {
            return 
    false;
        }    

    In OOP, when I want to check if a record exists, not much will change except that I will have to work out how to make the function accessible inside a class (if it isn't automatically global). If I wanted to really push my luck I might make a SQL class and incorporate that... Functions are perhaps step one to code centralisation, classes are step 2.

    Resources:
    - lots of tutorial reading
    - Sitepoint's PHP Anthology
    - phpclasses.org (more so for study rather than using stuff in production)
    - and naturally Sitepoint's OOP forum

    For all you guys and girls who already have gone down this road, please add your comments and advice... if any of my above logic is flawed, please point it out so I may ingrain the right thinking while i'm still impressionable
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    The fundamental difference in OOP is that I have an object where the delete action is embedded in the class.
    PHP Code:
    if (isset($_GET['action']))
    {
      
    $action $_GET['action'];
      if (isset(
    $_GET['id']))
      {
         
    $id = (int)$_GET['id'];
         
         
    // lets say i'm changing a blog post
         
    $object = new post();
         
         switch (
    $action)
         {
            case 
    'delete':
            
    $object->deletePost($id);
            break;
         }
      } else {
        
    $output['error'][] = 'no id';
      }
    }
    // start html 
    One of the key differences between procedural and object oriented, is that objects encapsulate entities, while in a procedural approach, you separate functionality from data. A primary key id is an excellent example of the difference; With procedural code, you would have a function, which you invoke, passing the identity of the entity (the primary key) to the function. In an OO approach, the identity would be encapsulated within the object. So the above example is bad OO, because you pass the id to the post instance. A better solution is:
    PHP Code:
    ...
         
    $id = (int)$_GET['id'];
         
         
    // lets say i'm changing a blog post
         
    $object = new post($id);
         
         switch (
    $action)
         {
            case 
    'delete':
            
    $object->deletePost();
            break;
         }
    ... 
    Now, your object instance represents a blog post. Try not to think in classes, but rather in object instances.

  3. #3
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for that, surprisingly I do understand what you mean, the main point that this post object now has an identity, and can be used and reused (in this example for other potential switch cases like update or insert) without continually passing the $id.

    Also if it's at all relevant in my approach to learning OOP, my planned usage will be focused on various web applications where I would like to have identical or near identical classes that are shared. The main benefit I see are -
    a) I can now literally drag and drop a class into an application with little to no modification
    b) When I learn new things I can update my complete web software base with relative ease
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  4. #4
    SitePoint Wizard holmescreek's Avatar
    Join Date
    Mar 2001
    Location
    Northwest Florida
    Posts
    1,707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, since you have already worked with PHP in the procedural sense, if your serious about learning OOP, I highly recommend you get a copy of the book Head First Java. It is the best book for learning OOP inside and out.

    All the books that I have found on PHP & OOP, just cover the very basics of OOP and php i.e. syntax, classes, constructors etc.

    If you read the java book, you'll have no problems with all the concepts of object oriented programming which can be applied to PHP, Java, C++, Objective-C or whatever language you opt to use now and in the future. In addition, you will be be pretty much prepared for PHP 6.
    intragenesis, llc professional web & graphic design

  5. #5
    SitePoint Enthusiast
    Join Date
    Oct 2005
    Location
    Lyon, France
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Object-oriented programming references

    Quote Originally Posted by holmescreek View Post
    Well, since you have already worked with PHP in the procedural sense, if your serious about learning OOP, I highly recommend you get a copy of the book Head First Java. It is the best book for learning OOP inside and out.
    I haven't read a Head First book yet but the collection seems very interesting. Some free chapters from the book are available on the Head First Labs :: Head First Java, Second Edition page.

    When I switched from PHP 4 to 5 I also found the Classes and Objects (PHP 5) chapter of the PHP manual very enlightening, the user contributed notes are also very helpful.

    Quote Originally Posted by holmescreek View Post
    All the books that I have found on PHP & OOP, just cover the very basics of OOP and php i.e. syntax, classes, constructors etc.
    It's weird because they're many PHP books for advanced and object-oriented developers. Just try some keywords on Amazon.com for example. They're also dozens of great tutorials available online.

    Don't hesitate to ask if you need some good references.

  6. #6
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks for the recommendation holmescreek, that looks like a good book... if you had to put a a figure on it, how much of the book is relevant to php?

    Just to slightly get off topic, how similar are ASP.NET/JAVA/PHP OOP? It seems the OOP logic is basically the same in any language... are the syntax differences extreme or not?
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  7. #7
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    Just to slightly get off topic, how similar are ASP.NET/JAVA/PHP OOP? It seems the OOP logic is basically the same in any language... are the syntax differences extreme or not?
    PHP's object syntax is highly inspired by Java. You should be able to translate 1:1 between the two, except for a few esoteric constructs. ASP.NET is an umbrella of several languages, hereunder C#, which is also heavily inspired by Java.

  8. #8
    SitePoint Wizard holmescreek's Avatar
    Join Date
    Mar 2001
    Location
    Northwest Florida
    Posts
    1,707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    Just to slightly get off topic, how similar are ASP.NET/JAVA/PHP OOP? It seems the OOP logic is basically the same in any language... are the syntax differences extreme or not?
    Yeah, from my suggestion, I'm recommending that you learn the concepts of OOP then use any language such as PHP to implement those concepts. Most all languages are nearly identical when it comes down to basic syntax. for(), while(), next(), if(), <, >, true, false -- for instance are present across the board.
    intragenesis, llc professional web & graphic design

  9. #9
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    just ordered Head First Java... was a right pain to track down, none of the local bookstores I contacted had it in stock and I had to order online... too bad its now thursday, gotta wait till next week till it arrives.

    so hopefully this book will give me the best possible foundations... then I will begin looking specifically at how to do it all in PHP.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  10. #10
    SitePoint Wizard holmescreek's Avatar
    Join Date
    Mar 2001
    Location
    Northwest Florida
    Posts
    1,707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    just ordered Head First Java... was a right pain to track down, none of the local bookstores I contacted had it in stock and I had to order online... too bad its now thursday, gotta wait till next week till it arrives.

    so hopefully this book will give me the best possible foundations... then I will begin looking specifically at how to do it all in PHP.

    Well, sounds like you now have a plan. I find it takes me a long time to figure out "which way" to proceed when learning a new language or technology. I hope it works for you as well as it has me & good luck.
    intragenesis, llc professional web & graphic design

  11. #11
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    cheers - i'll try and contain my learning OOP 101 problems/questions to this thread so it can hopefully serve as a bit of a guide for others.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  12. #12
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Head First Java arrived today, i've gone headfirst in... on page 36 of 685

    excellent book by the way I find it really engaging...

    I just have a couple of questions considering it is giving me java examples and I am trying to translate it to php equivalent...
    I see this alot...
    Code:
    public class MovieTestDrive {
      public static void main(String[] args) {
        Movie one = new Movie; // this class was stated above, just had a simple playIt() function
        one.title = "Gone with the Stock";
        one.genre = "Tragic";
        // etc etc 
      }
    }
    Firstly, it explains that the "main" has two purposes:
    1) to test your real class
    2) to launch/start your java applications

    Is the php equivalent to this __construct? and is this the correct translation:
    PHP Code:
    public class MovieTestDrive {
      function 
    __construct() {
        
    $one = new Movie();
        
    $one->title 'Gone with the Stock';
        
    // or 
        
    $this->title 'Gone with the Stock';
        
    // ?
      
    }

    * I think I can hear the groans already
    Last edited by wheeler; Oct 8, 2007 at 19:03.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  13. #13
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The PHP equivalent is this:
    PHP Code:
    class MovieTestDrive{
        public static function 
    main(){
            
    $mov = new Movie();
            
    $mov->title "That movie title that should've been here";
            
    // et cetera.
        
    }
    }

    MovieTestDrive::main(); 
    Only Java does the call to ::main automatically and in PHP you'd have to do it by yourself.
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  14. #14
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    And before you pull your hair out over it -- In Java, this is implied. So you wouldn't have to write this.foo() or this.bar, although it's allowed. You could just write foo() or bar

  15. #15
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    get, set and privacy

    get and set methods:
    the point to getters and setters, is that you can change your mind later, without breaking anyone else's code!

    Hide the data
    it is that simple to go from an implementation that's just begging for bad data to one that protects your data and protects your right to modify your implementation later.
    Therefore:

    Make instance variables private
    make getters and setters public

    is this equally true for php? I remember a few weeks ago a class that had a bunch of get and set functions, and I thought it was ridiculous - but then, I hadn't read anything like the above quote either!

    and this is a kindof similar question that I might as well throw in: obviously php is more flexible with variable types, it doesn't force (or even allow?) you to declare the variable type.... eg.
    Code:
    // java
    int x = 3;
    PHP Code:
    // php 
    $x 3
    however, it seems to make sense to force the data type in a method, such as:
    PHP Code:
    function deleteRecord((int)$id) { 
    this generates a fatal error in php... is there actually a variation of this that would work (short of forcing the data type within the method?)? It seems to make sense to ensure you have an integer straight away rather than validating inside the method.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development

  16. #16
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wheeler View Post
    however, it seems to make sense to force the data type in a method, such as:
    PHP Code:
    function deleteRecord((int)$id) { 

    The immediate problem with that would be; what happens if you pass a string that represents a number? Should it fail, or should there be a conversion? What about if you pass a float? Unlike objects, primitives are easily and regularily co-orced into different types, which makes type hinting with primitives very complex.

    The other issue is, why limit deleteRecord to only take an int? Instead of trying to limit what types functions and methods can take, why not design them to take multiple types? In this case, an array of ids, or a record object? Duck typing is somthing that should be seen as a benefit, not a liability.

  17. #17
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    why limit deleteRecord to only take an int? Instead of trying to limit what types functions and methods can take, why not design them to take multiple types?
    Yes, it should only take an int if you want to delete a record. If you accept multiple types on all your functions, the system becomes unreliable and difficult to maintain.

    If you pass an array of id's, you'll still face the same issue:

    PHP Code:
    $ids = array(1'2');
    function 
    deleteRecord(array $ids) {
        
    // now we have 2 problems instead of 1


  18. #18
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by phpimpact View Post
    Yes, it should only take an int if you want to delete a record.
    Why? Wouldn't passing an array of ids make sense if you want to delete multiple records?

    Quote Originally Posted by phpimpact View Post
    If you accept multiple types on all your functions, the system becomes unreliable and difficult to maintain.
    Obviously, you do it where it makes sense. And I don't see how it makes the system unreliable; I'd think it would have the opposite effect.


    Quote Originally Posted by phpimpact View Post
    If you pass an array of id's, you'll still face the same issue:

    PHP Code:
    $ids = array(1'2');
    function 
    deleteRecord(array $ids) {
        
    // now we have 2 problems instead of 1

    That's not at all what was suggesting, and I don't even know what you mean by "two problems". What I meant was something like:

    PHP Code:
    function deleteRecord($id) {
      if (!
    is_array($id)) $id = array($id);

      foreach(
    $id as $i) {
      
    // delete $i
      
    }
      


  19. #19
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by phpimpact View Post
    Yes, it should only take an int if you want to delete a record. If you accept multiple types on all your functions, the system becomes unreliable and difficult to maintain.
    PHP automatically converts between int, float and string. That's not a problem -- that's a feature.

  20. #20
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's not at all what was suggesting, and I don't even know what you mean by "two problems". What I meant was something like:

    PHP Code:
    function deleteRecord($id) {
      if (!
    is_array($id)) $id = array($id);

      foreach(
    $id as $i) {
      
    // delete $i
      
    }
      

    Yep, I know what you are suggesting, I've been tempted with doing the same as well. But, you have to resist temptation I think a function should never try to outsmart the programmer. It should be strict and not cleaver.

    This is what I do for example:

    PHP Code:
    function deleteRecord(array $idArray) {
        foreach(
    $idArray as $key => $id ) {
            
    // delete $id
        
    }

    I would append the word "Array" to the $id to let the programmer know that he needs to pass an array, and also using code I would force him to pass an array. Then, it's up to him to do: array(1), or array(1, 2). Because another programmer may come along and will see: $id = 1 and in his mind $id is an int, and does not associate that variable with an array. Then he sees: $id = array() and he knows that there's something wrong. So you are forcing the programmer to think, and that's when the function outsmart the programmer.

    PHP automatically converts between int, float and string. That's not a problem -- that's a feature.
    Yes, I see that as a feature as well. I was referring to the example above. For example:

    PHP Code:
    function deleteRecord(array $idArray) {
        foreach(
    $idArray as $key => $id ) {
            
    // var_dump((int) $id) or var_dump($id);
        
    }
    }

    $idArray = array(1'2''param3');
    // a) var_dump((int) $id) - int(1) int(2) int(0)
    deleteRecord($idArray);
    // b) var_dump($id) - int(1) string(1) "2" string(6) "param3"
    deleteRecord($idArray); 
    If you don't force the parameter to be an array, you'll have to add extra complexity to the function. And since a value of an array can be of any type, you'll need to check the values one by one. So in this case, PHP doesn't convert the parameter $idArray automatically nor the values of the array.

    But I think you were trying to make a point about something else, and I agree with you, no doubt about that.

  21. #21
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP has something called typehinting, which allows you to restrict the type of function parameters. You can't typehint to primitive types though -- just to classes and interfaces.

    Whether getters/setters are a godsend or bloat, is an open question.

  22. #22
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm much less open:

    (1) Always use getters and setters. Classes are supposed to encapsulate something. With an interface.
    (2) Never use private, protected or final. They don't actually do anything except add clutter.
    (3) Never use type hints unless there is a genuine need for the code to know something about itself eg dependency injection. More java-esque verbosity which you can safely ignore.

  23. #23
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    // ...
    function deleteRecord((int)$id) { 
    I prefer to use an assert to verify the parameter from within the class method it's self, and leave type hints for objects only, thus you don't pollute the class methods signature so to speak

  24. #24
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, it's set by the logError() method and returned to the public resize() method. This method then decides weather the error produced needs to be handled and if so, what should be done.

  25. #25
    SitePoint Wizard wheeler's Avatar
    Join Date
    Mar 2006
    Location
    Gold Coast, Australia
    Posts
    1,369
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    time to get practical...

    I have made my first attempt at planning out an OOP site.

    This website is a classifieds directory that will:
    - have classifieds, members and categories all stored in the db

    At this point, I am trying to understand two things:

    1. is my UML diagram (also a first ever attempt) logical, and look like it's going to work? Have I fallen for any common pitfalls or just totally got the concept wrong?

    2. the concept of MVC. From what I understand, I have the model and controller covered in my UML, and the view layer will be the html interacting with my objects.

    I have a feeling i've gone slightly off the rails with the User superclass and subclasses. I'm also unsure about the relationships - for example, a Member can update their own classified. However, does this method belong to Classified or Member?

    .please take a look at the attached file and let me know if i'm on the right track!

    P.S. This diagram is by no means meant to be complete or comprehensive..
    Attached Images Attached Images
    Last edited by wheeler; Oct 31, 2007 at 20:21.
    Studiotime - Time Management for Web Developers
    to-do's, messages, invoicing, reporting - 30 day free trial!
    Thomas Multimedia Web Development


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
  •