myol
myol

Reputation: 9896

Edit php code and variables in file

I have a php file with comments and code.

<?php

// Some comments
define('THING', 'thing1');

$variable = 'string1';

if ($statement === true) { echo 'true1'; }

I want to know the best way to edit this file to change the variables and spit out a new version of the file with the changes.

<?php

// Some comments
define('THING', 'thing2');

$variable = 'string2';

if ($statement === true) { echo 'true2'; }

The file is fairly large. I could write a function which adds together a massive string for output but all the escaping I would have to do with comments etc would be a headache.

I was thinking of including the file but this would just allow it's variables to be used within another class.

So far the only thing I can think of is to make a 'skeleton' version of the file (below) with the variables I want to change written into the file. I can assign them, but actually dumping it all back out to the file like either of the above examples has escaped me.

Best way of doing this?

<?php

// Some comments
define('THING', $thing);

$variable = $string;

if ($statement === true) { echo $true; }

Upvotes: 3

Views: 259

Answers (2)

Darragh Enright
Darragh Enright

Reputation: 14146

I was going to echo @Prisoner's comment above, but I see that you mentioned you are working with a limitation. You can use strtr() to do basic templating, like so:

<?php

$template = <<<'STR'
hi there {{ name }}

it's {{ day }}. how are you today?

STR;

$vars = [
    '{{ name }}' => 'Darragh',
    '{{ day }}'  => date('l'),
];

$result = strtr($template, $vars);

Which yields the following string:

"hi there Darragh

it's Monday. how are you today?"

You can then write the result to a file, echo it etc.

For your specific example above:

<?php

$template = <<<'STR'
<?php

define('THING', '{{ const }}');

$variable = '{{ variable }}';

if ($statement === true) { echo '{{ echo }}'; }
STR;

$vars = [
    '{{ const }}'    => 'thing1',
    '{{ variable }}' => 'string1',
    '{{ echo }}'     => 'true1',
];

echo $result = strtr($template, $vars);

Yields:

"<?php

define('THING', 'thing1');

$variable = 'string1';

if ($statement === true) { echo 'true1'; }"

Hope this helps :)

Upvotes: 2

light
light

Reputation: 4297

Sounds like a form of the simple string replacement problem.

If you need to save the new variables into a new file, while the "skeleton" file remains as valid PHP syntax, you probably need to name your template variables in a way such that they can be uniquely and correctly found & replaced. You are basically creating your own simple templating language.

So your template file could look like this:

<?php

// Some comments
define('THING', $TEMPLATE_VARIABLE['thing']);

$variable = $TEMPLATE_VARIABLE['string'];

if ($statement === true) { echo $TEMPLATE_VARIABLE['true']; }

And the code to replace your template variables

// Read the template file
$str = file_get_contents($template_file_path);

// Make your replacements
$str = str_replace("$TEMPLATE_VARIABLE['thing']", 'thing1', $str);
$str = str_replace("$TEMPLATE_VARIABLE['string']", 'string1', $str);
$str = str_replace("$TEMPLATE_VARIABLE['true']", 'true1', $str);

// Save as a new file
if (file_put_contents($output_file_path, $str, LOCK_EX) === FALSE) {
    throw new Exception('Cannot save file. Possibly no write permissions.');
}

If you don't mind your template file not being valid PHP, you can of course go crazy with your templates, e.g. define('THING', ~!@#$THING%^&*);

FINAL NOTE: In any case, if you can afford time and effort to refactor, please do. The code snippet you have shown is not the best method of managing variables that are potentially used in multiple places (are they actually application settings?). The best thing to do would actually be to have a configuration file that defines all these variables.

// In the config file
define('MESSAGE_TO_SHOW_IF_TRUE', 'true');
define('DEFAULT_USER_NAME', 'lala');

// In the application file
if ($statement === TRUE) { echo MESSAGE_TO_SHOW_IF_TRUE; }
$name = DEFAULT_USER_NAME;

Upvotes: 1

Related Questions