Программное изменение конфигов CodeIgniter

9 246 просмотров 2 комментария 4 августа 2012

Делая все тот же сайт-каталог свадебной обуви, о котором я упоминал в прошлой статье, возникла необходимость в том чтоб в админке цены на товар вводились в одной валюте, а front-end показывал в другой валюте, следовательно курс конверсии периодически будет меняться и его надо где-то хранить, конечно можно хранить его в базе данных, включить кэширование и в целом норм будет, но мне захотелось хранить это значение в конфиг-файлах Codeigniter, с хранением проблем не возникло, но с изменением оказалось что не все так просто, в CodeIgniter предусмотрена установка элемента конфигурации, в контроллере или еще где-либо но эта функция не меняет сам файл, а мне нужно было именно это. В итоге ничего готового не найдя написал небольшую функцию, которую всунул в helper.

Функция сыровата, в ней практически нет никаких проверок, и она не умеет работать с массивами в конфигах, не ищет по всем конфигам, а для нее нужно указать имя конкретного конфига, но мне этого не надор было, и не было времени на различные проверки и переборы файлов, если кто-то допишет что-нибудь в нее и поделится я буду очень рад.

Сейчас я приведу пример который позволяет изменить конфиг файл CodeIgnniter используя php он будет основываться на том что  мне нужно с помощью формы изменить курс USD который записан у меня в config.php так:

$config['usd'] = 8000; //да, у нас в Беларуси курс примерно такой

Где-то в админ-панели у меня есть такая форма:

<div class="padding">
    <?
    echo form_open();
    $form[] = form_label('Курс USD:<br>', 'usd') . form_input('usd', $this->config->item('usd'));
    $form[] = form_submit('submit','Применить');
    echo ul($form);
    echo form_close();
    ?>
</div>

Для корректной работы этой формы необходимо загрузить помощники Form Helper и HTML Helper в контроллере или автозагрузке.

И контроллер обрабатывающий эту форму:

<?php
class Adm_settings extends MX_Controller
{

    function __construct()
    {
        parent::__construct();
    }

    function index($id = 0)
    {
        $this->load->helper('admin');
        if (count($_POST)) {
            if(change_config('config', 'usd', $_POST['usd'])) redirect(current_url());
            else echo 'Произошла ошибка';
        }
        echo $this->load->view('v_index');
    }
}
?>

Тут мы подключили хелпер admin в котором лежит функция change_config(), которая и меняет значения конфигов в файлах.

Ну и сама функция, для которой я создал отдельный хелпер, но ее можно переместить в любой другой более подходящий вам.

function change_config($file,$key,$value)
{
    $ci =& get_instance();
    $ci->load->helper('file');
    $file = './'.APPPATH.'config/'.$file.'.php';
    $string = read_file($file);

    $pattern = '/\$config\[\''.$key.'\']\s*?=s*?.*;/i';
    if(!is_numeric($value)) $value = "'$value'";
    $replacement = "\$config['$key'] = $value;";
    $text = preg_replace($pattern, $replacement, $string);
    if ( ! write_file($file, $text))
    {
        return false;
    }
    else
    {
        return true;
    }
}

Функция принимает 3 обязательных параметра, 1 название config-файла без .php в конце. Ключ элемента конфиг файла, в моем случае это usd и новое значение для этого ключа. После выполнения она возвращает либо TRUE либо FALSE, но возвращенное TRUE говорит только о том что не произошло ошибок с записью в файл, а не о том что все значение действительно найдено и изменено, поэтому нужно потом проверять на всякий случай значение в форме. Если третим параметром будет передана строка а не число то она будет обрамлена в одинарные кавычки. 

UPD

Как я недавно узнал, такой способ изменения конфигов является небезопасным, т.к. на файл надо по ходу ставить права такие чтоб эта функция не могла его изменить, следовательно надо искать другой способ хранения таких конфигов. 

2 комментария

Я приспособил для конфигов сайта(не приложения), хранение в ini файлах. Библиотека Config_ini. Пока нравится.
Спасибо, тоже думал про них, позже посмотрю че там как, а для этого проекта и так пойдет) Никто его ломать там не будет)

Вы можете оставить комментарий