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.
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'm wanting to gauge people's opinions on the use of static classes instead of namespaces. I come from a C++ background and am quite fond of its syntax and how it lets you structure code. I recently decided I needed to group my code into logical units instead of just files. For instance I prefer calls like User::login to user_login. So, I did a bit of googling and was relieved to find that PHP has namespaces. My relief didn't last long though, I really don't like the syntax; it adds more mess to my function calls. So, at the moment I'm using static classes to simulate namespaces. Are there any downsides to this?
I found a similar question at PHP Namespaces vs Classes with static functions but there wasn't a whole lot of discussion.
Also, is there a way to avoid the following situation:
class Test {
public static void myFunc() {
Test::myOtherFunc();
}
public static void myOtherFunc() {
}
}
I assumed it would be ok to call functions in the same class without specifying the name, but apparently not. Are there any workarounds for that (for instance in C++ there the using keyword).
Coincidentally I've actually been moving into the exact opposite direction:
Use namespaces to organize domain classes (or functions)
Use dependency injection where I would have otherwise used static classes
The thing with static classes to simulate namespaces is that you can't organize them across multiple files, everything has to be defined inside one file; this may well be up to personal taste.
The other thing about static classes is that you start without any state and slowly some state management creeps in and you end up with some weird lock-in dependency. State should be reserved for instances. Currently my only notable static class is the site-wide configuration.
Lastly, self referencing in static classes is explicit, whereas in namespaces it works exactly like C++ would: you specify the function name and it gets looked up within the namespace first.
If you look from the standpoint of code structure, there is no difference between static class method and namespaced function. They both end up in global scope. Only difference is, that, with static class method, you are trying to fake OOP.
Therefor it is better to use namespaced functions, if what you really need are standalone/utility functions. Namespaces are for grouping thing (both function and classes).
As for you User::login() example, it would be a bad practices. Instead you should have a real object, which is able to capable of containing state.
$mapper = new UserMapper;
$user = new User;
$user->setNickname( $name );
$mapper->fetch( $user );
if ( $user->hasPassword( $password ) )
{
$user->setLastLogin( time() );
}
else
{
// log the access attempt
// set error state
}
$mapper->save( $user );
The bottom line is this: if you are using static structures ( functions or methods ), it is not OOP. You are just faking it. Instead you should use real OOP, with dependency injection.
If your code uses static methods and variables all over the place, it causes tight coupling between classes, add global state and makes harder to maintain and test your codebase. And this is not PHP specific.
Writing a PHP app and have several classes that only have static methods (no need for instance methods). An example of one is NumericValidator, which has methods like checkInteger($toCheck) which checks to make sure the argument you pass it is of type int, and checkGreaterThan($lOperand, $rOperand), which makes sure that the left operand is greater than the right operand, etc.
I know I could just throw each of these methods into a PHP file without putting them inside of a class, but I want to take an OOP approach here in case the API evolves to require instantiating NumericValidator.
But it does beg the question: how is a class with 100% static methods any different than have a class implement a singleton design pattern, where every reference used throughout the code base invokes the same instance?
For example, here is what my code looks like now:
public function doSomething($p_iNum)
{
if(!NumericValidator::checkInteger($p_iNum))
// throw IllegalArgumentException
// ...
}
But I could turn all of NumericValidator's static methods into non-static instance methods, forcing the programmer to instantiate it, and then implement a singleton design pattern so you can only ever reference 1 instance of it:
public function doSomething($p_iNum)
{
NumericValidator $nv = NumericValidator::getInstance();
if(!nv->checkInteger($p_iNum))
// throw IllegalArgumentException
// ...
}
Finally, my question: which is better and more in keeping with best practices? Are there performance considerations? How would either approach affect things like concurrency, or requests coming from multiple users?
I would use a static class in your example. The differentiator I would use is if there is any state of the properties of an instance you are trying to preserve across access. This is what a singleton is designed for. The static class gives organized access to methods in a namespace which is helpful for clarity in your code but it does not have any properties about itself.
So yes you can use a singleton but it would be bad form because there are no instance properties that you want to make available across page accesses.
Hope this helps.
Use Singleton instead of static class only if you going to pass instance of NumericValidator in variable to some function.
In PHP 5.3 you can get instance of static class:
class test
{
public static function instance()
{
print 'zz';
}
}
$z = new test;
$z->instance();
Don't care about concurrency requests in PHP, it's single threaded, each process executes own code.
Are there any reasons I should not create a final class with static methods to avoid that some internal functions are called?
final class ModuleGlobalFunctions {
static public function generateWord {
$result = '';
while (strlen($result) < 12) {
$result = self::generateSyllable();
}
return $result
}
static private function generateSyllable() {
// Generates a random syllable.
// …
}
}
$word = ModuleGlobalFunctions::generateWord();
// It raises an error.
$syllable = ModuleGlobalFunctions::generateSyllable();
Creating a class to shield off private functions is a good idea. This way, a public method in the class can call a private method, without making the private method callable from outside the class.
Making a class final is also a good idea, as this indicates that the class has not been designed with overloading in mind, and makes the class simpler.
Making the class static is a bad idea, because it tightly couples the caller to the class. If you call Test::generateWord(), this will always use the Test class. However, if you use $test->generateWord(), you can pass in another class, which creates other words. This makes it easier to change the software and easier to unit test it.
Well, personally, I would recommend using classes to group similar logic. So in your case (the example you provided), it's a good idea.
As for final, it's a toss up. I prefer to use abstract to prevent instantiation (since PHP doesn't support static classes). If you do use final, I would suggest adding a private constructor to prevent instantiation: private function __construct() {}...
Personally, I like the concept of keeping it static. The reason is three fold. First, it's easier on memory (since there are no instances to keep track of). Second, it's faster (A static method call is faster than an instance method call). Third, and more importantly, it makes sense. Instances have a state (that's why they are instances). Does your class need a state? If so, then use an instance. If not, that's exactly what static classes are meant for...
As for passing an instance as Sjoerd mentions, you can do that with static classes (and actually be less tightly coupled than with instances). Here's the reason. Unless you require (and check for) an interface or inheritance, you have no idea if the object actually implements the method generateWord(). But, if you pass in a callback, it doesn't matter how the method is accessed (or its underlying construction), all that matters is that it has the same (or similar) syntax (with respect to parameters and return values). Now, interfaces are a better solution to this (since it enforces the interface), but they require pretty deep understanding of OOP to get the design right. In a pinch, a callback will work quite fine for that case...
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 ^^