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).
Related
Assuming that I have to create a class that takes some text do some processing and return it ... with no dependency and it's a stateless class..
I'd like to know would be better to create a stateless class without constructor or just create a static class (in php it's just Static methods)
class like this:
class ClassName
{
public function processText($text)
{
// Some code
$text = $this->moreProcessing($text);
return $text;
}
protected function moreProcessing($text)
{
return $text;
}
}
and this:
class ClassName
{
public static function processText($text)
{
// Some code
$text = static::moreProcessing($text);
return $text;
}
protected static function moreProcessing($text)
{
return $text;
}
}
I Know that dependency injection into the class where these classes are used would be better but assume that I just won't have dependency injection..
My question is mainly would it be better to create static class for the simple example above?
Practically you will see no difference whatsoever.
It's only in the syntax, and the ability of a constructor to perform stuff automatically, though you still have to create instances to invoke the constructor, which in this case is not far off calling some equivalent static member function.
However, non-static member functions are supposed to affect internal state so, if you have no state, static member functions seem more conventional, and will be slightly less surprising to users of the class.
The best approach, though, is to stick your functions in a namespace. Classes are for data and functions operating on that data... even static ones.
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(...);
}
Why in PHP you can access static method via instance of some class but not only via type name?
UPDATE: I'm .net developer but i work with php developers too. Recently i've found this moment about static methods called from instance and can't understand why it can be usefull.
EXAMPLE:
class Foo
{
public static Bar()
{
}
}
We can accept method like this:
var $foo = new Foo();
$foo.Bar(); // ??????
In PHP
the class is instantiated using the new keyword for example;
$MyClass = new MyClass();
and the static method or properties can be accessed by using either scope resolution operator or object reference operator. For example, if the class MyClass contains the static method Foo() then you can access it by either way.
$MyClass->Foo();
Or
MyClass::Foo()
The only rule is that static methods or properties are out of object context. For example, you cannot use $this inside of a static method.
Class Do {
static public function test() {
return 0;
}
}
use like this :
echo Do::test();
Why in PHP you can access static method via instance of some class but not only via type name?
Unlike what you are probably used to with .NET, PHP has dynamic types. Consider:
class Foo
{
static public function staticMethod() { }
}
class Bar
{
static public function staticMethod() { }
}
function doSomething($obj)
{
// What type is $obj? We don't care.
$obj->staticMethod();
}
doSomething(new Foo());
doSomething(new Bar());
So by allowing access to static methods via the object instance, you can more easily call a static function of the same name across different types.
Now I don't know if there is a good reason why accessing the static method via -> is allowed. PHP (5.3?) also supports:
$obj::staticMethod();
which is perhaps less confusing. When using ::, it must be a static function to avoid warnings (unlike ->, which permits either).
In PHP, while you're allowed to access the static method by referencing an instance of the class, you don't necessarily need to do so.
For example, here is a class with a static function:
class MyClass{
public static function MyFunction($param){
$mynumber=param*2;
return $mynumber;
}
You can access the static method just by the type name like this, but in this case you have to use the double colon (::), instead of "->".
$result= MyClass::MyFunction(2);
(Please note you can also access the static method via an instance of the class as well using "-->"). For more information: http://php.net/manual/en/language.oop5.static.php
In PHP 7 it seems to be absolutely necessary for you to be able to do $this->staticFunction(). Because, if this code is written within an abstract class and staticFunction() is also abstract in your abstract class, $this-> and self:: deliver different results!
When executing $this->staticFunction() from a (non-abstract) child of the abstract class, you end up in child::staticFunction(). All is well.
However, executing self::staticFunction() from a (non-abstract) child of the abstract class, you end up in parent::staticFunction(), which is abstract, and thusly throws an exception.
I guess this is just another example of badly designed PHP.
Or myself needing more coffee...
I want a function in my class to perform a simple task, such as:
function hello($name)
{
return 'hello '.$name;
}
i.e. Not necessarily static (though I suppose it might be), but not related to the object (no reference to $this necessary).
Do I use a static function? ie.
static function hello($name){return 'hello '.$name;}
and call it using $string = ClassName::hello('Alex');
or is there a better way?
Thanks!
Class methods which don't require an instance of object to be called and which should be able to be executed without an instance of object should be declared as static.
Static methods don't have $this and should be called as ClassName::methodName().
Static methods can access static member variables of their class.
A static function should be a static function.
If it is stateless, than use static.
You may also encapsulate group of similar functions in a class *Utils. so these functions will be like helpers
class StringUtils{
function splitBy($delimeter,$val){....}
}
than you call it StringUtils::splitBy(..)
meaning if it is not related to the object, seperate it.
You can take with you the utils folder to every project and reuse it on and on and on....
what for this function in this class? if it not belong to it - just move somewhere else
... if belongs then the question is in possibility to call it without creating object
If there is no reference to $this (or possible future reference to $this) make it static.
I say this because sometimes I go with:
static function hello( $name ) { return 'hello '.$name; }
and after a few months of developing and expanding the program I feel the need to reference $this, like:
function hello( $name ) { return $this->helloInLanguage[ $this->language ].' '.$name; };
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()