0

I have a function in php:

function renden(array $additional_css_files = array(), $load_js = true, $load_keen = false, $allow_robots = false, $generate_csrf = true) {

}

It is becoming really nasty to specific all the optional parameters each time. I'd like to do the following trick using or'd flags (bitmask) as a single function parameter.

define("LOAD_JS", 1);
define("NO_LOAD_JS", 0);
define("LOAD_KEEN", 1);
define("NO_LOAD_KEEN", 0);
define("ALLOW_ROBOTS", 1);
define("NO_ALLOW_ROBOTS, 0);
define("GENERATE_CSRF", 1);
define("NO_GENERATE_CSRF", 0);


function render(array("foo"), LOAD_JS | NO_LOAD_KEEN | NO_ALLOW_ROBOTS | GENERATE_CSRF) {

}

See (http://www.php.net/manual/en/function.json-encode.php) and the paramter options. How do I code this logic inside the function?

Justin
  • 42,716
  • 77
  • 201
  • 296
  • Why not pass an array instead? `array('load_js' => true, ...)`? – zerkms Apr 02 '14 at 22:58
  • a bitmask is a nice dense handy way of representing a bunch of boolean values, not that the performance hit of the (bloated) array would really matter in most settings. One question is why is it a pain to pass all the optional parameters, if they are optional? If you often have to set just one of them that's late in the list, then I could see that. Anyway, extracting the values is easy.. answer coming. – RobP Apr 02 '14 at 23:06

1 Answers1

1

Change your define's to bitmasks:

// using binary literal notation requires PHP 5.4
define("LOAD_JS", 0b00000001);
define("LOAD_KEEN", 0b00000010);
define("ALLOW_ROBOTS", 0b00000100);
define("GENERATE_CSRF", 0b00001000);

Call your function as follows:

$flags = LOAD_JS | LOAD_KEEN | ALLOW_ROBOTS | GENERATE_CSRF;
render(array("foo"), $flags);

Inside your functions, extract the flags as follows:

function renden(array $additional_css_files = array(), $flags = 0b00001001);
$load_js = $flags & LOAD_JS;
$load_keen = $flags & LOADKEEN;
// ...etc
RobP
  • 9,144
  • 3
  • 20
  • 33
  • Great, awesome response. If I don't want to load, i.e. lets say default is `true` and I want to pass `false`, do I need `NO_LOAD_JS` or do I simply use `^LOAD_JS | LOAD_KEEN | ALLOW_ROBOTS | GENERATE_CSRF` – Justin Apr 02 '14 at 23:15
  • if you call render(array("foo"), LOAD_JS | LOAD_KEEN), for example, you are passing binary 0b00000011 which means ALLOW_ROBOTS and GENERATE_CSRF will be turned off. You could define("DEFAULT", 0b00001001) and then pass (DEFAULT | LOAD_KEEN) & ~LOADJS, for example. – RobP Apr 02 '14 at 23:18
  • Sorry, I mean if I prepend a parameter with `~` does it negate it? – Justin Apr 02 '14 at 23:20
  • 1
    So ~ inverts the bits of a parameter, then you have to logically AND with that to turn OFF the bit you don't want. Therefore ($someParams & ~LOAD_KEEN) turns off the LOAD_KEEN bit. – RobP Apr 02 '14 at 23:26