Search code examples
phpvariablesfunctionoptional-arguments

how to use a function with a non-optional argument defined as the third


I'm using someone elses class and that person has defined a function with five arguments.

in Sentry.php:

function checkLogin($user = '',$pass = '',$group = 10,$goodRedirect = '',$badRedirect = '')

If all five fields are filled in this leads to a login procedure.

Now on the page where he explains how to use this there is a snippet which, according to php.net, doesn't make sense.

in a page that loads the sentry:

require_once('../system/Sentry.php');
$theSentry = new Sentry();
if(!$theSentry->checkLogin(2)){ header("Location: login.php"); die(); }

which by default should behave as such that it checks if the $group argument is <= 10 (default). In this situation it should be two. If the user checked has a group-variable of <=2 this should enable the person to view the page.

However, this doesn't work and for a very obvious reason: the php manual states:

Note that when using default arguments, any defaults should be on the right side of any non-default arguments; otherwise, things will not work as expected.

So the code, according to phpbuilder.com should have no optional ($variable = default_something) field to fill in with a call to the function and it definitely shouldn't be defined as the third of five arguments.

How can I use the function like this?:

checkLogin(2)

Solution

  • Default arguments are PHP's way of dealing with the lack of overloaded functions. In Java you can write this:

    public void login(String username)
    public void login(String username, String password)
    

    In PHP you have to solve it like this:

    function login($username, $password = '')
    

    This way $username is mandatory and $password is optional. While this may be convenient, it isn't always. In your example there are a log of arguments and they are all optional. A clean solution for this would be to make 1 function that does the work and add 'convenience' methods to make the interface cleaner.

    So add:

    function checkLoginGroup($group = 10) {
      $this->checkLogin('', '', $group);
    }
    

    It simply calls the function that already exists, but it allows for a cleaner interface, just call:

    $theSentry->checkLoginGroup(2);
    

    It's even neater to make the provided method private (or protected, depending on your needs) and create public 'convience' methods so you can hide the implementation details.

    However, if you can not or don't want to change the original class, you might be able to create a subclass.