SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    SitePoint Zealot
    Join Date
    Aug 2010
    Posts
    193
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    what's the meaning of ::

    I'm reading that :: is used to access class methods that perform static operations, i.e., classes that do not need to be instantiated.

    But I've also seen this in some examples: parent::constructor($value)

    Don't constructors only run when a class is instantiated?

  2. #2
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    64 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by sessions View Post
    I'm reading that :: is used to access class methods that perform static operations, i.e., classes that do not need to be instantiated.

    But I've also seen this in some examples: parent::constructor($value)

    Don't constructors only run when a class is instantiated?
    Not when the child has its own constructor. Only one construct will be called. EDIT: This is the case for any magic method (destruct, etc)

    Code PHP:
    class Parent {
     
      public function __construct() {
        echo "I'm a parent.\n";
      }
    }
     
    class Child extends Parent {
     
      public function __construct() {
        echo "I'm a child.\n";
      }
    }
     
    $t = new Child(); // I'm a child.

    This is why you'll see your class calling parent construct..

    Code PHP:
    class Parent {
     
      public function __construct() {
        echo "I'm a parent.\n";
      }
    }
     
    class Child extends Parent {
     
      public function __construct() {
        parent::construct();
        echo "I'm a child.\n";
      }
    }
     
    $t = new Child(); 
    // I'm a parent.
    // I'm a child.

    So with that being said, I'm not sure I'd say that :: is used for static methods as you can call any public function in the parent in the same way I just called the constructor.

  3. #3
    SitePoint Zealot
    Join Date
    Aug 2010
    Posts
    193
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Thanks. Your example makes sense, I think I'm getting tripped up on the syntax itself.

    Here's the original question and answer that got me Googling before posting:

    Q. What’s the difference between accessing a class method via -> and via ::?
    A. :: is allowed to access methods that can perform static operations, i.e. those, which do not require object initialization.

    So is :: only used inside of classes to call other public functions? Or is it possible to see it in general script logic, outside of classes? And is the above answer accurate?

  4. #4
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    64 Post(s)
    Tagged
    2 Thread(s)
    Well honestly I'm not an expert on it, to be able to perfectly explain the difference. The only time I use :: is to access a class name explicitly (shouldn't be needed unless you've poorly named your functions to close together), call the parent, or call a static variable within that class, which is the one I commonly use:

    Code PHP:
    MyClass {
      private static $var = 'foo';
     
      public function bar() {
        echo self::$var;
      }
    }

    You might be able to find something a little more useful here:
    http://php.net/manual/en/language.oo...ekudotayim.php

  5. #5
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,073
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sessions View Post
    Thanks. Your example makes sense, I think I'm getting tripped up on the syntax itself.

    Here's the original question and answer that got me Googling before posting:

    Q. What’s the difference between accessing a class method via -> and via ::?
    A. :: is allowed to access methods that can perform static operations, i.e. those, which do not require object initialization.

    So is :: only used inside of classes to call other public functions? Or is it possible to see it in general script logic, outside of classes? And is the above answer accurate?
    To answer one of your questions. I believe you will ONLY see :: related to classes. Either accessing a function/method, a variable, or a constant. I have not seen :: used outside of an OOP approach (but that's not to say it doesn't exist there).

    The :: is just a mechanism to separate the class name from the method/function, variable, and/or constant that is being referenced in that class. Just like -> is used to separate the class reference variable from the method/function or variable of that given reference. Or \ is used to identify Namespace separation: \Namespace\ClassName::MethodName for example.

    Hope that helps clarify a few of your questions.
    Be sure to congratulate Patche on earning July's Member of the Month
    Go ahead and blame me, I still won't lose any sleep over it
    My Blog | My Technical Notes

  6. #6
    SitePoint Enthusiast
    Join Date
    Mar 2010
    Location
    Surrey, UK
    Posts
    84
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sessions View Post
    Here's the original question and answer that got me Googling before posting:

    Q. What’s the difference between accessing a class method via -> and via ::?
    A. :: is allowed to access methods that can perform static operations, i.e. those, which do not require object initialization.

    So is :: only used inside of classes to call other public functions? Or is it possible to see it in general script logic, outside of classes? And is the above answer accurate?
    As I understand it, :: can also be used outside of a class to access static properties and methods without instantiating an object, eg:

    PHP Code:
    class test {
     public static 
    $foo 'Bar';
    }
    echo 
    test::$foo// Bar 
    Martin.

  7. #7
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,023
    Mentioned
    63 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by K. Wolfe View Post
    Not when the child has its own constructor. Only one construct will be called. EDIT: This is the case for any magic method (destruct, etc)
    Parent is used to call the parent method.

    Code php:
     
    class A {
      public function foo {
        echo 'Bah';
      }
    }
     
    class B extends A {
      public function foo {
        parent::foo();
        echo 'Bah!';
      }
    }
     
    $a = new A();
    $a->foo(); // Bah
     
    $b = new B();
    $b->foo(); // Bah Bah


    So with that being said, I'm not sure I'd say that :: is used for static methods as you can call any public function in the parent in the same way I just called the constructor.
    parent::method isn't the same thing as Class::method. Confused? Welcome to PHP.

    Parent is a magic invocation to call the copy of the method in the parent class. For sanity reasons it should only be used by overriding method calls, though nothing in PHP stops you from using it incorrectly you will be very, very sorry if you do (I learned this one from experience. Talk about nightmare to debug code).

    Outside of a child method calling the parent in an override situation, the Paamayim Nekudotayim or :: is only used in a static context as was pointed out previously in the thread.

  8. #8
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    64 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Michael Morris View Post
    Parent is a magic invocation to call the copy of the method in the parent class. For sanity reasons it should only be used by overriding method calls, though nothing in PHP stops you from using it incorrectly you will be very, very sorry if you do (I learned this one from experience. Talk about nightmare to debug code).
    I'm interested if you might have an example of what can go wrong by using this incorrectly?

  9. #9
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,023
    Mentioned
    63 Post(s)
    Tagged
    0 Thread(s)
    A Hell of a lot.

    Code php:
    class A {
      public function foo() { return 1; }
      public function bar() { return 2; }
      public function mar() { return 3; }
    }
     
    class B extends A {
      public function foo() { return parent::foo(); }
      public function bar() { return 10; }
      public function lambda() { return 4; }
    }
     
    class C extends B {
      public function foo() { return parent::mar(); }
    }

    Now, months later, a maintanence programmer goes in and adds a mar method to B. That'll mess up C->foo unexpectedly. As projects grow so to does the complexity of their interactions, and allowing class methods to bypass their sister methods opens up an enormous can of worms and makes code go spaghetti crazy in short order. I know this one particularly because I made that mistake in my first year. Don't do it.

  10. #10
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    64 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Michael Morris View Post
    A Hell of a lot.

    Code php:
    class A {
      public function foo() { return 1; }
      public function bar() { return 2; }
      public function mar() { return 3; }
    }
     
    class B extends A {
      public function foo() { return parent::foo(); }
      public function bar() { return 10; }
      public function lambda() { return 4; }
    }
     
    class C extends B {
      public function foo() { return parent::mar(); }
    }

    Now, months later, a maintanence programmer goes in and adds a mar method to B. That'll mess up C->foo unexpectedly. As projects grow so to does the complexity of their interactions, and allowing class methods to bypass their sister methods opens up an enormous can of worms and makes code go spaghetti crazy in short order. I know this one particularly because I made that mistake in my first year. Don't do it.
    Thank you for the advice

  11. #11
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    That's a very good example. However the same thing can happen even if you're using parent::method() calls "correctly".

    Consider this:


    PHP Code:
    class {
      public function 
    foo() { return 1; }
      public function 
    bar() { return 2; }
      public function 
    mar() { return 3; }
    }
     
    class 
    extends {
      public function 
    bar() { return 10; }
      public function 
    lambda() { return 4; }
    }
     
    class 
    extends {
      public function 
    foo() { return parent::foo(); }


    C::foo() is expecting to call A::foo(). If B::foo() is defined at a later date, the behaviour of C::foo() may change unexpectedly. This may or may not be desirable. The problem the person who is making changes to the class B has, is that they don't know whether or not any classes are extending it and what effect evenly seemingly safe changes may have on subclasses. This is an example of the Fragile base class problem

    If you need complex inheritance trees it's more likely there's a poor separation of concerns. Do the subclasses really use all those inherited behaviours? Probably not! The real answer is to favour composition over inheritance or use interfaces.

  12. #12
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,023
    Mentioned
    63 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TomB View Post
    That's a very good example. However the same thing can happen even if you're using parent::method() calls "correctly".

    Consider this: C::foo() is expecting to call A::foo(). If B::foo() is defined at a later date, the behaviour of C::foo() may change unexpectedly.
    I hardly consider that to be an unexpected change. Also, composition has problems of its own. To me its a matter of right tool for the job, and includes design patterns.

  13. #13
    SitePoint Guru bronze trophy TomB's Avatar
    Join Date
    Oct 2005
    Location
    Milton Keynes, UK
    Posts
    988
    Mentioned
    9 Post(s)
    Tagged
    2 Thread(s)
    It depends what B::foo() is doing, if it alters the state of the object in some manner that C::foo() hasn't anticipated, things in C::foo() will break. This can be avoided to a large extent by only using private variables in both classes, however knock on effects in the change in the implementation can still arise if, for instance, C::foo() is using the return value of parent::foo(). It's a well documented issue: http://en.wikipedia.org/wiki/Fragile_base_class , http://martinfowler.com/bliki/ProtectedData.html , http://zf-william.blogspot.co.uk/200...es-can-be.html

  14. #14
    Community Advisor silver trophybronze trophy
    dresden_phoenix's Avatar
    Join Date
    Jun 2008
    Location
    Madison, WI
    Posts
    2,791
    Mentioned
    34 Post(s)
    Tagged
    2 Thread(s)
    For classes which can be instantiated, you do so by assigning the instance to a variable.

    class thing{}
    $a= new thing();

    Non-static methods/ properties will be changed within the instance alone.

    $a->someProp=$newval;
    so essentially you use -> to reach a non-static method/or property.
    on the other hand static methods and properties, which by their definition cannot be instantiated , you are actually dealing directly with the CLASS itself and not an instance of the class. to reach these you use ::.

    :: can be used out side the class definition, accessing a singleton object, for example. or inside a class, you may have even seen :: parent as a way to access a property at the PARENT LEVEL of a class.

    hope that helps


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
  •