Avoiding variable replacement

I’m writing a configuration script so my users can use a form to make changes to a settings (.php) file instead of editing the file directly – keeps editing errors at bay. The settings file has some options like:

$lang['error_title'] = "Error";

If the user wanted to, they could add HTML or PHP variables into the setting:

$lang['error_message'] = "<b>Error:</b> $sys_domain doesn't allow that.";

If I get all the settings values by including the settings file, any variables are replaced by their value; the option above now becomes:

$lang['error_message'] = "<b>Error:</b> example.com doesn't allow that."

How can I avoid the the variable replacement and still allow the user to edit the settings in a web form?

I don’t understand what you mean

I have a settings file (settings.php) with this in it:

<?php
...
$sys_domain = 'example.com';
...
$lang['error_message'] = "<b>Error:</b> $sys_domain doesn't allow that.";
...
?>

My script includes the setting file:

<?php
...
include ('settings.php');
...
?>

after which the value of $lang[‘error_message’] is

<b>Error:</b> example.com doesn't allow that.

I need to be able to edit the value of $lang[‘error_message’] in a web form, without “$sys_domain” being replaced by “example.com” when it’s read in:

$output .= "Error message: <input name=\\"l_error_message\\" type=\\"text\\" size=\\"80\\" value='"
   . $lang['error_message'] ."' />

The problem is with how PHP handles double-quoted strings:

“The most important feature of double-quoted strings is the fact that variable names will be expanded…When a string is specified in double quotes or with heredoc, variables are parsed within it.”

http://www.php.net/manual/en/language.types.string.php#language.types.string.parsing

And I’m using double-quoted strings specifically for this reason.

Unless I’ve missed something, this little bit of code ought to work just fine to give me some strings where the variables aren’t expanded:

<?php
$settings = file('settings.php');
$language = array();
for ($i = 0; $i < count($settings); $i++) {
  if (substr($settings[$i],0,6) == '$lang[') {
    list($key,$value) = explode('=',$settings[$i]);
    $key = preg_replace('/(.*)\\'(.*)\\'(.*)/','$2',trim($key));
    $value = preg_replace('/"(.*)";/','$1',trim($value));
    $language[$key] = $value;
  }
}
echo '<pre>'.print_r($language,true).'</pre>';
?>

If there’s something better to use, please let me know.

Why don’t you just use an SQLite database to hold the configuration details?
It is a whole lot easier using SQL commands to get and update options this way.

You’re absolutely right, but:

  1. This is a piece of legacy software that I’m maintaining

  2. A database adds a level of complexity that I’d rather avoid for the users I’m targeting

That said, my plan is to develop a version that does use a database, as soon as I’ve got this version to the point where it’s dead simple.