Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    New Coder
    Join Date
    Dec 2011
    Posts
    80
    Thanks
    5
    Thanked 12 Times in 12 Posts

    Retrieve Data from an Array the OOP Way

    This is a fairly simple Constructor class, but I think will save people who are developing a forum or a blog some time.

    Suppose you have a Column in your database called post_date in one table and update in another table? Instead of writing a whole bunch of if statements, simply create a constructor class.

    For example:
    PHP Code:
    <?php
    class BlogPosts extends BlogPost {
        
         public function  
    __construct($page) {
             foreach (
    $page as $key => $value)
             {            
                
    $pos strpos($key'date'); // Find the word date in array
                
    if ( $pos !== false $value date('F j, Y g:i A'strtotime$value )); // Format MySQL date to proper format
                
    $this->$key $value// Assign value to variable in object. 
             
    }
         }
    }
    *Note - the if statement seems a little weird, but what you are basically saying is if the statement is not false then perform the formatting of the date in order to make it readable for a human.

    Then all you have to do is something like the following:
    PHP Code:
         public function blogPostRecords()
        {
            
    $database parent::connect(); //Connects to the mysqli Database
            
            
    $query "SELECT id, blog_name, content, new_blog_date, update_date, username FROM pages ORDER by id DESC";
            
    $result $database->query($query);
            
            while (
    $page $result->fetch_array(MYSQLI_ASSOC)) {
                
    /* This makes it an array of an object, also note */
               /* if you just want an object then just omit the   */
               /* [] braces from $this->send_posts for example   */                   
               
    $this->send_posts[] = new BlogPosts($page);                      
            }
            
    /* free result set */
            
    $result->free();

             
    $databaseClose parent::close_connection();              
            
            return 
    $this->send_posts;
            
        } 
    I also believe this will save the amount of code that needs to be written and is reusable or easily modified.
    Last edited by Strider64; 04-21-2013 at 01:07 PM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    One thing to note is that whilst it may be reusable, it also contains no integrity and open to privacy violations between objects. Making use of PHP's magic property setting chained with PHP's datatype weakness means I cannot verify for 100% certainty that an object property is that of what I expect. It also makes debugging far more complex since I cannot tell at compile time what the properties are, only at runtime.
    So in a full OO system you would presumably have a BlogPost object and you can have a BlogPosts collection of BlogPost objects. The problem with the magic properties is when I attempt to dereference the BlogPosts for a BlogPost, there is now no integrity to verify with 100% certainty that it will dereference to the proper datatype (since the properties are all public). Fortunately, with mysqli that is very easy to get around:
    PHP Code:
    class BlogPost
    {
        private 
    $id;
        private 
    $blog_name;
        private 
    $content;
        private 
    $new_blog_date;
        private 
    $update_date;
        private 
    $username;

        
    // add getters and setters
    }

    abstract class 
    GenericArrayObject extends ArrayObject
    {
        public abstract function 
    validate($data);
        public function 
    offsetSet($key$val)
        {
            if (!
    $this->validate($val))
            {
                throw new 
    InvalidArgumentException('Provided data does not fit into generic collection!');
            }
            
    parent::offsetSet($key$val);
        }

        
    // add some utility methods if you like.  I'll use pop in my example
        
    public function pop()
        {
            
    $ret $this[count($this) - 1];
            
    $this->offsetUnset(count($this) - 1);
            return 
    $ret;
        }
    }

    class 
    BlogPosts extends GenericArrayObject
    {
        public function 
    validate($data)
        {
            
    $bResult true;
            if (
    $data != null && !($data instanceof BlogPost))
            {
                
    $bResult false;
            }
            return 
    $bResult;
        }
    }

    // and used by:
            
    $query "SELECT id, blog_name, content, new_blog_date, update_date, username FROM pages ORDER by id DESC";
            
    $result $database->query($query);
            
    $blogposts = new BlogPosts();
            while(
    $blogposts[] = $result->fetch_object('BlogPost') or $blogposts->pop()); 
    Simple as that. MySQLi is privileged and ignores the scope violation on the objects whilst setting a fetch_object to a class. There is a trick to this though, fetch_object will set the properties *before* calling the constructor. This means that the constructor must accept only optional arguments (if any), and an additional check would be done to massage the data as needed. Since they are set, you can check the value of them and cast to appropriate types, otherwise, set them as provided in the constructor. It's a shame that they didn't choose the __set functionality instead which could be chained directly to setters via reflection.

    So in a full blown OO application, you would opt for writing the classes with integrity as needed since you need the objects anyway. You would then exploit the mysqli setting of the object and then calling the constructor to typecast anything you need. Now I get to keep my integrity rules, and have easy setting of my objects from a database (sorta, it will complicate the use of objects of objects of course, but I can get around that by writing an intermediate class to massage the data more).
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

  • Users who have thanked Fou-Lu for this post:

    Strider64 (04-24-2013)

  • #3
    New Coder
    Join Date
    Dec 2011
    Posts
    80
    Thanks
    5
    Thanked 12 Times in 12 Posts
    Thanks, that helps out a lot for I was looking at finding a way of protecting (or giving it integrity to the data), I would have never in a million years of thought of doing something like that. ( I was actually looking at doing it a different way, but after looking at this that idea of mine looks stupid now. LOL )
    Last edited by Strider64; 04-24-2013 at 05:32 PM.

  • #4
    New Coder
    Join Date
    Dec 2011
    Posts
    80
    Thanks
    5
    Thanked 12 Times in 12 Posts
    I just want to follow up on this, I can't say Thank You enough. I made the modifications and while it's a little more code it sure does bring the flexibility, ease of modification and vastly improves data integrity and provides better privacy (security). What I don't understand I watched a php tutorial (I believe from lyndia.com) and the person doing the tutorial said it was "no" big thing about using public classes and data. There are a few other misleading things from this instructor has also said about php, but maybe way technology changes at the time of the tutorial it was OK to think that way? Anyways I guess everyone has to be careful when watching a tutorial(s) on the net even from well established sources. Anyways, visiting forums, going to php.net manual, reading books on php and practicing writing code helps a lot. I think (hope) I'm learning how to write proper OOP and how to properly use OOP, but I think I'll always be learning PHP for I just learn there is such a thing as Object Relational Mapping (ORM). I guess it's better to not know it all than to think that you know it all.
    Last edited by Strider64; 04-25-2013 at 05:33 PM.

  • #5
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    The problem with public properties in PHP is its datatype weakness. Some languages you can get away with public so long as it has non-strict business rules to apply. In something like Java, you can say I need an integer, but it doesn't matter what it is. By default I will give you zero, but you can change it if you see fit:
    PHP Code:
    public class MyClass
    {
        public 
    int mynumber;

    At least Java can guarantee to me that it is indeed an integer. Personally, I wouldn't do that in Java since it doesn't use properties with the get/set blocks, so this is more useful in a language like C# which chains the get/set mechanism directly to the derference: myobj.property = 4; would call the actual method that handles it. This behaviour can be simulated with PHP's __set method, but requires a large block in order to deal with case conditions. I'd still write each method separately and then chain it to the __set's variable name. I'd use reflection myself since I'm lazy and would only want to write the __set once and let it find and invoke the actual setProperty() method I've written. Problem there now becomes the use of by-reference primitives which do not pass through on the __set magic method.

    PHP provides no integrity at the variable level. Because of this I can guarantee nothing from the storage of public variables:
    PHP Code:
    class MyPet
    {
        public 
    $myPet;
        public function 
    __construct(Animal $pet)
        {
            
    $this->myPet $pet;
        }

        public function 
    getMyPetName()
        {
            return 
    $this->myPet->getName();
        }
    }

    $p = new MyPet(new Cat("KittyCat"));
    print 
    $p->getMyPetName();
    // that above is fine.  But since myPet property is public:
    $p->myPet "KittyCat";
    print 
    $p->getMyPetName();
    // fatal error. 
    So in PHP, you need to use the setter mechanisms either by individual functions (what I'd recommend), or by simulating properties with private variables and chained set methods in order to ensure the datatypes. Objects in particular are the biggest problem to work with; I want to guarantee that an object has its integrity in place when dereferencing it. I can do that with setters during runtime.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •