1

I use a config.php file that returns an array. Before releasing the project, I usually manually change the 'apiKey' value that I use while developing in the file. I forget to perform this replacement sometimes, so I'm looking for a programmatical way to find this in a string version of the file:

'apiKey' => '1234567890'

and replace with this:

'apiKey' => 'YourAPIKeyHere'

The development apiKey value, spaces, tabs and formatting are inconsistent (Developer/IDE specific), so I guess there are wildcards for that?

Then I can just make the change in my deployment script.

Edit to show sample of config.php (which will be read into a string, edited, then re-written as a file).

<?php
return array(
// Comments with instruction exist throughout the file. They must remain.
'apiKey' => 'ecuhi3647325fdv23tjVncweuYtYTv532r3',
...
);

Edit: **There are instructional comments in the config.php file that must remain. So re-writing a modified array will lose the comments, and that is undesirable.

10
  • can you edit your question to show the config.php content? Commented Aug 26, 2018 at 12:40
  • if you are using linux you can do a sed -i "s/'apiKey' .*/'apikey' => 'yourAPIKEYhere'/g" file.txt from terminal ,, will only work if the apikey part is in a single line and nothing follows it Commented Aug 26, 2018 at 12:46
  • @Elementary, I edited the question for requested info. Commented Aug 26, 2018 at 15:53
  • so the answer of Hasan Tingir is the correct way to proceed according to me... Commented Aug 26, 2018 at 15:55
  • @Elementary Please see my edit. Commented Aug 26, 2018 at 16:24

5 Answers 5

1

Save the config file's text in a variable called $content.

Then call:

 $content = preg_replace("~'apiKey'\s*=>\s*'\K[^']+~", 'YourAPIKeyHere', $content, 1);

Then overwrite the file with the updated variable.

http://php.net/manual/en/function.preg-replace.php

\s* means match zero or more whitespace characters.

\K means restart the match from this point.

[^']+ means match one or more non-single-quote character.

Regex101 Demo

PHP Demo

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

5 Comments

@mickmacusa Nice! RegEx makes an elegant solution as opposed to looping through a file as array like I ended up doing. I could never wrap my head around regex to feel comfortable. I'm implementing this into the project and accepting this answer as it was what I originally requested, a regex. My question was edited and someone actually replaced the regex part with something they figured I really wanted. Go figure. lol. One question. I tried with YourAPIKeyHere! and it failed. Do I need to escape the replacement value?
No, the replacements string doesn't need any special markup -- just a raw text string. If you show me your new snippet, I'll have a look. You are welcome to overwrite my edit if it does not accurately depict your issue or you wish to add more relevant details.
$config = file_get_contents('app/config.php');$config = preg_replace("~'apiKey'\s*=>\s*'\K[^']+~", 'YourAppAPIKeyHere!', $config, 1); $zip1->addFromString('app/config.php', $config); Fails with !. Although I would probably never use special characters.
May I see a pastebin of your text file? or does it contain sensitive data? I don't see anything out of place in your code. As a blind guess, perhaps add i after the closing pattern delimiter (the second ~) to make the pattern case-insensitive. Maybe your apiKey has slightly varied casing. ...My pattern will not find/match apikey because it is case-sensitive.
It worked fine without the exclamation mark. When it failed it eliminated the entire line. I can share the file but don't know how to do a pastebin.
1

I assume that you have a config file such as;

return [
 'dbname' = 'project',
 'username' = 'root',
 'password' = '123456',
  .
  .
  .
 'apiKey' => '1234567890',
]

So you can make a small helper method then you can use it before relasing your project..

function reset_config()
    {
        $file_path = "your/config/path";
        $configs = require_once($file_path);

        array_walk_recursive($configs, function (&$config, $key) {
            $config = "your " . $key;
        });

        $string = var_export($configs,true);

        $new_config_file = <<<HEAD
    <?php
    return $string;
HEAD;

        file_put_contents($file_path, $new_config_file);
    }

so all you need to use reset_config() function before relasing the project

4 Comments

I need to say that, after using above function, new config file might be look like messy. So if you're using phpstorm, you can use the CTRL + ALT + L for reformat your codes (mean array)
Tingir I appreciate the answer but I can't get it to work. the "your ".$key; seems to be where I fail.
There are comments in the file that must remain. That's why I needed to use a find and replace method.
@user1730452 I'm trying in localhost right now, and it seems work as well without comments :/ But as you mentioned you need to make regex pattern if you want to keep comments
0

You can use this simple RegEx to match any line containing a key between the apostrophes:

'apiKey' => '[^']+'

