Passing variable to a static function inside subclass - php

I have a class with a variable $x that I want to use in a static function on his subclass.
class people{
protected $x;
function __constructor(){
$this->x = 'cool';
}
}
class person extended people {
function static status() {
'Here I want to use the x variable. I tried $this->x,parent::x..';
}
}

This obviously is not possible, since there is no object referred to inside a static method. That is the whole point of a static method: to be able to use it independent of an instantiated object. But without such object you obviously do not have a property $x...
There are a few alternatives, which one you chose depends on your situation:
you can hand over the value as an explicit argument (so static function status($x)), if you have access to the property of an instantiated object of class people.
you can declare the property as static const inside the class. In that case you obviously do have access from within a static class method. However it obviously is a constant that can be initialized, but which can not change its value over time.
you can design that property outside the class. Yes, this is obvious and changes the point of the class design. But since you already try to use a static method chances are that this method should not depend on any instantiated object at all...
In general one can say that the issue you ran into demonstrates that your class design is not conclusive, does not really make sense in itself in its current state. You will have to redesign the class (or maybe a bigger architecture).
Start by asking yourself a question: "why do you want to make the method status() static at all?"

Related

Are there best practices for working with static members in PHP?

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.

Singleton: How does static variable $instance store data

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.

Private static method vs. static method

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(...);
}

Should I keep variables used only in one class method local or declare them as class properties?

I've been wondering if a class property is instantiated and used only in one class method should it be a class property at all or should it just be a local variable accessible to that class method only?
For example, should I keep a variable only used in one method as a local variable like this:
class myClass
{
public function myMethod()
{
$_myVariableUsedOnlyOnce = "Hello World";
echo $_myVariableUsedOnlyOnce;
}
}
Or should I make the variable a private class property like this:
class myClass
{
private $_myVariableUsedOnlyOnce;
public function myMethod()
{
$this->_myVariableUsedOnlyOnce = "Hello World";
echo $this->_myVariableUsedOnlyOnce;
}
}
Which approach "smells"? What are the benefits to making all method variables class properties other than when I need to print_r() the entire object for debugging purposes?
Thanks
If you need it to have persistence across function calls, a class property would be best so that it moves around as the object does. You also might want to use it for other reasons in future in other functions. However, it does add overhead.
Generally, the class should have some real-world analogue, so if your variable corresponds to something that makes sense e.g. a person class has a $height, then it belongs as a class property. Otherwise, if it's just a part of the internal calculations of a method, then it doesn't really belong attached to the class e.g. a person does not have a $shoelaceIterator or whatever.
I'd argue that a confusing object design would be more of a smell than a potentially small memory overhead (although this depends on how big the variable is).
These local variables are not properties of your object.
They are not defining your object, then they should not be declared as private member.
First I would ask if you really need the variable/property at all if you are only using it once. As for which one "smells", a property is stored in memory for the entire life of the object whereas the variable is only in memory until the method finishes executing.
If you don't need a variable outside the method, it should not be any property of the class. Moreover, accessing local variables is faster.
In a pure design approach I would suggest you to make your choice according to what the attribute/property is supposed to model.
In pure performance terms, having one static attribute is better because memory space won't be allocate with each instance of the class.

Static or not static?

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.

Categories