SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    SitePoint Zealot
    Join Date
    Aug 2002
    Posts
    168
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    class constructors

    Hi

    I am just really sinking my teeth in to OOP PHP as I have been using my own classes for a while now but have not really got the hang of a full aplication architecture. I have read numerous articles on the subject and I am just starting to understand how I can use this concept.

    One thing that is puzzling me at the moment though is how many of these classes are constructed. For instance I see most classes constructed in the following manner...
    PHP Code:
    Class MyClass()
    {
        var 
    $someVariable;
     
        function 
    MyClass(& $someVariable)
        {
             
    $this->someVariable =& $someVariable;
        }

    I don't think I understand referencing properly but isn't this the same as doing this...
    PHP Code:
    Class MyClass()
    {
        var 
    $someVariable;
     
        function 
    MyClass($defaultInputVariable)
        {
             
    $this->someVariable $defaultInputVariable;
        }

    If it is not then I would greatly appreciate an explanation of the differences. If it is then I would like to knwo whatt he advantage of the firsth process, as there obviously is one.

    thx in advance

  2. #2
    SitePoint Evangelist
    Join Date
    Jul 2001
    Location
    Michigan, USA
    Posts
    414
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There is a difference in what you did. I don't think you'll notice a difference in useage, but the second method passes by reference, while the first makes a copy of the object.

    Edit:

    I'm an idiot, reverse first with second and second with first in my entire post...I apoligize for any confusion.


    You'll probably want to use the second method when you can to save memory. I know in C++, you also don't get the effect that you want when copying sometimes.
    Last edited by Andy Tomaka; Jul 17, 2003 at 21:28.

  3. #3
    SitePoint Zealot
    Join Date
    Jun 2003
    Location
    Middle / East TN
    Posts
    127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Andy Tomaka
    There is a difference in what you did. I don't think you'll notice a difference in useage, but the second method passes by reference, while the first makes a copy of the object.

    You'll probably want to use the second method when you can to save memory. I know in C++, you also don't get the effect that you want when copying sometimes.
    It's the other way around, use & to reference, meaning it points to the original object instead of working from a copy of the object. Here's an example using a simple string

    $one = 'Hello';
    $two = ' World';

    $three = $one;
    $four =& $two;

    $three = ' Yep';
    $four = ' weee!';

    echo $one . ' -- ' . $two;

    Prints:
    Hello -- weee!

    The difference is that $three is working from a copy of $one while $four is actually pointing to $one. It works the same way when using a function:

    $hello = 'hey';

    function go (& $string) {
    $string .= ' (again)';
    }

    go($hello);
    echo $hello;

    Prints:
    hey (again)
    There are 10 kinds of people in this world,
    those who can read binary and those who can't.

  4. #4
    SitePoint Zealot
    Join Date
    Oct 2002
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Also there is no need for the & in
    PHP Code:
    $this->someVariable = &$someVariable
    pass-by-reference declarations should be done on the function declaration itself
    i.e.
    PHP Code:
    function &$foo() {
       
    // do this if you want to pass-by-referece the
       // returned.
       
    return;
    }

    function 
    $foo(&$bar) {
        
    $this->bar $bar// note the lack of '&' on this line. (not necessary)


  5. #5
    SitePoint Evangelist
    Join Date
    Jul 2001
    Location
    Michigan, USA
    Posts
    414
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    haha, that's my bad bonk. I did mean that the ampersand meant reference. Evidently, I confused myself with the ordering of my post or something. Thanks for the correction.

    shoebox, are you sure about that. I am not saying you are incorrect, but I've always seen it with both ampersands in PHP. I don't see why people would write like that if they didn't have to. There must be some reason.

  6. #6
    SitePoint Zealot
    Join Date
    Aug 2002
    Posts
    168
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks for the replies

    So let me get this straight. The original example I gave can be done like this...
    PHP Code:
    Class MyClass()
    {
        var 
    $var1
        function 
    MyClass(& $arg1
        {
            
    $this->var1 $arg1;
            
    // This sets var1 to a value that is a reference 
            // to arg1, not a copy of arg1 as would be the 
            // case in the second example I provided
        
    }
    }
    // It is done with $this->var1 = $arg1; and doesn't 
    // require the ampersand e.g. $this->var1 =& $arg1; 
    So does this mean that by setting the value of $var1 from a reference to $arg1 instead of a copy of $arg1 it makes the script more efficient because PHP doesn't have to make another copy of $arg1 before assiging it's value to $var1?

    cheers

  7. #7
    Sidewalking anode's Avatar
    Join Date
    Mar 2001
    Location
    Philadelphia, US
    Posts
    2,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No no no.

    That code passes a reference to $arg1 into the function, but it copies $arg1 to $this->var1. You'll probably want to both pass the argument in as a reference (the ampersand in the argument list) and assign it by reference also (the ampersand after the =.)

    harry's article on references in PHP4 may clear things up a bit.
    TuitionFree a free library for the self-taught
    Anode Says... Blogging For Your Pleasure

  8. #8
    "Of" != "Have" bronze trophy Jeff Lange's Avatar
    Join Date
    Jan 2003
    Location
    Calgary, Canada
    Posts
    2,063
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That article is quite good, however it contains some flaws in the way PHP uses internal reference counting.

    (PHP does not actually create a copy in memory of a variable containing the same value, so more memory is not used. Also, since PHP has internal reference counting, and keeps track of memory locations anyways, passing by reference shouldn't be any slower.)

    On a related note, because of internal reference counting, I'm not entirely sure of performance gains by passing objects by reference, although I hear that there is, I'm not completely sure, does PHP use internal reference counting for objects? I don't know. It would be something interesting to ask one of the core developers about.
    Who walks the stairs without a care
    It shoots so high in the sky.
    Bounce up and down just like a clown.
    Everyone knows its Slinky.

  9. #9
    SitePoint Zealot
    Join Date
    Oct 2002
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    turns out you are right.. and I was mistaken..

    In the case where you would be just returning $foo instead of setting $this->$foo = $foo, you would need the & like this $this->foo =& $foo;

    Sorry for that...

    when all else fails turn to the php manual.
    http://us3.php.net/manual/en/languag...ences.pass.php

    "You can pass variable to function by reference, so that function could modify its arguments. The syntax is as follows:
    PHP Code:
    function foo (&$var)

    $var++;
    }
    $a=5;
    foo ($a);// $a is 6 here 
    Note that there's no reference sign on function call - only on function definition. Function definition alone is enough to correctly pass the argument by reference.
    Following things can be passed by reference:
    • Variable, i.e. foo($a)
    • New statement, i.e. foo(new foobar())
    • Reference, returned from a function, i.e.:
    PHP Code:
    function &bar()
    {
    $a 5;
    return 
    $a;
    }
    foo(bar()); 
    See also explanations about returning by reference.
    Any other expression should not be passed by reference, as the result is undefined. For example, the following examples of passing by reference are invalid:
    PHP Code:
    function bar() // Note the missing &

    $a 5; return $a;
    }
    foo(bar());
    foo($a 5); // Expression, not variable
    foo(5); // Constant, not variable 
    These requirements are for PHP 4.0.4 and later. "
    Last edited by shoebox; Jul 18, 2003 at 15:11.

  10. #10
    SitePoint Zealot
    Join Date
    Aug 2002
    Posts
    168
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks for the replies everyone...

    I get it!
    PHP Code:
    Class MyClass
    {
        var 
    $var1
        function 
    MyClass(& $arg1
        {
            
    $this->var1 $arg1;
        }
    }
    $someVar 1;
     
    $myClass = new MyClass($someVar);
     
    $someVar 2;
     
    echo 
    'var1 = '$myClass->var1
    This will echo "var1 = 1" because $var1 is set to a copy of $arg1 when it is passed to the constructor, which is the value of 1.
    PHP Code:
    Class MyClass
    {
        var 
    $var1
        function 
    MyClass(& $arg1
        {
            
    $this->var1 =& $arg1;
        }
    }
    $someVar 1;
     
    $myClass = new MyClass($someVar);
     
    $someVar 2;
     
    echo 
    'var1 = '$myClass->var1
    This will echo "var1 = 2" because $var1 is a direct reference to $someVar and as $someVar's value has changed so does the value of $var1.
    PHP Code:
    Class MyClass
    {
        var 
    $var1
        function 
    MyClass(& $arg1
        {
            
    $arg1++;
            
    $this->var1 $arg1;
        }
    }
    $someVar 1;
     
    $myClass = new MyClass($someVar);
     
    $someVar 2;
     
    echo 
    'var1 = '$myClass->var1
    This will echo "var1 = 2" because a copy of $arg1 that is passed to the constructor is incemented by one then $var1 is set to a copy of the new value. But...
    PHP Code:
    Class MyClass
    {
        var 
    $var1
        function 
    MyClass(& $arg1
        {
            
    $arg1++;
            
    $this->var1 =& $arg1;
        }
    }
    $someVar 1;
     
    $myClass = new MyClass($someVar);
     
    $someVar 2;
     
    echo 
    'var1 = '$myClass->var1
    This will echo "var1 = 2" because $var1 only ever references the orginal value of $someVar therefore the incremented copy of $arg1 never gets refered to, it still gets incemented though.

    Thanks again!

  11. #11
    SitePoint Addict
    Join Date
    Aug 2002
    Location
    Ottawa, Ontario, Canada
    Posts
    214
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    (Note I am very tired right now so just pretend my versions of the functions are in a class so I can get away with the "$this" references)

    Quote Originally Posted by shoebox
    PHP Code:
    function foo (&$var)

    $var++;
    }
    $a=5;
    foo ($a);// $a is 6 here 
    Note that there's no reference sign on function call - only on function definition. Function definition alone is enough to correctly pass the argument by reference.
    I don't think the above is the same as:
    PHP Code:
    function foo (&$var)

    $this->my_var=$var;
    $this->my_var++;
    }
    $a=5;
    foo ($a);// $a is 5 here 
    In your example the variable var is directly referencing the integer that is external to the function (I agree 100% with you so far).

    The second example has var passed in as a reference however, the assignment to my_var is done by copy. There isn't some sort of transitive property at work here...

    Finally:
    PHP Code:
    function foo (&$var)

    $this->my_var=&$var;
    $this->my_var++;
    }
    $a=5;
    foo ($a);// $a is 6 here 
    Now my_var will be a reference to the integer that exists somewhere outside the function...

    Cheers,
    Keith.

  12. #12
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I find it very useful to do this:
    PHP Code:
    define('FOO_DATA''_foo_data_index');

    class 
    foo
    {
      var 
    $_data;
      function 
    foo()
      {
        if (!
    array_key_exists(FOO_DATA,$_SESSION)) {
          
    $_SESSION[FOO_DATA] = array();
        }
        
    $this->_data =& $_SESSION[FOO_DATA];
      }

    now every reference to $this->_data is seamlessly tucked away in the session!
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.


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
  •