0

I wrote this script in PHP:

$menuen = array(
    "didattica" => "program",
    "procedure" => "policies",
    "news" => "news",
);
$menuit = array(
    ...
);
function getName ($link) {
    if ($lang === "en") {
        if (in_array($link, array_keys($menuen))) {
            return $menuen[$link];
        }
        else {
            return ucfirst(str_replace("_", " ", $link));
        }
    }
    else {
        if (in_array($link, array_keys($menuit))) {
            return $menuit[$link];
        }
        else {
            return ucfirst(str_replace("_", " ", $link));
        }
    }
}

$lang is en. But when I call the function like as getName("didattica");, the script throws following errors:

Warning:  array_keys() expects parameter 1 to be array, null given in [script path] on line [if (in_array($link, array_keys($menuen))) {]

Warning:  in_array() expects parameter 2 to be array, null given in [script path] on line [if (in_array($link, array_keys($menuen))) {]

So, the script doesn't recognize $menuen as an array. Why?

Thank you in advance

Agantacroxi
  • 81
  • 1
  • 10
  • You need to turn your error reporting setting up to also display E_NOTICE level errors. – deceze Jul 01 '13 at 14:53
  • 1
    @Agantacroxi - see my response below. The global recommendations are not a great solution for what you are actually trying to achieve. – Trent Jul 01 '13 at 15:08

5 Answers5

3

The problem is related to the scope of the variables, you need to identify its as global first.

Change the function for this one:

function getName ($link) {
    global $menuen,$menuit;

    if ($lang === "en") {
        if (in_array($link, array_keys($menuen))) {
            return $menuen[$link];
        }
        else {
            return ucfirst(str_replace("_", " ", $link));
        }
    }
    else {
        if (in_array($link, array_keys($menuit))) {
            return $menuit[$link];
        }
        else {
            return ucfirst(str_replace("_", " ", $link));
        }
    }
}
leticia
  • 2,390
  • 5
  • 30
  • 41
3

$menuen/$menuit is outside of the scope of the function. You can do 1 of 2 things.

Use global:

function getName ($link) {
    global $menuen,$menuit;
    ....
}

Pass the variable as a function parameter:

function getName ($link,$menuen,$menuit) {
    ....
}

getName($link,$menuen,$menuit);

The second is the preferred method.

Samuel Cook
  • 16,620
  • 7
  • 50
  • 62
  • 2
    The second method is definitely preferred. Using globals just seems so cheap. Pass in the parameters you need, or better yet pass them in as a single array of parameters. – bcrawford Jul 01 '13 at 14:56
2

So, everyone has suggested you define globals... Now, having looked at what you are trying to achieve, it's localisation stuff.

Assuming you've decided to write your own (for reasons unknown; goto phpclasses.org and you'll find a million localisation scripts to do this), I would suggest the following:

$menuen = array(
    "didattica" => "program",
    "procedure" => "policies",
    "news" => "news",
);
$menuit = array(
    ...
);
$lang = $_GET['lang']; // Just an example of how the lang would be set

if ($lang == 'en') {
    $link_name = getName($link, $menuen);
elseif ($lang == 'it') {
    $link_name = getName($link, $menuit);
.... // Also suggest using switch if it's a defined list; or perhaps a better array to hold all of them.

function getName ($link, $menu) {
    if (in_array($link, array_keys($menu))) {
        return $menu[$link];
    }
    else {
        return ucfirst(str_replace("_", " ", $link));
    }
}

This way, there is little code duplication and it's completely reusable.

[ EDIT : an even better approach ]

$menues = array (
    "en" => array (
        "didattica" => "program",
        "procedure" => "policies",
        "news" => "news",
    ),
    "it" => array (
        "didattica" => "...",
        "procedure" => "...",
        "news" => "...",
    ),
);

$lang = 'it';
$link = 'news';

$link_name = getName($link, $menues, $lang);

if ($link_name === false ) {
    echo "Language not defined";
}

echo $link_name;

function getName ($link, $menues, $lang) {
    if (in_array($lang, array_keys($menues))) {
      if (in_array($link, array_keys($menues[$lang]))) {
          return $menues[$lang][$link];
      }
      else {
          return ucfirst(str_replace("_", " ", $link));
      }
}
else {
        return false;
    }
}
Trent
  • 2,909
  • 1
  • 31
  • 46
  • $link changes each time. I can't put the if/ifelse statement each time (I have to use that function somewhat like 80 times) – Agantacroxi Jul 01 '13 at 22:09
  • I'm not sure you understand... $link has nothing to do with the if/else - the if else is for the language... Your current solution is terrible for what you're trying to achieve, you should read about DRY principles of programming... – Trent Jul 02 '13 at 04:20
  • Right. That's what I'm saying. I'm not going to put an if/else statement for languages 80 times, right? – Agantacroxi Jul 03 '13 at 18:06
  • @Agantacroxi - well you're doing that anyway. I'm not sure you understand my code. You only if/else the LANGUAGES not the links. In fact, I would say my code is probably closer to DRY principles than any of the other answers which mostly suggest a correction to poor software design – Trent Jul 04 '13 at 05:36
  • I understand why you couldn't follow me: I hadn't told you that I added the $lang parameter to the function (as $lang is global, too), so it is enough to call the function like this: getName($link, $menuen, $menuit, $lang); to have the right language without using an if/else statement each time. – Agantacroxi Jul 04 '13 at 08:06
  • @Agantacroxi - see the edit... This is approach is FAR better than using globals. Seriously, filling your application with globals is the worst design pattern out there. – Trent Jul 04 '13 at 11:48
  • Like this, you only cut the amount of globals by one (as you are merging the two menu arrays). It is better (no doubt), but I don't feel like I'm filling my application with globals otherwhise. – Agantacroxi Jul 04 '13 at 16:54
  • I must localize the application in only two languages (en and it), just to clear that out. Thank you anyway. – Agantacroxi Jul 04 '13 at 16:55
  • 1
    @Agantacroxi - a general principle to remember is; if a variable does not need persistence throughout the entire application; it should not be a global. Here's a good thread about globals you should read: http://stackoverflow.com/questions/2216340/the-advantage-disadvantage-between-global-variables-and-function-parameters-in – Trent Jul 04 '13 at 17:48
1

you can't just use globals in functions, you have to do it like this:

function getName ($link) {
    global $menuen, $menuit;
    if ($lang === "en") {
    .....
x4rf41
  • 5,184
  • 2
  • 22
  • 33
0

You should write

global $menuen;

after function definition if you want to run it this way.

mr. Pavlikov
  • 982
  • 5
  • 7