3

I'm looking for a PHP function that I can use to edit key/value pairs in a text file.

What I want to do (PHP):

changeValue(key, bar);

and have in setings.txt:

key = foo
key2 =foo2

Change to:

key = bar
key2 = foo2

What I got so far (not working):

function changeValue($input) {
    $file = file_get_contents('/path/to/settings.txt');
    preg_match('/\b$input[0]\b/', $file, $matches);
    $file = str_replace($matches[1], $input, $file);
    file_put_contents('/path/to/settings.txt', $file);
}

How to update an ini file with php? got me started. I read many other questions but I couldn't get it working.

Community
  • 1
  • 1
PeteM
  • 51
  • 6
  • I want to use this to store and change small strings of data, that user enters on a webpage. – PeteM Jan 07 '16 at 21:26
  • I'm assuming this is legacy code and that's why you're not using Yaml or something like that. Managing configuration files natively with PHP is a pain in the patooty. There are other ways to do this that are better, yaml being one of them. – Halfstop Jan 07 '16 at 21:28
  • The user is me and I will be using about 10 values. I'd like to keep it as simple as possible, but I will look into Yaml. – PeteM Jan 07 '16 at 21:29
  • OK, but the simplest way is to use yaml or something similar rather than cranking out a bunch of custom PHP code. http://webdeveloper.gdemolished.com/stop-building-shitty-php-web-applications/ – Halfstop Jan 07 '16 at 21:30
  • Related: https://stackoverflow.com/questions/3724584/what-is-the-best-way-to-save-config-variables-in-a-php-web-app – Jesse Nickles Jul 23 '22 at 17:48

2 Answers2

2

I would use JSON with at least the JSON_PRETTY_PRINT option to write and json_decode() to read.

// read file into an array of key => foo
$settings = json_decode(file_get_contents('/path/to/settings.txt'), true);

// write array to file as JSON
file_put_contents('/path/to/settings.txt', json_encode($settings, JSON_PRETTY_PRINT));

Which will create a file such as:

{
    "key": "foo",
    "key2": "bar",
    "key3": 1
}

Another possibility is var_export() using a similar approach, or another simple example for what you're asking:

// read file into an array of key => foo
$string = implode('&', file('/path/to/settings.txt', FILE_IGNORE_NEW_LINES));
parse_str($string, $settings);

// write array to file as key=foo
$data = implode("\n", $settings);
file_put_contents('/path/to/settings.txt', $data);

So read in the file, change the setting $setting['key'] = 'bar'; and then write it out.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • This won't work because often in text files the `\n` isn't always the only special break character and can cause a lot of processing errors. – Derek Pollard Jan 07 '16 at 21:53
  • I will study this. Just to make clear, there are multiple key/value pairs in the file (about 10). I will also edit the question to reflect that. – PeteM Jan 07 '16 at 21:53
  • I can work with limitations, such as no spaces or no certain characters, as long as I know them. – PeteM Jan 07 '16 at 21:56
  • 1
    @DerekPollard: This isn't for any text file, it is for the specific format that OP stated and has control over. But check out JSON. – AbraCadaver Jan 07 '16 at 21:56
  • A `.txt` file doesn't exclusively accept `\n` as the line break character. OP has control over a .txt. my comment still stands true. – Derek Pollard Jan 07 '16 at 21:57
  • Please see this page for various versions of line break special characters: https://en.wikipedia.org/wiki/Newline – Derek Pollard Jan 07 '16 at 22:00
  • @DerekPollard: Umm... The code I posted uses only a newline `\n` to construct the file. Where would these other linebreaks come from? – AbraCadaver Jan 07 '16 at 22:03
  • on windows servers an `\r` is needed along with a `\n` for the new line to be read properly. – Derek Pollard Jan 07 '16 at 22:04
  • If I change the file format to JSON, how do i actually access and write the data? – PeteM Jan 07 '16 at 22:19
  • @DerekPollard: No. Some programs such as Notepad need it to display on the next line but Windows and PHP do not need it. It's just an old convention from DOS eraly Windows days. – AbraCadaver Jan 07 '16 at 23:45
  • @abracadaver it does tho, depending on what server this script is on, it may not read the file correctly – Derek Pollard Jan 08 '16 at 00:08
  • I chose this answer because it answers my problem pretty much to the letter and provided another useful way to solve the problem. – PeteM Jan 14 '16 at 18:19
2

Instead of using file_get_contents use file, this reads each line in as an array. Under you see working code. Had a little problem with write array added more breaks but not sure why.

changeValue("key", "test123"); 

function changeValue($key, $value) 
{
    //get each line as an array. 
    $file = file("test.txt"); 

    //go through the array, the value is references so when it is changed the value in the array is changed. 
    foreach($file as &$val) 
    { 
        //check if the string line contains the current key. If it contains the key replace the value. substr takes everything before "=" so not to run if the value is the same as the key. 
       if(strpos(substr($val, 0, strpos($val, "=")), $key) !== false)
        {
           //clear the string
           $val = substr($val, 0, strpos($val, "="));
           //add the value 
           $val .= "= " . $value; 
        }
    }
    //send the changed array writeArray(); 
    writeArray($file); 
 }

function writeArray($array) 
{
    $str = ""; 
    foreach($array as $value)
    {
        $str .= $value . "\n"; 
    }

    //write the array. 
    file_put_contents('test.txt', $str);
}

?>
Nyranith
  • 367
  • 2
  • 6
  • 15