7

I recently answered this question:

What are good reasons to use static methods in PHP?

The first thing to come to mind, of course, was a singleton. With little exception, the other answerers provided the same singleton example. But that got me thinking... I don't really ever use static methods or properties for anything besides creating singletons!

A brief search netted many tutorials on using static methods, almost all of which implement some variation of the same singleton class.

I'm really interested: What reason do we have to make static methods other than creating singletons (or other than just being lazy and wanting a global function)?

Does anyone have a pragmatic example of using a static method that could not be accomplished better using a dynamic design pattern? The example can be a singleton if that makes sense in it's context, but I'm interested in other reasons besides the singleton-aspect of the solution.

Community
  • 1
  • 1
Stephen
  • 18,827
  • 9
  • 60
  • 98

3 Answers3

5

A factory pattern will normally use a static call as well; but it's sensible to use static methods for any class mathod that has no dependencies on the instance properties or other instance methods, especially when they're called regularly, for performance reasons.

The logical place for the following method in PHPExcel is in the PHPExcel_Cell class, because it pertains directly to manipulating a cell address (any cell address, not just the address of a specific instance), but it has no dependency on the instance, so I declare it static.

public static function stringFromColumnIndex($pColumnIndex = 0) {
    if ($pColumnIndex < 26) {
        return chr(65 + $pColumnIndex);
    } elseif ($pColumnIndex < 702) {
        return chr(64 + ($pColumnIndex / 26)).chr(65 + $pColumnIndex % 26);
    }
    return chr(64 + (($pColumnIndex - 26) / 676)).chr(65 + ((($pColumnIndex - 26) % 676) / 26)).chr(65 + $pColumnIndex % 26);
}

And this method isn't particularly difficult to test

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • And how exactly do I mock the static function call for this when I'm testing another object that uses this? – James Butler Jan 13 '11 at 23:17
  • Oh! I'd forgotten that there was only one true test methodology – Mark Baker Jan 13 '11 at 23:30
  • @Mark James raises a valid question. And I'd say it's interesting for anyone who wants to use PHPExcel in their own projects to know how it's creators suggest to test it. – Gordon Jan 13 '11 at 23:41
  • 1
    @Gordon - I can't use PHPUnit or SimpleTest for module testing, for reasons other than static methods/properties anyway... I've yet to figure out how to mock up a nested tree of self-referential (in both directions) objects. All my unit tests are hand-crafted, run via phpt, and the tests are ordered so statics are tested before anything that might reference them. Probably not the answer you're looking for: but when testing PHPExcel itself, it's easiest for users to treat it as a "black box" in much the same was as (for example) PDO is tested... after all, how do you mock a result set in PDO? – Mark Baker Jan 14 '11 at 09:08
  • @Gordon - Any further discussion is probably better continuing elsewhere. I think you and I disagree about statics, and about certain design patterns, and that's probably not appropriate for this forum. – Mark Baker Jan 14 '11 at 09:10
  • @Mark Actually that *was* the answer I was looking for. I didn't ask to start an argument or a flamewar but out of honest interest. Thanks for clarification :) – Gordon Jan 14 '11 at 09:20
  • @mark Sorry, my remark wasn't meant to come across quite so agressively. I agree there is no one true test methodology (for better or for worse), but there are some that are more commonly used than others. LSB in PHP 5.3 might actually allow static s to be tested sort of nicely but i haven't had a chance to give it a shot – James Butler Jan 14 '11 at 13:26
  • @James - I think the issue is that static methods still have their place; but there are no unit test tools/techniques that have a decent, clean method for testing when they're being used. Without that ability to test, they've gotten a bad rep... it doesn't help that they're often abused either. I use statics in (what I consider) appropriate situations, but have the pain of needing to "jump through hoops" when testing: not using them simplifies testing, but perhaps forces a different approach to coding... all the potential for a flame war that nobody can really win. – Mark Baker Jan 14 '11 at 13:45
4

It's not necessarily about patterns. PHP is not a persistent environment, so lifetime of any object instance is likely to be milliseconds, but it requires memory allocation/release and extra cpu cycles. Unless you need reusable objects or collections, I find non-static objects to have little justification.

Dennis Kreminsky
  • 2,117
  • 15
  • 23
2

Tongue in cheek answer, there aren't any. Static methods are very very hard to test or mock.

Gordon
  • 312,688
  • 75
  • 539
  • 559
James Butler
  • 3,852
  • 1
  • 26
  • 38
  • +1 and the same is true for [Singletons](http://stackoverflow.com/questions/4595964/who-needs-singletons/4596323#4596323). Avoid both althogether. – Gordon Jan 13 '11 at 23:09
  • Singletonitis - the plague of iffy oop designs – James Butler Jan 13 '11 at 23:14
  • 3
    Public static methods that reference global state (class public static state is global state too) can cause great difficulties in testing, especially negative tests for changes in global state. Static methods (or global functions) which only operate on arguments passed to them and call no other (or only known trusted) functions are extremely easy to test - no mocking needed. – Iiridayn Nov 21 '12 at 16:55
  • 1
    -1 Nice links but they all pinpoint the underlying issue. Don't couple static methods and (especially) global state. A stateless static method is actually easier to test because you don't need to waste time/memory on unnecessary object constructions. All it requires is one simple rule, "respect the local scope". Developers who don't understand what that means shouldn't use static methods. Static methods aren't some magical construct made of unicorn farts and fairy ashes. They're just namespaced functions. – Evan Plaice Dec 11 '12 at 23:16