Can anyone help me ?
How can I configure the CI database settings programmatically ? I saw this with other systems like OSCommerce, Joomla,开发者_Go百科 Wordpress etc..
The user needs to submit a form with database information.
I found two solutions for this although one I have not yet tested.
There are a lot o projects based on the Codeigniter framework that have some sort of installer. Like "Repox" wrote, you can find this in MojoMotor, there is a core/Config.php extension class that handles this specific task, also Expression Engine has this. Sadly those are under commercial license and cannot be used.
One free application that uses such solution is Ionize CMS.
Take a look at this class: https://github.com/ionize/ionize/blob/master/install/class/Config.php
The second one is in a spark called "files". You can find it here: http://getsparks.org/packages/files/versions/HEAD/show
The obvious limitation to that is that it rewrites the config file.
This was pointed out somewhat even in "codeigniter github issue 1058" (google that for link) but sadly the developers decided to close it.
Personally I don't understand why such a feature is not implemented in the framework, it could not only be used to edit the config file at install time but also it could be used in a control panel.
Since there is no automated CI installer like those for Joomla, Wordpress, etc. it is not possible. So, if you need such an opportunity, you'll have to create such an installer yourself. If you do, don't forget to share it with the community.
This is actually a pretty complicated process.
MojoMotor which is based on CI has an installation script which makes the additions to application/config/database.php
which means it's not impossible.
The license agreement for MM prohibits me from posting the actual installation script, but you should be able to create something that works.
Otherwise, imagine something like this:
// Data from user input
$db_config['hostname'] = $this->input->post('db_host');
$db_config['username'] = $this->input->post('db_user');
$db_config['password'] = $this->input->post('db_password');
$db_config['database'] = $this->input->post('db_name');
$db_config['dbdriver'] = $this->db_driver;
$db_config['dbprefix'] = $this->db_prefix;
$db_config['pconnect'] = ($this->input->post('pconnect')) ? TRUE : FALSE;
$this->CI =& get_instance();
$this->CI->load->helper('file');
$prototype = array(
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => '',
'dbdriver' => 'mysql',
'dbprefix' => 'mojo_',
'pconnect' => TRUE,
'db_debug' => FALSE,
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci'
);
// Now we read the file data as a string
$config_file = read_file(APPPATH.'config/database'.EXT);
// Dollar signs seem to create a problem with our preg_replace
// so we'll temporarily swap them out
$config_file = str_replace('$', '@s@', $config_file);
// Cycle through the newconfig array and swap out the data
if (count($dbconfig) > 0)
{
foreach ($dbconfig as $key => $val)
{
if ($val === 'y')
{
$val = TRUE;
}
elseif ($val == 'n')
{
$val = FALSE;
}
if (is_bool($val))
{
$val = ($val == TRUE) ? 'TRUE' : 'FALSE';
}
else
{
$val = '\''.$val.'\'';
}
$val .= ';';
// Update the value
$config_file = preg_replace("#(\@s\@db\[(['\"])".$active_group."\\2\]\[(['\"])".$key."\\3\]\s*=\s*).*?;#", "\\1$val", $config_file);
}
}
// Put the dollar signs back
$config_file = str_replace('@s@', '$', $config_file);
// Just to make sure we don't have any unwanted whitespace
$config_file = trim($config_file);
// Write the file
$fp = fopen($this->database_path, FOPEN_WRITE_CREATE_DESTRUCTIVE);
flock($fp, LOCK_EX);
fwrite($fp, $config_file, strlen($config_file));
flock($fp, LOCK_UN);
fclose($fp);
I haven't tested this, but I'm trying to implement something like similar to one of my own projects.
I hope this could bring you a little closer.
That approach should be fine. All you need to do is avoid autoloading the DB library in the autoload.php file as it will throw an error everytime you try to load a page otherwise.
$autoload['libraries'] = array(<strike>'database',</strike> 'form_validation', 'cart','session');
You can then have a MY_Controller which has:
function __construct()
{
$this->load->database();
}
You can then extend this to all the controllers that require DB access making sure to exclude the one that the setup runs from.
精彩评论