The [^']+ will find one or more characters between single quotes. Just replace with your new line. Edit: Your replacement string would simply be:

'apiKey' => 'EnterYourAPIKeyHere' 

5 Comments

But I don't know what the actual key value is. All I know is that there is: 'apiKey'=>'?', - and a line break.
Yes, the new key is always 'EnterYourAPIKeyHere'
I guess I just can't wrap my head around how to use RegEx. Could you provide more detail?
Well, you asked about RegEx, so I answered showing using RegEx. RegEx is really too complicated for a comment here.
The issue is complicated. That's why I needed help. It MUST be done with some type of RegEx but there's one of my weaknesses. LOL. I thought it would only be a line or two of code. You have pointed me in the right direction.
0

I solved the issue by reading the file into an array and replacing the line with 'apiKey':

$array = file('app/config.php');
$string = "";
for($i = 0, $maxi = count($array); $i < $maxi; $i++)
{
    if(strpos($array[$i],'apiKey')>0){
        $string.="  'apiKey' => 'YourAppAPIKeyHere',\r\n\r\n";
    }else{
        $string.=$array[$i];
    }
}

It may not be the most elegant solution but it works. Until someone doesn't format their code right. For this reason, I would still like to use a RegEx that isolates the replacement to the required pattern. But RegEx is something I just don't get into, and there's other issues to resolve now.

Inspired by everyone who helped.

Feedback appreciated.

Comments

0

As i suggested you can use the PHP tokenizer extension functions to achieve your purpose

function replaceApiKey($configpath,$newKey='test',$newpath=''){
    if(file_exists($configpath)&&is_readable($configpath)&&is_file($configpath))
        $string = file_get_contents($configpath);
    else 
        return false;

    $tokens=token_get_all($string);
    $start=false;

    foreach($tokens as $key=>$token){
        if(is_array($token)&&stripos($token[1],'apiKey')){
            $start=true;
            $tokens[$key]=$token[1]; 
            continue;
        }
        if($start&&$token&&is_array($token)&&token_name($token[0])!=="T_COMMENT"&&token_name($token[0])!=="T_DOUBLE_ARROW"&&!ctype_space($token[1])){
            $token[1]=$token[1][0].$newKey.$token[1][strlen($token[1])-1];
            $start=false;
        }
        if(is_array($token)) $tokens[$key]=$token[1]; 
    }
    if(empty($newpath)) 
        $newpath=$configpath;
    if (file_put_contents($newpath, join('',$tokens)))

        return true;
    else
        return false;}

This function take in parameter the config path,tokenize the content then search and replace the old apiKey by the new one and save the changes in the new path...

6 Comments

This would loose the comments that must remain in the file. See original post.
the comment is kept in my test.You just don't test it right?
I'm sorry. I tested a lot of suggestions from here and from my colleagues. I was wrong. Yours did keep the comments but replaced the original file. However, with little modification I can see where it could just return the string leaving the original file intact (as desired).
if the code replace the original file it is because you didn't fill the newpath argument...Did you really test my code...?
I see... I did test your code. Right after you posted it and it failed with php error. It was copied and tested again right as we came up with the solution. Thats when we saw it replaced the original file. And since there was a solution, I just didn't move any further with it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.