SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 64
  1. #26
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    The below class could represent a scenario where a Dog must belong to a vet.

    PHP Code:
    class Dog {

        protected 
    $vet;

        public function 
    __construct(Vet $vet) {
        
            
    $this->vet $vet;
        
        }
        
        public function 
    setVet(Vet $vet) {
        
            
    $this->vet $vet;
        
        }


    The below code represents a scenario where the dog may not belong to a vet.

    PHP Code:
    class Dog {

        protected 
    $vet;

        public function 
    __construct() {
        
        }
        
        public function 
    setVet(Vet $vet) {
        
            
    $this->vet $vet;
        
        }


    In the first example, a Dog can not be created without a vet. Thus, reflecting the idea that a Dog must belong to a vet. In the ladder example a Dog may be created without a vet. Thus, reflecting the idea that Dog is not required to belong to a vet.

  2. #27
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    And this is how I would handle those models without needing to rewrite a whole bunch of code. Just happens to be a active record but the interface could be applied to any pattern.

    PHP Code:
    class Dog extends ActiveRecord {

        public static 
    $table 'dogs';

        public static 
    $fields = array(
            
    'id'
            
    ,'vet_id'
        
    );
        
        public static 
    $foreignKeys = array(
            
    'vet_id'=>array('Vet','id')
        );
        
        public static 
    $belongsTo = array('vet');

    }

    class 
    Vet extends ActiveRecord {

        public static 
    $table 'vets';

        public static 
    $fields = array(
            
    'id'
            
    ,'name'
        
    );
        
        public static 
    $hasMany = array('dogs');


    PHP Code:
    $vet = new Vet(2// pull down a existing vet with a primary key of 2
    $dog = new Dog(); // create a empty dog object

    $dog->vet $vet// associate dog with vet

    $dog->save(); // insert dog object into database 

  3. #28
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oddz View Post
    No, a Vet is a vet. A Vet can't have another vet can it? If Vet where to have a property named vet you would be saying that vet has a vet, which isn't true from my understanding of your structure.



    Well, no you would have setters for every property of that class. However, the id is the only one that is necessary to resolve its association with a dog to keep it simple.

    This is where things become a little complicated. A Dog by itself is a Dog. A Vet by itself is a Vet. However, the moment you say a Dog belongs to a vet you need to have a way to resolve that association. The way the previous code resolves that association is by making the associated vet instance a property of the dog class. So a Dog actually has a vet which is expressed by its vet property.

    PHP Code:
    $dog = new Dog();
    $vet = new Vet();

    $dog->setVet($vet); // dog now belongs to this vet 
    (...)

    Now I guess the question is whether to not a dog MUST belong to a vet. If a Dog MUST belong to a vet that in theory in can't exist without out it. So it would be appropriate to make sure that a Dog always has a Vet.

    With that said, vet_id isn't actually a property of the Dog class. Instead vet_id maps to vet. Then we can get its unique id by calling vet->getId().

    Hopefully this isn't to much. However, associations are a complicated matter.
    Perfect!! I believe I get it.


    Quote Originally Posted by oddz View Post
    The below class could represent a scenario where a Dog must belong to a vet.

    PHP Code:
    class Dog {

        protected 
    $vet;

        public function 
    __construct(Vet $vet) {
        
            
    $this->vet $vet;
        
        }
        
        public function 
    setVet(Vet $vet) {
        
            
    $this->vet $vet;
        
        }


    The below code represents a scenario where the dog may not belong to a vet.

    PHP Code:
    class Dog {

        protected 
    $vet;

        public function 
    __construct() {
        
        }
        
        public function 
    setVet(Vet $vet) {
        
            
    $this->vet $vet;
        
        }


    In the first example, a Dog can not be created without a vet. Thus, reflecting the idea that a Dog must belong to a vet. In the ladder example a Dog may be created without a vet. Thus, reflecting the idea that Dog is not required to belong to a vet.
    I see, and it makes sense, when we put the vet on a dog constructor each time we instantiate a dog class, a vet will be there. ok. If we don't do that, we will only have a vet/dog association on some methods of our dog class.


    Obviously your last posted code is better that the one I'm about to make, however, I do prefer to understand a bad code, then to not completely understand a good code. Probably you will explain, but I have to much already and for a newbie, doing the code again and again, could be a good thing.


    I will present some code tomorrow, based on your post. Thanks a million. Really really.


    Regards,
    Márcio

  4. #29
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    Quote Originally Posted by oikram
    Obviously your last posted code is better that the one I'm about to make, however, I do prefer to understand a bad code,
    The code isn't bad at all. I just have a more generic way of handling everything so that I don't need to repeat everything. I like to operate under the DRY principle

    However, a Gateway pattern that is hard coded can work equally as well. In fact it may be better in some respects because you don't need to account for all the possible scenarios. I just hate repeating code. As you get further into what your doing you'll begin to see what I mean. However, creating a generic system/library is a huge task. Its a project in itself. I've been working on mine for about 6 months on and off. So its not generally something that is quick and easy unless your just supporting very basic generalizations such as one way mappings.

  5. #30
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok...

    I have this already:

    Dog.class.php

    PHP Code:
    Class Dog {
    private 
    $_id_dog;
    private 
    $_name_dog;
    private 
    $_id_vet;
    //setters

    public function setIdDog$id_dog ){        
        
    $this->_id_dog $id_dog;    

    public function 
    setNameDog$name_dog ){        
        
    $this->_name_dog $name_dog;    
    }     
    public function 
    setIdVetVet $id_vet ){        
        
    $this->_id_vet $id_vet;    
    }    

    //getters

    public function getIdDog ($id_dog) {
        
    $this->_id_dog $id_dog;
                    
    }
    public function 
    getNameDog ($name_dog) {
        
    $this->_name_dog $name_dog;
                    
    }
    public function 
    getIdVet (Vet $id_vet) {
        
    $this->_id_vet $id_vet;
                    
    }
    //end of dog class. 

    1) Since I don’t want to have a representation of the whole vet object here, but only the id, can I pass only the id here? Or this decision is to be made on the instances side?


    2) We need to have a getter to the _id_vet; property to. Right? Because my objects will not
    access the dog properties directly, instead the class must get the proprieties with methods, and that public methods will be accessible to my objects, so that the objects can access the class properties trough the methods. Is this correct?



    DogDAO.class.php

    PHP Code:
    class DogDAO extends GeneralDAO {
    public function 
    insertDog(Dog $dog) {
    $vetId $dog->vet->getVetId();
    $stmt $this->_dbh->prepare("INSERT INTO DOG (name_dog, id_vet) VALUES (?, ?)");
    $stmt->bindParam(1$dog->getNameDog(), PDO::PARAM_STR );
    $stmt->bindParam(2$dog->vet->getVetId(), PDO::PARAM_INT);

    $stmt->execute();
    }
    }
    //end of DogDAO class. 


    3) This is a correct approach?
    PHP Code:
    $stmt->bindParam(2$dog->vet->getVetId(), PDO::PARAM_INT); 
    4) If so, do I need to declare $vetId on this line?
    PHP Code:
    $vetId $dog->vet->getVetId(); 
    ?



    Vet.class.php

    PHP Code:
    class Vet {
    private 
    _id_vet;
    private 
    _name_vet;
    //setters
    public function setIdVet$id_vet ){
    $this->_id_vet $id_vet;    

    public function 
    setNameVet$name_vet ){        
        
    $this->_name_vet $name_vet;    
    }
    //getters
    public function getIdVet ($id_vet) {
        
    $this->_id_vet $id_vet;
                    
    }
    public function 
    getNameVet ($name_vet) {
        
    $this->_name_vet $name_vet;
                    
    }
    // end of Vet class. 

    VetDAO.class.php

    PHP Code:
    class VetDAO extends GeneralDAO  {
    public function 
    listVets() {
    $stmt null;
    $stmt $this->_dbh->query("SELECT * FROM VETS");
    $rows $stmt->fetchAll(PDO::FETCH_OBJ);
    return 
    $rows;
    }
    //end of VetDAO class. 


    Thanks a lot,
    Márcio

  6. #31
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    Looks like you have the right idea.

    PHP Code:
    $stmt->bindParam(2$dog->vet->getVetId(), PDO::PARAM_INT); 
    That line is going to result in an error because vet isn't a property of the dog object.

    However, I would advise that you make it a property of the Dog class. Otherwise, there isn't a way to access a vet through a dog.

    1.) With that said, I would do both. have the vet_id be a property and vet. Vet_id is an integer and vet is a Vet instance. You could just have a vet though in theory. Only having the vet_id inside the Dog doesn't make it easy to access information about the dogs vet - does it?

    PHP Code:
    $dog->getVet()->getId(); 
    Where that would come in handy is a select statement that selects all dogs and their vet. You could then load the dog object with the vet. Otherwise, you can't do this. Normally I would handle this with dynamic properties though to make it flexible.

    3.) Yes, if you don't need to perform any type of validation checking on the vet_id. For instance if the vet id hasn't been set then the query would error.

    On a aesthetic note it doesn't seem useful to postfix the getter and setters with the class name. If anything it just results in more code.

  7. #32
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oddz View Post
    PHP Code:
    $stmt->bindParam(2$dog->vet->getVetId(), PDO::PARAM_INT); 
    That line is going to result in an error because vet isn't a property of the dog object.
    Dog object. Ok. That's one part of the code that I'm not getting clear:

    When we do this:
    PHP Code:
    public function insertDog(Dog $dog
    We are using Type Hinting to ensure that $dog parameter passed on insertDog method, be of the "type" Dog. Ok.
    What I'm not yet getting is: how does php know that when we put $dog inside () we are actually pointing to the Dog class, and hence, we can later, on the insertDog method, use something like $dog->getVetId() for example... ? Type Hinting is not doing that, Type Hinting is only there to ensure that that's the case, but, we can perfectly have something like insertDog($dog). So how does php (and we) know that we are talking about the Dog class?

    Quote Originally Posted by oddz View Post
    However, I would advise that you make it a property of the Dog class. Otherwise, there isn't a way to access a vet through a dog.
    A composition relation between Dog and Vet classes demands that we create an instance of vet inside the dog class as a property. I was having problems accepting this because I have thought, if I only need the VetID why should I have the complete object referenced there? But the feature is: having a Vet Instance as a Dog property allow us to call other Vet methods, and associate them with the Dog Class on many possible ways; And we will not call all the object at once, we can designate what method of the Vet Class we want to deal with on our Dog class, so let's instantiate the Vet class, creating a vet object inside the dog class, as a property.
    Is this "thinking process" ok?


    Quote Originally Posted by oddz View Post
    With that said, I would do both. have the vet_id be a property and vet. Vet_id is an integer and vet is a Vet instance.
    But isn't it better to have only the vet object as a property and forget about the vet_id as a property. And, when we need to access vet_id we will doing so, using the getVetId method trought the Vet object that was created as a Dog property?

    You seem to reply to this by saying:
    Quote Originally Posted by oddz View Post
    You could just have a vet though in theory.
    . So, we we can actually put this theory on practice, right?


    Quote Originally Posted by oddz View Post
    Only having the vet_id inside the Dog doesn't make it easy to access information about the dogs vet - does it?
    Nop. If we do that, we are stuck by the Id.




    Quote Originally Posted by oddz View Post
    On a aesthetic note it doesn't seem useful to postfix the getter and setters with the class name. If anything it just results in more code.
    If when we have something like this :
    PHP Code:
    $dog->getVet()->getId(); 
    It's always clear that the getId is the Vet Id and not the Dog Id, then, I will clean up my code (less words less), and follow your advice.



    Thanks a lot for the support,
    Márcio

  8. #33
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    Quote Originally Posted by oikram
    A composition relation between Dog and Vet classes demands that we create an instance of vet inside the dog class as a property.
    Well you should create the vet outside of the dog class. Then pass it to the dog upon constructing an instance or via a setter method such as setVet(Vet $vet);

    Quote Originally Posted by oikram
    But isn't it better to have only the vet object as a property and forget about the vet_id as a property. And, when we need to access vet_id we will doing so, using the getVetId method trought the Vet object that was created as a Dog property?
    Sounds good in theory, but if you need to deal with associations its much easier to resolve something to a primitive value then a object. I don't think that will be a problem though in your instance because everything is hard coded.

    Quote Originally Posted by oikram
    What I'm not yet getting is: how does php know that when we put $dog inside ()
    The type will only be checked if you use type hinting. Otherwise its all up to the developer to treat the parameter as the intended type. When you use type hinting your essentially saying this item must be that. In this the item must be a Dog. If it is not the code won't even run. The type checking happens before any code is run. Which easier to trouble shoot then a misusing a intended Dog instance. For instance, calling a method that doesn't exist. Even with type hinting its possible to call non-existent methods. However, if you treat a Dog as a Dog it shouldn't be a problem.

    Placing it out of content here is a simple example:

    PHP Code:
    class Person {

        public function 
    getName() {
        
            return 
    'tom';
        
        }

    }



    function 
    showName(Person $person) {

        echo 
    $person->getName();

    }

    $person = new Person();
    showName($person); 

    You could further abstract this using a interface to to make the code even more flexible.

    PHP Code:
    interface Nameable {

        public function 
    getName();    

    }

    class 
    Person implements Nameable {

        public function 
    getName() {
        
            return 
    'tom';
        
        }

    }

    function 
    showName(Nameable $nameable) {

        echo 
    $nameable->getName();


    Now, we could create classes for several nameable that share nothing in common with each other besides for the interface. Which results in very loosely coupled code.

    PHP Code:
    class Dog implements Nameable {

      public function 
    getName() {
        return 
    'fred';
      }

    }

    class 
    Vet implements Nameable {

      public function 
    getName() {
        return 
    'Happy Pet';
      }


    Now, a dog, vet and person can be passed to the showName() method because they implements Nameable and gain that type. Even though they share nothing else in common it doesn't matter as long as you program to the Nameable interface. As long as the item is Nameable you can always assume that the interface methods exist on the object. This is essentially called programming to interfaces. How the methods do what they doesn't matter to "anyone" besides the class itself. Maybe a little advanced, but maybe it clears up some things regarding type and why its always good to type hint?

  9. #34
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oddz View Post
    Well you should create the vet outside of the dog class. Then pass it to the dog upon constructing an instance or via a setter method such as setVet(Vet $vet);
    Ok. So, when we have this:

    PHP Code:
    public function setVet(Vet $vet) {    
        
    $this->_vet $vet;             

    We are not creating an object $vet anywhere.


    (Now the hard part)
    Instead, we are using a setter method to "point" to the $vet object that will be accessed,
    when we do something like this?

    PHP Code:
    $dog = new Dog();
    $vet = new Vet();

    $dog->setVet($vet); 
    And when we do
    PHP Code:
    $dog->setVet($vet); 
    we will know that this $vet will be of the type Vet, because Type Hinting as say so.

    Close?



    Regards,
    Márcio


    hm... maybe talking of a setter like something that "points" is already wrong at the first place... It seems that I'm not getting the point of this setter method. :s
    Last edited by oikram; Apr 20, 2009 at 13:41. Reason: add few lines at the end...

  10. #35
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    yep, that is pretty much the idea.

    We are not creating an object $vet anywhere.
    Well you need to create it somewhere to pass it in, but no its not being created inside that method.

    Quote Originally Posted by oikram
    we will know that this $vet will be of the type Vet, because Type Hinting as say so.
    Yep, it is safe to say that the _vet property will always be a vet. Unless you modify it from within class, but you won't .

    In many languages such as Java this isn't really the case. When a variable is declared you must also define its type. However, in theory you can't always guarantee that the _vet instance will be a vet because class methods could change it in php. However, its a relatively safe assumption in php so long as the property is not public and you type hint the setter.

  11. #36
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    hm... maybe talking of a setter like something that "points" is already wrong at the first place... It seems that I'm not getting the point of this setter method. :s
    Nope, it's all correct

    It means you can do something like:
    PHP Code:
    $lassie = new Dog();
    $bobby = new Dog();
    $drEvil = new Vet('Dr Evil');
    $lassie->SetVet($drEvil);
    $bobby->SetVet($drEvil);
    echo 
    $lassie->getVet()->getName(); //Dr Evil
    echo $bobby->getVet()->getName(); //Dr Evil
    $drEvil->SetName('Mike Myers');
    echo 
    $lassie->getVet()->getName(); //Mike Myers
    echo $bobby->getVet()->getName(); //Mike Myers 
    This is, in fact, a handy thing indeed. If multiple objects share an object, changing that object affects the way it works with the other objects.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  12. #37
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ufff...

    Ok. I will try to put all together tomorrow and see if I understand how it works.

    Thanks a trillion!
    Márcio

  13. #38
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    Setter is used to make sure the object has total control over its state. The objects state is expressed in its properties. Without setters and non public properties the objects state can be altered directly. In this case one could easily set the vet property to something other then a vet.

    // if vet were public
    $dog = new Dog();
    $dog->vet = 'ha ha ha screwed you!';

    Now when you attempt to treat that property as a vet a error will occurs because a string isn't a vet. A string doesn't have the public interface which you can assume a vet instance has. By using setters and type hinting you can easily control and make sure that the vet instance is always a vet unless you alter it from within the scope of the class.

  14. #39
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok... here is the form that allow us to insert the dog data and the corresponding vet data.

    insert.dog.php
    PHP Code:
    <html>
      <head>
        <?php
          
    require_once("VetDAO.class.php");
          
    $vet = new VetDAO();
        
    ?>
      </head>

      <body>
        <form action="processinsertdog.php" method="post">
           <?php 
                  
    echo "<select id='ListVets' name='ListVets'>";  
                  foreach(
    $vet->listVet() as $row){
             echo 
    "<option value=".$row->ID_VET.">".$row->NAME_VET."</option>"
         echo 
    "</select>";
          
    ?>

          <input type="text" name="txt_name_dog" />

        </form>
      </body>
    </html>

    And here is the php where this form will be processed:

    processinsertdog.php
    PHP Code:
    <html>
      <head>
        <?php
          $id_vet
    =$_POST[ListVets];
          
    $dogname=$_POST[txt_name_dog];


          
    $dog = new Dog();
          
    $dog->setName($dogname);
          
    $dog->getVet->setId($id_vet); /*here we are setting... and latter on, on our class DogDAO insert() method, we will be getting:  $dog->getVet->getId(). (is this correct?)*/
          
          
    $dogdao = new DogDAO();
          
    $dogdao->insert();

        
    ?>

      </head>

      <body>
           <p>Finally, you have inserted a dog! But, hey, go see on your database, just in case…</p>
      </body>
    </html>

    Here is the DogDAO Class:

    PHP Code:
    class DogDAO extends GeneralDAO {

    public function 
    insertDog(Dog $dog) {

    $stmt $this->_dbh->prepare("INSERT INTO DOG (name_dog, id_vet) VALUES (?, ?)");

    $stmt->bindParam(1$dog->getName(), PDO::PARAM_STR );

    $stmt->bindParam(2$dog->getVet->getId(), PDO::PARAM_INT);



    $stmt->execute();

    }

    }
    //end of DogDAO class 





    What I'm not getting is:
    On processinsertdog.php, this line:
    PHP Code:
    $dog->getVet->setId($id_vet); 
    will not work, because I need to have a Vet object for this to work… right?
    What I’m not yet getting is where should we create this Vet Object?




    Some lights will be greatly appreciated.
    Thanks a lot,
    Márcio

  15. #40
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    PHP Code:

    <html>

      <head>

        <?php

          $id_vet
    =$_POST[ListVets];
          
    $dogname=$_POST[txt_name_dog];

         
    $dogdao = new DogDAO();
         
    $vetDAO = new vetDAO();

          
    $vet $vetDAO->find(array('id'=>$id_vet)); // error handling if vet returns null (ie. primary key doesn't exist)

          
    $dog = new Dog();
          
    $dog->setName($dogname);
          
    $dog->setVet($vet);

          
    $dogdao->insert($dog);



        
    ?>



      </head>



      <body>

           <p>Finally, you have inserted a dog! But, hey, go see on your database, just in case…</p>

      </body>

    </html>

    The problem with this:

    PHP Code:

          $dog
    ->getVet()->setId($id_vet); /*here we are setting... and latter on, on our class DogDAO insert() method, we will be getting:  $dog->getVet->getId(). (is this correct?)*/ 
    Your setting the foreign key without making certain the dependency exists. By actually creating a vet instance you guarantee the id references a actual vet.

    PHP Code:
      $vet $vetDAO->find(array('id'=>$id_vet)); // error handling if vet returns null (ie. primary key doesn't exist) 
    That line is essentially needs to locate the vet with the specified primary key and return it. Not sure of the aesthetics in your system though.

  16. #41
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Your setting the foreign key without making certain the dependency exists. By actually creating a vet instance you guarantee the id references a actual vet.
    Ok. before I put myself into more trouble, let's just suppose that it's certain that the dependency exists.
    (I have no idea what should I put on the find method, but, before that, I'm trying to understand how this "things" communicate between them...


    I've made a couple of changes on "processinsertdog.php" file:

    Before this:
    $dog->getVet()->setId($id_vet);

    I've put:
    $vet = new Vet();
    $dog->setVet($vet);

    So I have this:
    PHP Code:
    //instantiate vet.
    $vet = new Vet();

    //put the instance as a Dog property using the setVet method:
    $dog->setVet($vet);

    //assign the ID passed on the $_POST 
    //and stored in $id_vet variable, to the 
    //id_vet property, using the setId method:
    $dog->getVet()->setId($id_vet); 
    I'm getting the following error:
    Fatal error: Call to a member function setId()

    The reason why I'm unable to solve this error, is sufficient prof that I'm a little bit lost between this objects and class communications, and I have not completely understand how classes and objects communicate with each other.


    Anyway, please, sitepoint gurus, just throw me something about this, so that I can read more, and maybe grasp something here...


    Regards,
    M&#225;rcio

  17. #42
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Duplicate post. I'm sorry. Delete this one.
    Last edited by oikram; Apr 22, 2009 at 05:28. Reason: It as been posted twice.

  18. #43
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK...

    Ok. I'm really sorry for this newbie questions. Really. But this is the kind of questions that is between the code and the books, and that's why I use the mailing lists and forums for this.

    So, the Dog::getVet method, needs to return an instance of a class, I was having this:

    $dog->getVet->setId($id_vet);

    Question 1)
    And this is not even correct, because, to call a method I need to had the (). Right?

    So I need to have something like this instead:

    $dog->getVet()->setId($id_vet);


    However, since I have used Type Hinting (a newbie that forget to put the "" on the POST strings, is using Type Hinting and DAO and ahahaha - I'm dead! :| ),
    I need to put as an Argument, an object of the type VET.

    Question 2)
    Luckily (yes, because, I still don't understand why)?
    I have instantiated the vet class using $vet = new Vet; so, if I do this:

    $dog->getVet($vet)->setId($id_vet);

    It seems to work...

    Is this ok?


    Thanks once more,
    Márcio

  19. #44
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    And now for the complete "newbility":

    I have done all this trips trying to understand what I'm doing.
    I'm now asking myself, on this scenario, since I instantiate the vet, why not just do something like this:

    $vet->setId($id_vet);

    :s


    AHHH!!!!

    I mean:

    If, for using this,
    PHP Code:
    $dog->getVet($vet)->setId($id_vet); 
    I need to create a vet instance,
    why not just using:
    PHP Code:
    $vet->setId($id_vet); 

    ?


    Regards,
    Márcio

  20. #45
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I mean, at the beginning, I was trying to stablish a Composition Association relation between the dog and the vet classes, but I believe I completely miss that, the moment I instantiate the vet class on my processinsertdog.php page.

    Right?

  21. #46
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Last question, promise:

    When I do this:

    $stmt->bindParam(3, $dog->getVet()->getId(), PDO::PARAM_INT);

    I get this:
    Catchable fatal error: Argument 1 passed to Site::getVet() must be an instance of Vet, null given.


    It seems that, for running something like this:
    $dog->getVet()->getId()

    I need to have an Instance of the vet created, inside the dog class.
    But the propose was, to create an association between vet and dog, by
    passing "the Veterinary object to the method".

    I was trying to accomplish this, by making use of the setters and getters, hence, I was hoping, without the need to instantiate the vet class, inside the dog class, however, at the end of all this loops, its seems that we actually NEED to instantiate the vet class, inside the dog class.

    Is this the proper way to pass the veterinary object to the method?


    Regards,
    M&#225;rcio
    Last edited by oikram; Apr 22, 2009 at 06:16. Reason: Need to translate the error. I'm working on portuguese, but, to easy things, I was translating to english on equivalent terms

  22. #47
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    Quote Originally Posted by oikram
    I was trying to accomplish this, by making use of the setters and getters, hence, I was hoping, without the need to instantiate the vet class, inside the dog class, however, at the end of all this loops, its seems that we actually NEED to instantiate the vet class, inside the dog class.

    Is this the proper way to pass the veterinary object to the method?
    No, the vet should be placed inside through a setter.

    Quote Originally Posted by oikram
    $dog->getVet($vet)->setId($id_vet);
    This doesn't make any sense. A getter gets something. That should be the below.

    Quote Originally Posted by oikram
    $dog->getVet()->setId($id_vet);
    If the above code results in an error then either vet is null or the setVet() isn't returning the object.

    Quote Originally Posted by oikram
    why not just using:

    $vet->setId($id_vet);
    That is how it should be done. Either way version 5 passes objects by reference.

    $vet = new Vet();
    $dog->setVet($vet);
    $vet->setId($vet_id);

  23. #48
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    I would also recommend looking into some of the below libraries. You could possibly just use one of them so that you can place more focus on getting your site done rather then worrying about moving information between the database and domain. Unless of course the problem intrigues you as much as it does me.



    There are plenty others out there but those would be the ones that I've found the most flexible, feature rich and easy to use/understand.

  24. #49
    SitePoint Wizard
    Join Date
    Feb 2009
    Posts
    1,006
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have change the getVet method by removing the Type Hinting.
    Now he inserts on the database, (great progress!) however he inserts all null values.

    Before trying to solve that null insertion problem, I have some questions:

    1)
    Why does something like this makes no sense:
    PHP Code:
    $dog->getVet($vet)->getId($id_vet); 
    And something like this, makes sense:
    PHP Code:
    $dog->getVet()->getId($id_vet); 

    2)

    Something like this:
    PHP Code:
    $dog->getVet()->setId($id_vet); 
    It makes sense to use on my dog CLASS. This is the way we have to access or vet OBJECT using a setter
    on our dog CLASS. Is this precise?


    3)
    But since we are on a class, we can put it, like:
    PHP Code:
    $this->getVet()->setId($id_vet); 
    So, on our insert method we can have:
    PHP Code:
    $stmt->bindParam(3$this->geVet()->getId($id_vet), PDO::PARAM_INT); 
    Instead however, we are having:
    PHP Code:
    $stmt->bindParam(3$dog->geVet()->getId($id_vet), PDO::PARAM_INT); 
    Why do we have $dog instead of $this?

    The class is extendend, I know that we cannot call by $this the properties or methods on our
    super class. We have to use :: $mysuperclass::something. But here, we are accessing $this class, so, why not using $this instead?

    3.1) Does this has something to do with the fact that we are passing params inside or method: public function insert(Dog $dog) ?



    Thanks a lot,
    M&#225;rcio

  25. #50
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,194
    Mentioned
    17 Post(s)
    Tagged
    5 Thread(s)
    this refers to the object which the method resides. The method getVet doesn't reside inside the dogDAO class it resides inside the Dog class. The Dog instance is passed to the dogDAO insert() method because otherwise it is inaccessible and out of scope of that method.

    When you use getters your getting something that exists. Therefore, generally it would be incorrect to pass something as a parameter. Setters on the other hand set something so it is appropriate to pass a argument in order to set it. With that said the below code would be correct.

    $dog->getVet()->setId($id);

    or to get the id of the vet is its previously been set

    $dog->getVet()->getId();


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
  •