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

2
  • You need to turn your error reporting setting up to also display E_NOTICE level errors. Commented Jul 1, 2013 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. Commented Jul 1, 2013 at 15:08

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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.
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));
        }
    }
}

Comments

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;
    }
}

9 Comments

$link changes each time. I can't put the if/ifelse statement each time (I have to use that function somewhat like 80 times)
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...
Right. That's what I'm saying. I'm not going to put an if/else statement for languages 80 times, right?
@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
@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: stackoverflow.com/questions/2216340/…
|
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") {
    .....

Comments

0

You should write

global $menuen;

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.