Calling a PHP method from an Object the proper way [duplicate] - php

This question already has answers here:
PHP: Static and non Static functions and Objects
(5 answers)
Closed 8 years ago.
I am still learning OOP PHP and I keep swapping and changing between the following way of calling methods within an object
$obj = new Model();
$obj->method($param);
against
Model::method($params);
I understand the difference when I within the method as I can use $this in the first example, and I have to use self:: in the second.
Which is the correct way and what are the reasons of using each way
The reason I ask is I cannot find a suitable search term to research. I am currently reading a book on OOP and it will probably tell at some point, but would be nice to know now.

Foo::bar() calls the static class method, while $foo->bar() calls the instance method on an object. These are two completely different things. You do not need an object instance to call Foo::bar(), and in fact you do not have access to instance data when doing so. Foo::bar() is essentially nothing else but a regular function call like bar(), except that the function is attached to a class.
Instance methods act on a specific object instance:
class User {
protected $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public static function hi() {
// no access to $this->name here, since static
// methods are not bound to specific instances
echo 'Hi';
}
}
$dave = new User('Dave');
$mary = new User('Mary');
echo $dave->getName(); // Dave
echo $mary->getName(); // Mary
User::hi(); // Hi
Unless you understand this, you know nothing about OOP.

First example is a non-static call to the method, second a static call.
The first is better if you want to access private variables of your Model, second is better if you use the method like a normal function.
In general you should declare methods of the first type as static (public static function method(){}).

First case is invocation of method on class instance, second case is call of static method.
See http://php.net/manual/en/language.oop5.static.php

There is no "proper" way because both call types serve different purposes.
The first call type is the standard way of handling objects: You initialize a concrete instance of a class. This instance can have its own internal values and each instance can use these values to create a different result when you call the method with the same parameter.
The second call type is called static and operates directly on the class, there is no instance (hence no $this). There are some use cases for it, see this answer for Java, it's the same for PHP.

Related

Difference in Class Calling PHP

With learning fuelPHP, I am introduced on calling classes using scope resolution, or :: in sense. Typically, when we call a method in a class we do this ...
$myclass = new myclass();
$myclass->mymethod();
On fuel, methods are usually called in this manner ...
myclass::mymethod();
I was wondering if there are any difference between the two? Is the scope resolution is something of an update on 5.3 as well ... if not, which one is ideal, or when should I use these.
Thanks.
The scope resolution operator is used to access either class constants like ::const, static variables like ::$var or call static methods like ::method().
See http://php.net/manual/en/language.oop5.static.php
Static methods can be called without having an instance of the class they are defined in. They're defined in that class with the static keyword.
For example, one of CakePHP's static methods is defined like this:
class ClassRegistry {
// ...
public static function &getInstance() {
// ...
}
}
... which you can call like ClassRegistry::getInstance().
Without the static keyword, you'd need an instance of the ClassRegistry class to call that function.
You can read more here, especially about why using static methods in your own code can sometimes be a bad idea: http://kore-nordmann.de/blog/0103_static_considered_harmful.html
I am not sure how would myclass::mymethod(); work, since I use such syntax only when I am calling a STATIC class.
MyClass::DoSomething();
would call a static method named DoSomething()
while
$instance = new MyClass();
$instance->DoSomething();
would call the instance method.
I have not tested it but I believe you will run into an error if you do $instance::DoSomething()
I think the best way to understand why there is a static call and what it does behind the scene is to check this FuelPHP blog's entry: http://fuelphp.com/blog/2011/05/why-did-you-do-that
The obvious difference is that the first solution $myObject->myMethod() it's a dynamic call : you need an instance to execute myMethod().
In the second solution, MyClass::myMethod() is a static call. The class acts as a sort of namespace where a function belong. You don't need an instance for that.

Static keyword usage php

