Classes Vs Functions

I understand classes (or how to write them anyway), functions and a very good level of PHP. However, I often see people confused over when to use functions over classes. For me, use a function unless there is a good reason to use a class. Many (semi-programmers or below) seem to use only functions (because they don’t understand classes) or mainly classes (because they think they have to).

I have produced a quick-reference guide (for myself) to help me decide whether I should use a function or a class.

The question is: am I right? is this the right way to approach classes?

Use a class when…
(1) You need to remember something in a function (for example how many times you’ve executed that function in that script or feel variables in the function would be better ‘memorised’ for other executions of that function during that script).
(2) To group data together, e.g. if you return user data from a database and then update it various times in the script. (If you find you’re using lots of arrays to store data that is updated during the script execution then a class may be better).
(3) To group together an entire part of the system (user login, database access etc.)
(4) Use a static class on occasions when you have a few functions that can be grouped together and will only be used a few times on your site (rather than putting them all in a file of all functions that is included on every page).
(5) If someone wants to group together pieces of code and distribute as a read-made solution (like on phpclasses.org) - maybe even if it’s just a group of functions (e.g. a complete date/time manipulation class would probably just be a few functions together).

If the requirement doesn’t fit with the 5 points above then use a function.

I always use an MVC design so code would not be unnecessarily duplicated regardless of if I used functions or classes.

If you don’t need polymorphism, inheritance, abstraction or encapsulation (which are OOP’s main powers), you probably don’t need an OOP-approach.
Using OOP for the sake of using it, is useless, but the code may be more understandable and maintainable, especially on somewhat bigger projects.
It depends on the problem you need to solve.

:scratch:


function main() {
  static $callOnce = false;

  if($callOnce) {
    throw new FatalException('Main cannot be called more than once per script iteration');
  } else {
    $callOnce = true;
  }
}

So, no. Functions have a mechanism to do this.

(2) To group data together, e.g. if you return user data from a database and then update it various times in the script. (If you find you’re using lots of arrays to store data that is updated during the script execution then a class may be better).

Encapsulation. Good, that’s one reason.

(3) To group together an entire part of the system (user login, database access etc.)

To a degree.

(4) Use a static class on occasions when you have a few functions that can be grouped together and will only be used a few times on your site (rather than putting them all in a file of all functions that is included on every page).

Prior to PHP 5.3 yeah, subsequent to PHP 5.3 use namespaces for this. Static classes are rarely useful.

(5) If someone wants to group together pieces of code and distribute as a read-made solution (like on phpclasses.org) - maybe even if it’s just a group of functions (e.g. a complete date/time manipulation class would probably just be a few functions together).

If the requirement doesn’t fit with the 5 points above then use a function.

I always use an MVC design so code would not be unnecessarily duplicated regardless of if I used functions or classes.

Hmm, that’s close to abstraction.

Here…

  • Encapsulation - related methods and data are bound together. Instances of data carry their own functions to work with them and don’t have to worry about overwriting each other.
  • Abstraction - Classes, once stripped of dependencies, function as a ‘black box’ where you don’t necessarily need to know about or worry about what is going on inside just as long as you understand the API the class presents.
  • Inheritance - Code is reused by having child classes inherit methods and members from parents.
  • Polymorphism - Code can be changed, provided the functions are granular enough, by creating child methods that override their parent methods.
  • Dependency Control - Most programmers throw this in with encapsulation but I consider this its own point - dependency control means hiding as much of the interior workings of a class from the outside world as possible, carefully limiting the use of public members and methods. Makes the code a lot easier debug than any function collection.

– And these are particular to PHP –

  • Typehinting is currently object based. Heavy use of it can make the program easier to debug and control.
  • Autoloading is object based. You can’t autoload a function library short of binding it to a static class. Using static classes just feels like swimming in the kiddie pool - if you’re going to use classes, use them - don’t wade.

I use one function in my current code base because non of the above applies to that function. Also, functions create a new variable scope, which is important if you want to keep your application’s variables out of the $GLOBALS array.

The biggest problem with functions is they have no scope control. You can’t protect them or declare them private. Since they can be called from anywhere reliance on them creates nasty dependency headaches as the application grows.

Thanks for the reponses.

On another forum someone said “If you’re going to use OO then follow it through and stick with it. Don’t switch between procedural and OO coding styles in one program.”

This has slightly confused me as I would say that I want to create a fully OO site but surely a simply requirement to (e.g.) ‘convert a number into a currency amount’ would be best done in a function on its own.

Is this person saying to never use functions?

You can still have functions. Procedural programming isn’t defined and limited by the use of functions. And OOP also allows functions outside of classes. In fact, an oop purist would demand that a function unrelated to an object be outside of said object.

Writing a function in the global namespace is, IMO, no different to using PHP’s built in functions.

Many times when carrying out a task code needs to be factored across multiple logic sets. Using an OO approach makes it very simple to hide these parts from the rest of the application. A single entry method can be used within public scope, having all the other support-oriented methods limited to the classes scope. using only functions does not make this possible and the only way to replicate the concept of limiting the number of functions within public scope is to essentially cram all logic into a single function. This approach supports very poor coding practices and non-reasonable segments of logic. Therefore, scope is an important part of OO that shouldn’t be overlooked when comparing to functions that are always going to be global. For that of many reasons reason, I prefer the DI approach and rarely, if ever resort to functions, unless native to the language of-course.