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 4 of 4
  1. #1
    New Coder
    Join Date
    Jul 2012
    Posts
    33
    Thanks
    18
    Thanked 0 Times in 0 Posts

    Basic OOP question

    Heya, new to php oop, could you by any chance tell me if this idea will work?

    I have a simple class like this:

    File car.php:
    PHP Code:
    <?php
    class Car {

        private 
    $color;
        private 
    $speed;
        private 
    $description;

        public 
    funtion __construct($color$speed$description) {
            
    $this->color$color;
            
    $this->speed$speed;
            
    $this->description $description;
        }

        public function 
    __get($property) {
            if (
    property_exists($this$property)) {
                return 
    $this->$property;
            }
        }

        public function 
    __set($property$value) {
            if (
    property_exists($this$property)) {
                
    $this->$property $value;
            }
            return 
    $this;
        }
    }
    ?>

    I now want to both edit + create new car objects. For that I'm using POST values of regular forms.

    So whenever I click on my create/edit button, a php script is executed using POST values:

    File createCar.php:
    PHP Code:
    <?php
    include('car.php');
    $carcolor=$_POST['color'];
    $carspeed=$_POST['speed'];
    $cardesc=$_POST['desc'];
    $carname=$_POST['name'];
    $newentry=$_POST['new'];  //if newentry is false, it will update an existing obj. instead of creating it

    if ($newentry == true)
    {   
        
    $carname = new car($cartitle$carlink$cardesc);
    } else {
        
    $carname->set($color$carcolor);
        
    $carname->set($desc$cardesc);
        
    $carname->set($speed$carspeed);
    }

    ?>
    I'm really not sure if I'm accessing existing objects the right way nor if this would work at all... well, any input is appreciated! =) thx in advance
    Last edited by coffeecup; 04-19-2013 at 08:46 PM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Setting that way won't work. 'set' is an undefined function in the class Car. That would just be $name->color = $carColor; for example.

    In PHP, you shouldn't use any direct access to a variable, even through a __set. Although it can be handy, and would be alright in this case since there are so few properties.
    The problem is PHP is a datatype weak language. Allowing direct access to properties corrupts the anticipated data within it, especially noticable when using properties of objects. This is why we use setters for these which is used to enforce business rules as well.
    PHP Code:
    class T
    {
        private 
    $i;
        public function 
    getI()
        {
            return 
    $this->i;
        }

        public function 
    setI($i)
        {
            if (!
    is_int($i) || $i 0)
            {
                throw new 
    InvalidArgumentException('i must be a positive integer!');
            }
            
    $this->$i;
        }

    For example. Magic setters *can* be used, but needs to be chained or manually checked:
    PHP Code:
    public function __set($n$v)
    {
        switch(
    $n)
        {
            case 
    'i':
                if (!
    is_int($v) || $v 0)
                {
                    throw new 
    InvalidArgumentException('i must be a positive integer');
                }
                
    $this->$v;
                break;
        }

    Which as you can imagine an object with say 15 properties in it gets pretty cumbersome. If you use a consistent naming standard with get/set than you can use reflection too. That would involve writing the setter as appropriate, and than discovering the actual set method within the __set and calling it.
    There exists one other problem that cannot be dealt with in magic set, and that's by reference variables. Objects are okay since in 5.0+ they pass by object pointer reference, so its not quite the same, but changes within a __set to an external object will reflect in the external and vise-versa.
    Last edited by Fou-Lu; 04-19-2013 at 06:17 PM.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 

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

    coffeecup (04-19-2013)

  • #3
    New Coder
    Join Date
    Jul 2012
    Posts
    33
    Thanks
    18
    Thanked 0 Times in 0 Posts
    Thx a ton, I fully got the idea of the magic setter/getter wrong... =)

    This is the attempt for a fixed version:

    File car.php:
    PHP Code:
    <?php
    class Car {

        private 
    $color;
        private 
    $speed;
        private 
    $description;

        public 
    funtion __construct($color$speed$description) {
            
    $this->color$color;
            
    $this->speed$speed;
            
    $this->description $description;
        }

           public function 
    setColor($col) {
                
    $this->color $col;
           }
           public function 
    setSpeed($spd) {
                
    $this->speed$spd;
           }
           public function 
    setDesc($dsc) {
                
    $this->description$dsc;
           }
    }
    ?>
    File createCar.php:
    PHP Code:
    <?php
    include('car.php');
    $carcolor=$_POST['color'];
    $carspeed=$_POST['speed'];
    $cardesc=$_POST['desc'];
    $carname=$_POST['name'];
    $newentry=$_POST['new'];  //if newentry is false, it will update an existing obj. instead of creating it

    if ($newentry == true)
    {   
        
    $carname = new car($cartitle$carlink$cardesc);
    } else {
        
    $carname->setColor($color);
        
    $carname->setDesc($desc);
        
    $carname->setSpeed($speed);
    }

    ?>
    Btw. is there an easy approach to check if an object already exists so I don't have to use the "newentry == true" check?
    How about checking if an attribute exists, if no -> go for new object instead of updating it, something like:
    if $carname->setColor($color) == NULL then $carname = new car etc etc...?

    Thx in advance =)

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,979
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    That's much better.
    Define exists. Do you mean an object of type car already instantiated and running, or something within persisting storage? With just the code here, there is only ever this one created.
    There's an antipattern called a Singleton which would allow you to do this. It forbids direct construction of an object and instead you invoke it statically and it either creates an object for you, or reuses an existing one. Its not the *best* thing to do that typically, but I always say there are exceptions to the rules, so I guess it depends on what you want to do.
    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
    •