Let say I have a class like the following:
class MyClass {
public function __construct($str) {
// do some stuff including:
$str = self::getIP($str);
}
private static function getIP($str) {
return (bool) ip2long($str) ? $str : gethostbyname($str);
}
// other NON static functions ....
}
In the above scenario what is the advantage/disadvantage of having getIP static vs simply:
private function getIP($str) {
return (bool) ip2long($str) ? $str : gethostbyname($str);
}
and calling $this->getIP(); in the constructor (or any other method)
Context: I would normally do this without the static keyword but I have come across this a couple of times recently. Just wondering if there was any advantage of using static when you are definitely not going to use this.
In this particular case I'm not sure. Usually I use static methods because:
It stores data in a static variable that I want accessible from several objects (sort of like a global)
I don't want to have to create an instance of the object every time I call that method - especially if it's mostly called from outside.
For example, I usually create an App object that has many helper methods. One of these is fetch_db. Every time I want to connect to the database I just call App::fetch_db().
In this specific case there is no advantage or disadvantage. However, a static method can be used by other static methods (perhaps some public static method). Are you sure it's not called by another static method?
Technically any method that has no reliance on $this can be static as long as it conforms to its interface (e.g. if a parent method relies on $this but the child method doesn't, the child method should not be static).

In PHP, is it a problem to call a static class function using the -> dereferencer

I am using PHP 5.2
I have the following code:
class MyClass {
public function __construct() {}
public static function stuff() {
echo 'This is static! <br />';
}
}
$myClass = new MyClass();
MyClass::stuff(); // Reference by class.
$myClass->stuff(); // Reference by instance of class.
The output works in both cases here is the output:
This is static!
This is static!
Is there a problem using the 2nd way of referencing versus the 1st?
Since I am not allowed to have a non-static function with the same signature as the static one above that won't be an issue. I want the function to be static because there is also a speed boost when using static functions.
Am I missing anything or is the only issue here regarding the semantics of how the -> dereference syntax does not indicate this is a static function?
The docs explicitly say it's okay:
A property declared as static can not
be accessed with an instantiated class
object (though a static method can).
However, it's clearer to use ::. I also question the idea that the static method is significantly faster, particularly when no instance fields are used. You should do profiling before you start altering the semantics of your application for performance.

PHP and Python static methods in objects, two different worlds...?

i'm php coder, trying to get into python world, and it's very hard for me.
Biggest enjoy of static methods in php is automatic builder of instance. No need to declare object, if you needed it once, in every file (or with different constructor params , in one line)
<?php
class Foo {
function __constructor__(){
$this->var = 'blah';
}
public static function aStaticMethod() {
return $this->var;
}
}
echo Foo::aStaticMethod();
?>
we can call constructor from static method don't we? and we can access everything in class as it would be simple method ... we can even have STATIC CONSTRUCTOR in php class and call it like so: Object::construct()->myMethod(); (to pass different params every time)
but not in python???? #staticmethod makes method in class a simple function that doesn't see totally anything ??
class socket(object):
def __init__(self):
self.oclass = otherclass()
print 'test' # does this constructor called at all when calling static method??
#staticmethod
def ping():
return self.oclass.send('PING') # i can't access anything!!!
print Anidb.ping()
I can't access anything from that god damned static method, it's like a standalone function or something like this..??
Maybe I'm using the wrong decorator? Maybe there's something like php offers with static methods in python?
1) Please tell why static methods is isolated
2) Please tell me how to make the same behavior like php static methods have.
3) Please tell me alternative practical use of this, if php static methods behavior is a bad thing
P.s. the goal of all this to write totally less code as much as possible.
P.p.s Heavy commenting of sample code is appreciated
Thank you.
static methods in PHP are not as you believe, they can't access to instance members. No $this! with them.
<?php
class Foo {
public static $var = 'foo ';
function __construct(){
echo 'constructing ';
$this->var = 'blah ';
}
public function aMethod() {
return $this->var;
}
public static function aStaticMethod() {
#return $this->$var; -> you can't do that,
# $this can be accessed only in instance methods, not static
return self::$var;
}
}
$foo = new Foo();
echo $foo->aMethod();
echo Foo::aStaticMethod();
?>
Python has three kind of methods in objects static methods are like functions defined ouside classes, the only use to put them in object is to keep them with the class as helper functions. class methods can access only to variables defined in the class (decorator #classmethod). This is more or less what PHP calls static members or methods. The first parameter of such methods sould be cls, and content of class can be accessed through cls. Normal methods must get self as first parameter and are the only ones to be able to access to instance members.
If you want several objects of the same type you definitely need instances, and the other types are not what you are looking for. If you only have one instance of an object, you could use class methods instead (or PHP static methods).
But in most case you should not bother doing that if you don't know why and just stick with instances of objects and normal methods, doing otherwise is premature optimization and your code is likely to bite you later because of the many restrictions you introduce.
You want classmethod instead. That provides the class as the first argument.
EDIT:
class C(object):
foo = 42
#classmethod
def printfoo(cls):
print cls.foo
C.printfoo()
I see you've already accepted another answer, but I'm not sure that it will work with your code. Specifically, the oclass variable is only created for instances of the class, not for the class itself. You could do it like this:
class socket(object):
oclass = otherclass()
#classmethod
def ping(cls):
return cls.oclass.send('PING')
socket.ping()
However, using your existing code and removing all decorators, you could simply instantiate it and use a method on the same line:
socket().ping()

Proper way to access an object

I am working with the Facebook PHP library. It creates an object called $facebook.
In order to access the object within my functions I have to pass the object along with other parameters I want the function to process.
Is there a better way or is passing the object to the function an appropriate practice?
In your function definition: global $facebook;.
Making the functions member functions of the facebook object. (though it won't be logicical for each and every function, it will make sense for quite some possible functions)
Funnily enough, the only thing that will actually change is that your object now becomes a "hidden" parameter instead of an actual one.
Passing the variable is fine - it at least keeps you from defining $facebook as a global.
You could write a class for your functions, and pass the object in the constructor, e.g/
$myFacebook = new MyFacebook($facebook);
class MyFacebook {
private $instance;
public function __construct($facebookInstance) {
$this->instance = $facebookInstance;
}
}

Categories