Calling a parent classes method vs. calling a static method - php

To call a parent class (it has been instantiated) method I use
parent_class::method(); //tested it works
to call a method with in the instantiated class I am in I use
$this->method(); //tested it works
However if I call a static method from any class I use
parent_class::static_method(); //tested it works
I guess this makes since b.c. there is only one copy of a method per class, whether it is instantiated or not?
Can some one validate or provide insight to this. I just want to verify that the call method is the same for both static methods from any class and calls to a parent classes method.
Seems a bit strange.

The syntax is correct. Not exactly sure what your question is. If you wanted to call a static method defined in the child from within the child, you could use self::static_method() or $this->static_method(). Either would work.

Related

Statically calling methods causes not being able to reference $this within called class?

I don't usually call methods statically but since working with the Yii framework I have started to more.
I'm experiencing an issue which I haven't come across before, I am doing this from a SignupForm class:
$send = mail::sendMail($email_data);
..inside the sendMail method which is obviously inside the mail class I have this line:
$email_data['message'] = $this->sanitizeMsg($email_data['message']);
The sanitizeMsg is a method of the mail class and hence that's why I thought referencing it via $this should work.
However I am getting the error:
Calling unknown method: app\models\SignupForm::sanitizeMsg()
Why is it looking for it in the SignupForm class? Does this have something to do with me calling it statically? Do I need to revert to using self:: instead or should I stop calling it statically?
Using $this only works for member methods. I.e. you can only use it from an instance of the class and I believe also only to access instance members.
To access static members, you should use self::.
Not familiar with the Yii framework, but what someone does is to use static methods as factory methods. Maybe that's what you're confused by. The static method then creates a new instance of itself and returns it, and inside that instance you can of course use $this, but not in the static method. Static methods have no $this.

Can PHP class contain method not listed by function `get_class_methods` ? If so, how? If not, why does it appear to?

I am digging into some Magento code.
I'm looking at class Mage_Catalog_Model_Session
There is code in class Mage_Catalog_Block_Product_List_Toolbar extends Mage_Core_Block_Template function getCurrentOrder like this:
Mage::getSingleton('catalog/session')->getSortOrder();
Now, Mage::getSingleton('catalog/session') returns an object of type Mage_Catalog_Model_Session
So I would think that getSortOrder() is a method of that class, although the method seems like it would go with this toolbar class and not that session class.
This line should give me the list of methods of the class:
print_r(get_class_methods(get_class($_test)));
And it does seem to, but getSortOrder() is not listed.
So, which class is getSortOrder() a member of and how is it that it either A.) appears to be a member of a class it's not a member of, or B.) is a member of that class but does not appear in the get_class_methods() result set?
Sounds like getSortOrder() is an overloaded method. See here for more info on overloading. Taken from the link:
Overloading in PHP provides means to dynamically "create" properties and methods.
get_class_methods() wouldn't display overloaded methods because they are created on the spot when called (And therefore there's no way to know about them.) A lot of frameworks use overloading for getters.
Btw, see this answer for an example of how overloading a getter would be achieved.

oop php constructor access modifier, which one to use?

I've just started experimenting with OO PHP, but there's one basic principle I don't really uderstand that well, and don't find too much info on it.
When creating a __construct() method, why would you want it to be public, when it's specifically a constructor for that class?
When would you want to call a constructor outside the class?
To me, it seems using a protected constructor is good practice, right?
I know this is basic OO stuff, but I don't find any info directly on it, specifically for constructors.
The __construct (not "__constructor") method is the one called when you do new MyClass(), i.e. when you instantiate the class. The constructor needs to be public, unless you only want to instantiate the class from within itself. If the latter, you need at least one other public static method you can call in which the class will instantiate itself, otherwise you're unable to create any instance of it.
Whenever you create a new instance of a class, the constructor is called. If the constructor is not public, no other code can create an instance of that class.
Hence, if you want to create instances of the class, make the constructor public.
A constructor is always only part the class it is defined in, I don't understand what you mean by "when it's specifically a constructor for that class".
To clarify:
The only way to invoke the constructor is with new Class(). There is no other way to invoke it. __construct is a magic method and there is no way to explicitly call a magic method.

Can I recursively call a method from child to parent, using an inherited method?

There are lots of examples of child classes calling overridden parent methods, most commonly parent::__construct(). In these cases, however, you are actually calling the parent from a concrete method in the child itself.
Is there a way that I can recursively call a method from the child to the first ancestor, using an inherited method?
If I use parent::methodName() in my abstract parent class it causes a fatal error saying 'Cannot access parent:: when current class scope has no parent'. Presumably this is because 'parent' is being evaluated relative to the abstract class itself, not the current class context.
Thanks...
I'm not quite sure what you're trying to do, but:
The parent keyword is evaluated relative to the class it occurs in. If the class that you use the parent keyword in doesn't have a parent, it obviously won't work.
If you want a child to use a parent's method, simply don't override that method in the child. It does not make sense to define a method in a parent that forces the child to call the parent's method, when all you need to do is simply not override the method in the child.
You can force the parent's method to be "the last word" by making the method final, the child won't be able to override it.
A child cannot call a "grandparent's" method, since the child does not know, or at least has no guarantee, that its parent has a parent in turn.
In practical terms that means:
If you are writing a class that does not extend another class, it doesn't make sense to use parent anywhere in it.
If you are extending a class and are not overriding a method, the parent's method will be used automatically (it is inherited).
If you are extending a class and are overriding a method, you may call the parent's method from that overridden method, which in turn may call its parent's method etc.
Maybe something like this? (untested)
foreach (get_class_parents($this) as $className) {
(new ReflectionMethod($className, __METHOD__))->invoke($this, $args...);
}
I hate when I see this kinda junk in code.

Get the observability of class methods in PHP

The function get_classs_methods returns all methods of a class.
But, is there a function or technique to get the observability of these methods?
I want to list only the public methods.
The return value from get_class_methods depends on the scope you're calling it from; if you're calling it from outside the class, you'll only get the methods that are visible from the current scope. Calling it from a method inside the class will give you all the available methods from the class.
If you want more information or to query the class in a more detailed manner, you probably want to look at using reflection and the getMethods method.

Categories