views:

84

answers:

7

I have a config.php file for one of my site which holds information needed to run the site. It somewhat looks like this:

<?php

$site_name="The Site";
$base_url = "http://site.com";
$upload_path = "/images";

?>

Getting the values from that is easy, I just use require 'config.php'; but how can i give an option to add this from a html form? Means how can i update the values? One of the way i have in mind is using fopen and fsave, somewhat like this:

<?php
$filename = 'config.php';
$somecontent = "config here";


if (is_writable($filename)) {


    if (!$handle = fopen($filename, 'w')) {
         echo "Cannot open file ($filename)";
         exit;
    }

    // Write $somecontent to our opened file.
    if (fwrite($handle, $somecontent) === FALSE) {
        echo "Cannot write to file ($filename)";
        exit;
    }

    echo "Success, wrote ($somecontent) to file ($filename)";

    fclose($handle);

} else {
    echo "The file $filename is not writable";
}
?>

But is this the standard way to do this? Is this how all those cms write their config file?

A: 

I imagine that's how the admin panel of most CMSes would allow you to write directly to the config file, but:

  • You should make absolutely sure that the submitter is authenticated as an administrator before doing this.
  • REGISTER_GLOBALS should preferably also be turned off, although that's more of a general security concern than something specifically related to this.
David
what register globals has to do here?
Col. Shrapnel
+2  A: 

Writing into .php file is not a good idea at all. Better to store your config in database, .ini file or xml file. Using this "storages" for config make it really easy to read and write.

Attention: please note that you should put .ini, .xml files out from your document root directory to avoid accessing it from web.

Also, I advise you to check Zend Config http://framework.zend.com/manual/ru/zend.config.html to see how writing to config is implemented in OOP MVC framework.

Kirzilla
one little problem. you cannot store in the database your db credentials %)
Col. Shrapnel
+3  A: 
MartyIX
@MartyIX: +1 i should have suggested the same, ini way is nice way to go.
Sarfraz
The main problem with ini-files is, that they are public accessible via http. Suppose the config.ini is placed in the web-root, everybody can request http://www.domain.com/config.ini and read out your passwords. If you take a php-file instead you get an empty page because the php-file got no output.I know, there are possibilites of protecting the ini-file from downloading, but if you deploy a project you cant be sure it works, so I wouldn't take ini-files.
theomega
@theomega: You can move the file outside of document_root then.
MartyIX
That will work if you write the program for your own server, but if you start to deploy it to customers, perhaps even as open source it gets really difficult: You can't be sure that the user actually can access something out of the docroot. And, its hard to detect where to put the file. I only wanted to explain while nearly every OpenSource-PHP-Project I know writes the config to a php-file. There are of course better solutions but they are not as portable.
theomega
+1 to theomega and also note my answer which is as safe as any text file-based one.
Col. Shrapnel
@theomega: I don't have any own server and the first or the second possibility could always be used (I've tried five web-hostings so far; but maybe I was lucky). It seems to me that check out if the htaccess file works for config.ini is not so hard - why you can't be sure that it works?
MartyIX
I don't want to use ini file because my project is targeted to an audience that don't know server side stuffs and more over will be opensourced. So i don't think ppl would probably even consider about putting the config.ini somewhere else, they may not even know what htaccess is. And i believe the project should be secure without the user securing it. Security should come from the developer mainly when its opensource and given free to non-technical users. Thank You Very Much.
esafwan
esafwan: This should be probably written in your question.
MartyIX
+4  A: 
$cfg['sitename'] = $_POST['sitename'];

$file     = "config.php";
$contents = "<?php\r\n\$cfg=".var_export($cfg,1).";\r\n?>";

file_put_contents($file,$contents);
Col. Shrapnel
+1 for pointing out the `file_put_contents` method as a short-cut.
theomega
+1 for using `var_export` - @theomega see my answer in the linked duplicate for a more sophisticated and reusable version.
Gordon
these are just a syntax surar. while the whole concept is way more important IMO. It is as safe as it can be. A user can change only variable contents and nothing else
Col. Shrapnel
I would prefer this one, because my project will be open sourced after a private beta and more over the projects targeted audience is webdesigners who don't know server side stuffs... thanx.
esafwan
+1  A: 

You can use create a template for config.php using a template engine, e.g. Smarty

config.tpl

<?php
     // DB Settings
     $db_host = "{$db->host}";
     $db_user = "{$db->user}";
     $db_password = "{$db->password}";
     ...

And use Smarty to render the config.php for you and capture the output and save to the real config file.

<?php
      $smarty->assign('db', $db);
      $output = $smarty->fetch('config.tpl');
      // ...save the output into config.php

The advantage in using this approach is you can separate the layout and content of your config file, e.g. you can add extra comments in the config file, or arrange the item's order easily.

Also, using this approach, you can easily move to other formats such as INI or XML format, as suggested by others.

tszming
not too clear solution.
Col. Shrapnel
A: 

My suggestion from personal experience would be to keep the most basic stuff in the config file (database connection) and everything else in a database table. You should always try to keep away from writing stuff on the server unless you really have to otherwise you will run into permission problems, security issues ans so on...

It's getting biggie when you want to distribute scripts like this.

The rest, is pretty similar to the above answer:

<?php
$config = "<?php\r\n";

$file     = "/path/to/config.php";

foreach ( $_POST [ 'config' ] as $config_label => $config_value ):
    $config .= "$$config_label = '{$config_value}'\r\n";
endforeach;

file_put_contents($file,$config);

Good luck.

Ian Roberts
still not so clear and even dangerous solution
Col. Shrapnel
I'm starting to feel Col. Shrapnel is the op here and not someone else.
Ian Roberts
That's simple. I am only one who cares. Not just write an answer and wait for reputation points. But I am thinking of what I see. Of the stuff I am or others do. I know it's very unusual behavior, but I can't help it. So, to possible flaws in your code. Not to mention malicious user of this script (it would be a paranoia) but at least presence of `'` or \ symbols in the password is quite possible. That's why `var_export` is preferred.
Col. Shrapnel
+1  A: 

I've been using tszming's template solution for a while and it works fine - provided you're already at ease with Smarty or other templating systems, otherwise it might be too much effort just for saving your config.

A simpler solution is to have all configuration options in an array, and keep it in a file encoded as JSON. At the start of each script you file_get_contents() and json_decode() the settings file into the array. Any time you want to save the current options you json_encode() the options array and write to the settings file with file_put_contents(). This allows PHP to read and write the configuration with minimal fuss, but you're still able to edit it with a text editor should need arise.

djn