I understand that static means that an object doesn't need to be instantiated for that property/method to be available. I also understand how this applies to private properties and methods and public methods. What I'm trying to understand is what static private function gains you. For example:
class Beer {
static private $beertype = "IPA";
private function getBeerType() {
return self::$beertype;
}
static public function BeerInfo() {
return self::getBeerType();
}
}
print Beer::BeerInfo() . "\n";
The private method getBeerType() executes just fine without an instantiated object as long as it's being called from a static public method. If a static public method has access to all private methods (static and non-static), what's the benefit of declaring a method static private?
With strict error reporting turned on, I do get the warning that I should make getBeerType() static, although it still lets me run the code. And I did a little research and it seems like other languages (Java) will force you to declare a private method as static when called by a static public method. Looks like PHP lets you get away with this. Is there a way to force it to throw an error and not execute?
A static private method provides a way to hide static code from outside the class. This can be useful if several different methods (static or not) need to use it, i.e. code-reuse.
Static methods and static variables, sometimes called class methods and class variables, are a way of putting code and data into a kind of namespace. You could also think of class variables as variables attached to the class itself, of which there is (by definition) exactly one, instead of to instances of that class, of which there may be zero, one or many. Class methods and class variables can be useful in working with attributes that not just remain same in all instances, but actually be the same.
An example of a class variable is a database handler in an ORM entity object. All instances are their own object, but they all need access to the same database handler for loading and saving themselves.
Private versus public is a completely separate quality, which is I suspect what you're stumbling over. A private method cannot be called and private variables cannot be accessed from code outside the class. Private methods are usually used to implement "internal" logic on the object that must not be accessible from outside the object. This restriction can be needed by instance methods as well as class methods.
An example of a private class method could be in a factory method. There might be three factory calls for creating an object which might differ in parameters being supplied. Yet the bulk of the operation is the same. So it goes into a private static method that the non-private factory methods call.
I understand static means that an object doesn't need to be instantiated for that property/method to be available.
Everything static just exists. Globally.
I also understand how this applies to public properties and methods and public methods
Are you sure you have understood that it creates a global variable and a standard global function?
What I'm trying to understand is what static private function gains you.
The private is just a specifier of visibilityDocs. So that gains you visibility control.
Is it useful? Depends on the use-case.
it's for preventing OTHERS from consuming it.
Example, you have a Logger static object, then you have two public static methods LogOk and LogError and both benefeit from an "internal" method Log but you don't want the consumers of that class to be able to call Log directly.
You can call Logger::LogOk( "All right." ); but you cannot call Logger::Log( "abc" ); if Log is private.
You you can internally always make use of it from the same class.
Although the code works, it throws a Strict standards error:
Strict standards: Non-static method Beer::getBeerType() should not be
called statically
So, here you get the use of the private static.
Simply said you can declare a private static function if you have a repeated operation in some of the public static functions in the class.
Naturally if you are an inexperienced programmer or new to the OOP putting limitations to your code seem strange. But strict declarations like this will make your code cleaner and easier to maintain.
In large projects and complex classes you can appreciate to know exactly what to expect from a function and exactly how you can use it.
Here is a good read: Single responsibility principle and
God Object
Here's the rule and the best answer,
static methods cannot access non-static variables and methods, since these require an instance of the class. Don't worry about the warning, the rule is set and it will break your code in the future once it's fully enforced. That is why
static public function BeerInfo() {
return self::getBeerType()
is wrong,
you have to declare getBeerType as static.
In your example, you can simplify this by doing the following.
static private $beertype = "IPA";
static public function BeerInfo() {
return self::$beertype;
}
'static' purely means resident in a single region of memory. If you are memory conscious, static implementations are a good strategy.
When you use a public static function, chances are, most of the time, that you don't want to deal with an instance of that class, but want to re-use pre-existing functionality from within that class. Leveraging private static functions is the way to do that without instances.
However, you could have a public static function which accepts an argument which is an instance of said class, e.g.
static public function doSomething(Beer &$ref) {
$ref->instanceLevelFunction(...);
}
Related
I have a class like this.
<?php
namespace test;
class Test
{
public static function static1(){}
public static function static1(){}
...
}
And autoload use psr-4.
when is the static function load in memory ?
load with out use(include) ? I don't think it will do this.
use test/Test(include php file) ?
call Test.static1(); ?
In my option: static function is easy to use without new(of course, they don't have private data), but i afraid it's load more memory and make performance degradation.
Disclaimer: What you're asking/saying doesn't make a lot of sense to me. You need to research and correct your terminology and learn more about static methods or properties. I believe when you're referring to private data, you're actually referring to "instance properties".
Static methods would use no more memory than an instance method, not sure where you came up with that idea. The code of the class is loaded into memory by the compiler when it is included. Except for their definition (compiled code), methods or functions do not use memory. The amount of memory consumed when a method is run depends entirely on what the method is doing.
Methods have no private properties, classes have private properties, and a static method can access private properties.
If your goal is to have a property persist across multiple instances, you can access a static property from within an instance method:
public function getData() {
// self::$data or static::$data represents a static property $data
return self::$data;
}
If your goal is to only have one instance of a class exist at any time, you can look up the Singleton pattern.
If anything, static methods and properties can be more efficient than instance counterparts. One of the problems with static methods is they are less testable, you can do your own research on why you may want to avoid static methods, but performance is not likely one of the reasons.
I am a junior PHP programmer. I still have a lot to learn. That's why I ask this question. In a class you have a public function which you can call it from outside that class. Sometimes you have a private function which you can call several times in that class where the private function resides, for reusable purpose. I like to set the private function to static and I call that function with:
self::privateFunctionName();
By using self it reminds me that this private function resides in that class. if I use $this->privateFunctionName() for non-static function, it could be in the superclass/base class or in that subclass itself. That is why I like to use static private function. In a professional point of view, is it a good idea to use static private function instead of non-static? Is there any disadvantage that a professional programmer like you prefers to avoid the static function?
Only using self::... must not mean the method is static. parent:: and self:: work as well for non-static methods. You can find this in the PHP manual - Scope Resolution Operator (::) and I add some exemplary code excerpt at the end of the answer.
You perhaps might want to read through all answers of this earlier question:
When to use self over $this?
In total you will get there more details then my short description in this answer.
You might have been confused by the scope-resolution-operator :: which is used by those. I had a similar understanding problem grasping that.
However, do not just choose to use static methods for such a limited reason. Those static class methods should only be used in very limited and narrowed situations. As a rule of thumb:
"Do not use static class methods."
If you like to start with object oriented programming, just use normal object methods.
Here is an excerpt from existing code that shows that self:: as well as parent:: are used with standard (non-static) methods:
<?php
...
/**
* Class XMLElementIterator
*
* Iterate over XMLReader element nodes
*/
class XMLElementIterator extends XMLReaderIterator
{
private $index;
private $name;
private $didRewind;
/**
* #param XMLReader $reader
* #param null|string $name element name, leave empty or use '*' for all elements
*/
public function __construct(XMLReader $reader, $name = null)
{
parent::__construct($reader);
$this->setName($name);
}
/**
* #return void
*/
public function rewind()
{
parent::rewind();
$this->ensureCurrentElementState();
$this->didRewind = true;
$this->index = 0;
}
/**
* #return XMLReaderNode|null
*/
public function current()
{
$this->didRewind || self::rewind();
$this->ensureCurrentElementState();
return self::valid() ? new XMLReaderNode($this->reader) : null;
}
...
self:: does not in fact mean that the method is part of the same class, it may as well have been inherited from a parent class!
You should not use the semantics of static method calls to differentiate "internal" and "external" methods. There's no real point to it anyway, and you're just abusing language features for something they weren't meant for. Maybe let that be a primary lesson: don't try to invent clever new ways of using language features. Just don't.
You should view methods as small, self contained black boxes. You don't need to know and don't want to know what they do. All you know is that when you call method foo with parameter $bar, x will happen or it will return y. You don't care how this happens, just that it does because that's what the method is supposed to do.
As such, static and non-static methods convey a different use with different limitations. static methods are supposed to be called when you don't have an object, for example as alternative constructor methods (e.g. DateTime::createFromFormat).
Further, restricting a method to being static means it has no access to object instance data, which may limit you in the future. As your project evolves, you may find that your method now needs to take into account some additional data from the object to do its job. If you declared it as non-static from the beginning, all it takes is a little modification to the method itself; to the outside world it still does its job the same way (input → output). However, if you declared it as static and suddenly find yourself needing to make it non-static, you have to change a lot more code than just that one method.
Bottom line: if your method is not supposed to be exposed publicly because it's nobody's business to call it except for your own class, make it private. If the method needs to be static because it must work without object context, make it static. If it fulfils both requirements, make it private static. Otherwise, don't.
Well basically a "private static" function is a construct which is totally nonsense because it cannot be called from the outside.
There is no real difference between $this-> and using self:: expect the fact that it can be called from the outside without a object and its the same amount of work for the CPU to call the function, no matter in what namespace/class this function is located.
However the fact that a private function can only be called within the same class you always have an object and the "static" modifier is somewhat superflous here because it makes no difference.
In this cases I always like to say: do what you like its just a matter of your personal style but dont switch arround, keep it that way to develop and use the standard you feel comfortable with.
In some cases there is just "another" way and a "professional" way does not exist at all.
The trend often makes the one or the other method to become popular over time.
PHP allows use of static member functions and variables, since 5.3 including late static bindings:
class StaticClass {
public static $staticVar;
...
}
$o = new StaticClass();
Currently, there are various options to access those static members:
$o->staticVar; // as instance variable/ function
$o::staticVar; // as class variable/ function
Other options exist for accessing members from inside the class:
self::$staticVar; // explicitly showing static usage of variable/ function
static::$staticVar; // allowing late static binding
Restructuring some existing classes that make some use of static members I've asked myself if there are best practices for working with static members in PHP?
Well, obviously, they all do different things.
$o->staticVar
This is invalid, since you cannot/should not access static properties with the instance property syntax.
StaticClass::$staticVar
This very plainly accesses a specific static variable on a very specific class.
$o::$staticVar
This accesses the static variable on the class that $o is an instance of. It's mostly used as a shorthand for the previous method and is equivalent in all respects. Obviously though, which class is used exactly depends on what class $o is an instance of.
self::$staticVar
This can be used only inside a class, and will always refer to the class that it's written in. It's a good idea to use this inside a class instead of StaticClass::$staticVar if the class refers to itself, since you don't need to worry about anything if you change the class name later. E.g.:
class Foo {
protected static $bar = 42;
public function baz() {
self::$bar; // good
Foo::$bar // the same, but should be avoided because it repeats the class name
}
}
static::$staticVar
This can also only be used inside a class and is basically the same as self above, but resolves with late static binding and may hence refer to a child class.
What the "best practice" is is debatable. I'd say you should always be as specific as necessary, but no more. $o::$staticVar and static::$staticVar both allow the class to vary through child classes, while self::$staticVar and StaticClass::$staticVar do not. Following the open/closed principle, it's a good idea to use the former, more variable method to allow for extensions.
Properties, both static and non-static, should also not be public to not break encapsulation.
Also see How Not To Kill Your Testability Using Statics.
First of all, don't use $this->staticVar. I am unsure when this changed (I believe PHP 5.4), but in recent versions it is no longer possible to retrieve static variables this way.
As for using late static binding, don't use it if you don't need it. The reason to use it would be if you plan to use inheritance and expect to change the value of the static variable in a derived class.
I've got a comprehension question:
The singleton design pattern uses a static function call like Singleton::getInstance() and in this function it uses static variables like self::$_instance.
According to the definition, static functions and variables are independent of any concrete instances and are evoked each time just for the purpose of it's particular call. How then is it possible, that any value can be stored in such quasi-abstract and each-time-new-created 'objects'?
Hope you understood my question.
Static property is similar to global variable. Difference only of its visibilities. Global variable can changed by everybody as public static property, but private or protected static property has less visibility.
Imaginate that class is actually an object which created when defined and could exists only in one instance. Static properties and methods are properties and methods of this "object". That is why many people does not understand differnce between regular class with static members and singleton.
Visibility, static, singleton pattern
The Singleton design (anti-)pattern allows to make sure there is at most one instance created.
The property is static, therefore it can be accessed from a static method. However the underlying object is a real, live instance. From a static method, you cannot use $this, but you can refer to any already-instanciated object, which self::$_instance happens to be)
class SingletonClass {
private static $_instance;
private $_someProperty;
public static function getSomeProperty() {
return self::$_instance->_someProperty; // allowed, self::$_instance is static, but a real object nonetheless
}
}
Three things make the class Singleton or else it will a normal class.
Static variable
Static method
Private constructor
Probably you have created a class for counter functionality, Singleton is like the same.
What is better to use in this context, static methods, or simple public method and call them always like this: $request = new Request();
if($request->isPostRequest()){ do smth }
ofcourse its easier to use static, but what is more properly to use?
Class Request {
public static function isSecureConnection() {}
public static function isPostRequest() {}
public static function isAjaxRequest() {}
...etc
}
If each Request is a genuine entity, then it would be better to use non-static members. But if it's not and methods are used in general, like Sinus function in math, then they'd be better to be static.
Overall it'd be better to declare static functions in a class that is just consisted of functions and no data members.
You should always create a class like if it was to be used on a non-static environment.
Then you can use that as a Singleton with lazy-instantiation. Or even as a Static class instantiation. Or even as a Standalone instance object. You decide later what to do with it.
If you start by declaring all members as static you are basically just covering a bunch of Global variables inside a glorified namespace known as a Class. You also will statically allocate the memory used by that class even if you don't call it or use it in your code.
So, just write as a Class, then you decide what to do with it. Static/Non-Static. Singleton/Instance. Factory Pattern or not. Memory Allocator X/DLL bound or whatnot.
The only exception is static members used for book-keeping in behalf of the Object Instances; things like reference counting, caches and things like that. That is the good thing about static/non-static, you can mix and match for some clever behaviors.
What if later you wanted another Request? Or what would happen if you can create more than one because you are in a multithreaded environment? Things will get really strange once you go that route with statics.
It looks like you are handling one particular request.
Now this insinuates you should make it a singleton, and/or use static functions.
Reason:
There is only one request, all the state is defined by the environment delivered to the process. The class methods are just helper functions, and you want to be able to use them without class instance.
On the other hand, you would rarely use static functions with classes that represent one of many, for example one user of many, one question of many.
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).
Example:
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
See the reference of Static Keyword from php.net.
If you can, use static methods as a default. static methods run quicker than their non-static counterparts.