Posts Tagged call_user_func

Poking holes in PHP object privacy

Get it? Holes? Cheese?PHP provides a decent model of class member visibility, with public, private, and protected members to help you define tight APIs for your objects and show other developers how your object is supposed to be used. But used naively, PHP’s ‘magic methods’ can easily and subtly subvert this system, making everything public.

If you’re still new to object oriented programming in PHP5, think of “public” as roughly analogous to “my function’s arguments” and “private” as “local variables inside the function”. You wouldn’t want someone calling your function and messing with the local vars, and you wouldn’t want someone using your object messing with its private members.

Magic methods provide functionality like catching references to methods and properties which are not visible to us, and doing special things with them. Magic methods have always struck me as a bit weird, and whenever you bring them up in discussions online, there’s always a few people with reservations about them – efficiency, clarity, use-cases and so on.

I’m still in two minds; they can be useful in some circumstances, but here’s one reason why they could be considered harmful: Used carelessly, they can easily enable an OOP antipattern where all class members become public, even those declared as private or protected in the class definition. Read the rest of this entry »

, , , , , , , , , ,


Overloading in PHP

Murray Picton wrote up a blog post today on overloading functions in PHP. Overloading is a useful feature of many languages. Murray gives a nice definition in his post:

Overloading a function is the ability to define a function more than once with a different set of parameters for each one and then when it is called, the version of the function that matches the parameter set will be executed.

so you can define function foo(String $a) and foo(Array $a) and a different version will be called depending on how you call it. But, PHP’s idea of overloading is completely different and not really related.

Hello ladies, look at PHP, now back to Java, now back to PHP. Sadly, PHP’s not Java, but it can look (a bit) like Java if you stop using lady-scented functions and start using method overloading.

I just wanted to get that quote in somehow.

Murray’s solution is to use func_get_args inside your function, and perform some logic to switch execution to a different branch depending on what we find there. Something like:

function foo() {
    $args = func_get_args();
    if(is_string($args)) { /* do some stuff */ }
    else if(is_array($args)) { /* do some stuff */ }

This works well enough, but there are a few things I don’t like about it:

  1. You have to put all the code into one function, instead of literally overloading multiple functions
  2. The “which version am I” code and the actual functionality are intermixed inside the function

I thought an OO solution might mitigate against these things, allowing us to write completely separate functions, but which can be called with the same name, a different one being executed depending on the arguments. I’m not certain my solution is an improvement over Murray’s, but it’s a different approach if nothing else:

Read the rest of this entry »

, , , , , , , ,