问题
I'm using constants for output messages in different languages. For example, if a user chooses "English", a file with this constant would be required:
define('welcomeMessage','Welcome!');
If she chooses "Spanish":
define('welcomeMessage','Bien Venidos!');
etc etc...
The problem occurs when a user iterates through languages. I can't redefine constants with either define/apc_define_constants (as far as I know). Can I delete and redefine them?
Is there a good solution for this?
回答1:
Constants created with define() can't be undefined once created.
Constants created with apc_define_constants() can be removed by passing an empty array to the function.
I'm not sure I understand why this is a problem however. What do you mean "the user iterates through languages"? As soon as a request returns to the user and they generate a new request (via a redirect, submitting a form, clicking a link or generating an AJAX request) then you're free to define whatever constants you like on the new invocation.
Unless the problem is that you define the constants and then call the code to set the new language/messages, which triggers an attempt to set all the constants (which will fail with define()).
回答2:
It doesn't make sense to use a constant if the value can be changed later. I would recommend creating a static class where you can set the language and instead of using constants you would get your welcome message from that class. Let's say the class was named Lang:
Lang::setLang('spanish');
Lang::getWelcome();
The getWelcome() method checks the lang value set with setLang() and returns the appropriate translated string.
Using a static class means you won't have to instantiate the class, and all other code can reference that static class without having to make new instances and having to set the language being used.
回答3:
I don't know how the user changes his language during runtime but constants should not be modified or redefined during runtime.
Consider using global variables.
回答4:
You should not have your languages defined as constants. There are far more flexible ways, like putting them in a language class, the database or even local files. Having them in code is just bad.
The language class should abstract away all the details.
$language = new Language('english');
$welcomeString = $language->get('welcomeMessage');
....
$language = new Language('spanish');
$welcomeString = $language->get('welcomeMessage');
The parameters passed to the language constructor could still be a define, along w/the get() arguments, but the actual language text should not live in code, I'd stick it in the database.
回答5:
Here is what I do when I need "constants" that need to be redefined (as funny as it sounds):
// somewhere in your global file
function config($key, $value) {
$GLOBALS[$key] = $value;
}
function conf($key) {
return $GLOBALS[$key];
}
function configured($key) {
return isset($GLOBALS[$key]);
}
Now whenever you need to define your "constant" just use:
config('SHOW_AVATAR', true);
When you need to access it, use:
if(conf('SHOW_AVATAR') === true)
echo "AVATAR";
If you need to check if it's been defined already, use:
if(configured('SHOW_AVATAR'))
echo "Setting set";
Why I use this? Because it looks like define() function in my code. That makes it easier to separate settings from variables. I mainly use it in my partial views where I need to have a variable with global scope (like constants) but be able to redefine it at any time.
Hope it helps you.
来源:https://stackoverflow.com/questions/2217074/un-define-constants-with-define-apc-define-constants-in-php