I am trying to better understand basic concepts in OOP.
What are static and dynamic variables and methods in object-oriented programming?
What is, for instance, the difference between using $this vs. double colon (::)?
$this ($this->a_method())
Advantages: ?.
Disadvantages: ? ... "this" is not self-documenting as in: $this->method_from_an_extended_class().
Double colon (someclass::a_method())
Advantages: ?
Disadvantages: ?
"Static" and "dynamic" aren't the right descriptions for that.
-> indicates a instance functions or instance data, meaning that the function or data has an implicit $this reference. To put it another way you're referring to the function or variable within a particular object.
:: indicates a class function or class variable. This is very similar to a global function or variable in that there is no implicit $this reference. All instance of that class share that function or variable.
"Dynamic" would be a more accurate description for, say, PHP overloading where you can "dynamically" create variables, for example, using the magic methods __get() and __set() (which are called when you try to access a property that can't be found; you can overload these methods to essentially pretend the requested member exists).
Quoting the static page in the PHP manual :
Declaring class properties or methods
as static makes them accessible
without needing an instantiation of
the class. A property declared as
static can not be accessed with an
instantiated class object (though a
static method can).
Also note that when declaring a property as static, there will be only one version of that property for the whole script : static methods/properties "act at the class level rather than at the instance level" (quoting wikipedia).
About advantages / disadvantages, it's a bit hard to answer clearly, as those are just not the same...
The question is : what do you need ?
If you have an object that contains data, and want methods to deal with that data, you'll use dynamic properties and methods.
On the other hand, if you just want to use a class as container for methods that deal with external data (ie, not internal to the class), you'll probably use static methods.
For instance, I am sometimes using static methods as wrappers to libraries that don't export an Oriented-Object API : it allows me to call one class::method, instead of several functions.
Some would say an "advantage" of static methods is that you don't need to instanciate the class to use them -- that is true ; but it also means that you don't get objects, with methods working on them ; well : as I said, using static or not depends on what you need.
Oh, I almost forgot : if you are willing to use unit-testing, you might find out that static methods are not easy to test ; for instance, see Static Methods are Death to Testability.
And static properties (same with singleton and registry design patterns, which rely on static properties/methods) kind of imply "global state", like "global variables" -- which some don't quite like ^^
Related
I need to have method to get something from a database, but I don't understand the difference between static and normal functions in PHP.
Example code
class Item {
public static function getDetail($arg) {
$detail = $this->findProductId($arg);
return $detail;
}
private function findProductId($id) {
//find product_id in database where id = $arg
//return detail of product
}
}
and function outside of a class
function getDetail($arg) {
$detail = findProductId($arg);
return $detail;
}
If I use $item = Item::getDetail(15); and $item = getDetail(15); — they're the same.
What is the difference between static and function outside of a class?
If they are difference, How to use static function and function outside of a class? (I'd appreciate a really simple example.)
What are the performance properties between static and function outside of a class? Which is better?
1) What is difference between static function and normal function
While they are functions, I'd prefer to call them methods of a given class. One is a static method and the other is an instance method.
Static Method: $item = Item::getDetail(15);
Instance Method: $item = getDetail(15);
(refer to FuzzyTree's correct syntax above in the comments, however.)
2) How to use static function and normal function (if you simple exemplify is good)
Static means you do not have to instantiate (declare an object reference). That is, you can simply use the method. So, in your example, while the answer may be the same, the way you called that method/function is different, as you noted above.
In Java, for example, you have the Math class. It does not require instantiation to use, and in fact you cannot that I know of because its constructor is private. You can simply use a method by referencing the class and the method name you wish to use,
Math.pow(d1, d2); //no instantiation needed
in PHP this might be,
MyClass::pow(d1,d2); //no instantiation needed
Java: when to use static methods
3) Ask performance between static function and normal function. Which is better?
Better is a matter of your design. If you have to create an object every time you want to do the power of a number that will create more memoryusage than simply using the class directly. I do not have benchmark proof, but it seem logical since you are not handling the method the same way in memory. I do not think it will matter in real world unless you are doing a lot of complicated actions.
Performance of static methods vs instance methods
might also interest you.
I'm assuming you're asking about the difference between a static method:
class Item {
public static function getDetail($arg){}
}
And a function written outside of a class definition:
function getDetail($arg){}
Static methods should be used over functions written outside of a class for organizational reasons. In an application with many files, having Item::getDetails($arg) will give a hint of where that function is defined. Also, having just a function written outside of a class runs the risk of name collision, if you start writing many functions outside classes.
Especially if you are writing in the OOP style, you should be using static methods over functions outside of class definitions, but I think even in general, using static methods is the better way to go.
The difference about static and non static functions is a big answer and we have to look at Object Oriented Programming (OOP) in general.
OOP in general, as you should know, is about Classes and Object, a class describe and creates objects based of it's description.
If you tell the class to contain the function "A" the object will have a callable function "A" who will have access to the objects parameters.
However if you tell the class to have a static function you tell the class to have a callable function WITHOUT instantiate an object.
Confusing? Can be at first and hard to understand why it's sometimes needed when you take your first OOP steps. Static functions is a good way to share info about classes without the need to make an object.
An analgy would be:
Take the class Car and the object BMW.
the objects functions is about THE BMW, a static functions is about cars in general.
As of performance, it's not about performance at all, it's about design patterns. So performance-wise there is nothing to gain if the functions is static or non static.
1.Entire difference is, you don't get $this supplied inside the static function. If you try to use $this, you'll get a Fatal error:
Static functions are associated with the class, not an instance of the class
and You will get an E_strict warning in the second case.
2.Now static calling of non-static methods works but is deprecated. so use normal function.
3.Technically speaking Static methods and variables are useful when you want to share
information between objects of a class, or want to represent something
that's related to the class itself, not any particular object.
For some reason, PHP allows you to call non-static and static methods
interchangeably,So performance wise or in whatever way you may say just use a normal function.Static is not going to help you at all
The difference between static and non static is that you can access a static method without having an instance of the class.
$item = getDetail(15); shouldn't work because detDetail is a method in a class and not a function.
Performance of Static Methods
There used to be a big penalty when calling a static method - but it's fixed in 5.4.0. See http://www.micro-optimization.com/global-function-vs-static-method
From what the other guy said, if it uses more memory one way versus the other it will absolutely cause a performance difference. If you're using so much memory to the point of going into GC, it can cause queuing of processes due to backup, due to gc and take the whole system down potentially if it's an enterprise system with thousands of concurrent users. It may depend on the scale of the application.
We should never be of the opinion that a change in memory utilization is "minor". It's never minor in big systems...
I am doing a class "Container" to hold all my model/service instances, the class is a singleton.
Consider the following code portion (from a CodeIgniter project):
public function getReviewModel()
{
static $loaded = false;
if (!$loaded)
{
$this->load->model('review_model');
$loaded = true;
}
return $this->review_model;
}
I am wondering if is still ok to use static inside method like this or should I use only class property (I mean about performance and coding standard) ?
In your example, nothing prevents the programmer to instanciate the class more than once (with dire results), so it is rather a confusing bit of code.
Static variables have their uses, be them local to a function or defined at class level.
Especially in PHP scripts, when the output is often a single piece of data that can conveniently be handled as a class defining only static properties and methods.
That would be a true, foolproof singleton class.
Since mistaking a static variable for a dynamic one is a common pitfall, I tend to favor static class variables to avoid the confusion (i.e. the self::$... syntax makes them stand out clearly).
General consensus as far as statics are concerned in PHP is: Avoid, if at all possible. And yes, 99% of the time, it is possible to avoid statics.
Singletons should be avoided 100% of the time. For reasons you can find here and virtually everywhere else on the web. Singletons are like communism: sounds like a nice idea, but when put in to practice, it turns out there's one or two things you didn't anticipate.
A Singletons' main purpouse is to retain state, but PHP itself is stateless, so come the next request, the singleton needs to be re-initialized anyway.
If I write getters like yours, I tend to create them in a lazy-load kind of way:
class Example
{
private $reviewModel = null;//create property
public function getReviewModel()
{
if ($this->reviewModel === null)
{//load once the method is called, the first time
$this->reviewModel = $this->load->model('review_model');
}
return $this->reviewModel;
}
}
This basically does the same thing, without using statics. Because I'm using a property, I still retain the instance, so if the getReviewModel method is called again, the load->model call is skipped, just as it would be using a static.
However, since you're asking about performance as well as coding standards: statics are marginally slower than instance properties: Each instance has a HashTable containing for its properties, and a pointer to its definition. Statics reside in the latter, because they are shared by all instances, therefore a static property requires extra lookup work:
instance -> HashTable -> property
instance -> definition -> HashTable -> property
This isn't the full story, check answer + links here, but basically: the route to a static propery is longer.
As for coding standards: They exist, though still unofficial, most major players subscribe to them, and so should you: PHP-FIG
Things like $this->_protectedProperty; don't comply with the PSR-2 standard, for example, which states, quite unequivocally:
Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.
i am doing some oop in php and when i just wanted to know if its good to do this?
when i use $this->functionName(), it works fine and i even tried with self:: and static:: and they work as i expected:
self:: will use the parent method implementation and static will use the last implementation of the method if overridden (late static binding). but the problem is that it is being used on a non static function. is this good? does it has any drawbacks?? why shouldn't i use it?
See this answer for detailed description.
In general, it is possible to do the things you describe and PHP allows it. But remember that people are used to polymorphism and method overridding so if your base class allows to override some method and then, uses a self to call it, it will be weird that I can't change the class behavior, although it exposes it in its API as public or protected method.
IMO, it violates the Principle of least astonishment, referenced in Uncle Ben's Clean Code book.
Also, there are some differences between static and $this bindings, because static will always try to reference the element in the narrower, not always appropriate scope. This behavior is presented in this example, and is explained in the note above, which I reference here:
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope, using static:: may give different results. Another difference is that static:: can only refer to static properties.
Thus, although it is possible to use static in some places where $this is appropriate, the static keywords was introduced to use access static methods and fields and using it for another purposes should be considered confusing.
Starting a new PHP project and deciding that after a few years of PHP development, I'm thinking I should really start using PHP classes. I'm used to classes in the C++ world, so there's a few things I'm not quite sure about when porting this knowledge over to PHP.
In C++, you can automatically access any class variables without a prefix, in PHP, it appears that you need to prefix all such accesses (variables and function) with this->. I know what this is (or at least I think so, a pointer to the current class instance), but I'm not sure whether its required or preferred, or if there is any alternatives. My class will be using other functions within the same class (ie, itself) fairly heavily, so having to type this-> every time is going to get time consuming quite quickly.
The classes themselves are likely to be singletons, so I'm not sure whether to actually use a class, or just prefix the functions with an identifier.
It is required that you reference the object to which the member belongs in order to access the member.
Every method call or property access is prefixed with $variable-> - $this is a magic variable that refers to the current object instance. Its use is not optional.
This is (amongst other reasons) because not every function in PHP is a method, there are also global functions. If you reference a function without associating it with an object, it is assumed to be a global function.
As a side note, you should avoid the use of singletons in PHP - there is no performance/memory gain to be found from using them because each concurrently executing script is garden-walled into its own memory space.
The "pointer" (->) != C++ pointer.
$this means the current class and instance. All variables are accessed by using $this->variable; or $this->function();.
Static variables, and functions can be accessed using self::$variable or self::function()
Outside the class instance, you must indicate the class instance: $foo->variable; or $foo->function();
As far as I know, there is no way to access public/private/static/constant variables inside the class without using $this-> or self::
In reference to using an object of functions... up to you. Are you planning on expanding the code later to add more functions? Are all the functions somewhat related? If they are singleton functions, there is no harm in just writing a function instead of a class. It really just depends on what you are trying to accomplish.
Yes, you do have to use $this when accessing class method's or variables.
You need to remember that PHP doesn't require that variables be declared, so image the following situation:
<?
class A {
public $a = 'Hello World!';
function hello() {
$a = 'hello';
echo $a;
}
}
$object = new A();
echo $object->hello();
$a would be local scope and $this->a would be the class variable.
I understand that singleton enforces a class to be created once. But why should an instance exists if I dont access it directly? Why is that pattern for, isn't it easier just use full static class with static methods and datas?
Some time ago I was asked what is the benefit of using singleton over of using static class, here is my response:
Static class leads to invisible dependencies - that is a class that use the static class, but that class is not part of the class' interface.
Singleton also allows this, because it provides global access point, but it's instance can be passed as an argument to the class / method
If there is any initialization, as the connect method, it should be called from each class method, which leads to duplicated code. On the other hand, the initialization of the singleton is performed in the constructor, which is called just once from the getInstance()
method
Singleton can be easily refactored in a factory, adding a parameter to the getInstance() method and returning different instances
Static class is harder to extend, because if we want to override a method, that is called within the class with self::methodName(), we should override the caller as well (although in PHP 5.3 there is a late static binding, which can be used to avoid those problems)
If you need to add an argument, needed for all of the methods, you can easily do this in singleton because of the single access point, but you can't in a static class
The major difference between a static class and a singleton is that with the static class, you need to hardcode the class name in your code everywhere you use it:
StaticClass::doSomething();
StaticClass::doSomethingElse();
While with a singleton, you only need to hardcode the class name once:
$singleton = SingletonClass::getInstance();
// other code does not need to know where $singleton came from,
// or even that class SingletonClass exists at all:
$singleton->doSomething();
$singleton->doSomethingElse();
Another important difference is that singleton classes can be part of hierarchies and can implement interfaces.
This does not mean that Singleton (the pattern) is good and should be used liberally. But it is better than using a static class directly.
[Edit]: The stuff I have written below is actually plain wrong. Just got alerted to this answer from years ago by a downvote. They do serve a purpose ;)
A singleton exists once, but it can have internal state - as opposed to a static class. You might e.g. use it as a global registry, which you can't do with a static class.
[Edit:] What comes next, though, is as true as it ever was.
It's debatable whether singletons are a good idea, though. They introduce global state into an application, which can make it very hard to test. But that is another discussion.