dougu9895 2015-09-11 15:59
浏览 52
已采纳

通过引用返回更改CodeIgniter数据库配置

I'm trying change the database config at execution time in CI. I've had a little progress,but here we use 3 database managers: ActiveRecord(native from CI),Lumine(a small and old ORM) and Doctrine. I'll try explain better.

In CI exists a database static config file,called database.php. In that file you put the configs,in a matrix format:

$db['config_group']['username']
$db['config_group']['password']

Well,I had to create a Class to generate and return that configuration. So I found a way that I could change it dinamically:

DatabaseClass

Then in the database.php I call it:

$database = DatabaseManager::initDatabase('address',"user","db");
$active_record = &$database->getActiveRecord();
$active_group  = &$database->getActiveGroup();
$db = &$database->exportConfigCI();

Full database.php file

Fine! It makes and exports the config for me. Note that I call it with return by reference. Now, it's the time to change it. I have to make a change in the user of DB, according to the type of user logged. So I build a hook of type post_controller_constructor.

Hook to change DB config

The problem: The reference is lost in the middle of the process. No matter how I try, I can't change the values of CI->db object(the object that holds the database attributes). By polymorphism(how I show in the hook) I can do that, but only to ActiveRecord. The others ORM's are based on database.php file. Here I need of return by reference, to change all dependencies linked at database config file.

Doctrine and Lumine config files are linked to the same database.php from CI.

Lumine config file

Doctrine config file

What am I missing? It's possible do what I want?

  • 写回答

2条回答 默认 最新

  • dongzen7263 2016-06-04 20:39
    关注

    I found a solution and now I had enough time to elaborate an answer. As I said,I needed change the DB core config for multiple db managers linked to CI database config file (Doctrine,Lumine and CI active record itself). The main problem was that once loaded,the CI database object holds its state immutable. Said that,if you need change the db user or other attribute at execution time,it will not work by just calling the $CI->db object and changing it.

    The solution:

    Create a class to manage and export all the configs from db,access the attributes and methods and return by reference.

    How it works,in simple steps?

    The database config file has became a class. That class,as I said,manages and exports the db attributes returning by reference,in the array format from CI.

    DatabaseClass

    In the ORM's configuration files linked to CI db file,a call by reference is made as well.

    $user = &$database->getUsername();
    $pass = &$database->getPassword();
    

    DoctrineConfigFile

    The same happens to the Lumine file.

    Changing the configs at execution time

    To change the db user at execution time,a post_controller_construct hook has been created. The hook checks the user mode(superuser: can view the system as other user - or a normal user) at every request. If the user is a superuser,him can view and use the system as other user,but cannot realize some operations,like inserts and deletes. The hook then make the changes,getting the attributes values from the Database class,and switching the user db by a user without permissions to perform such actions.

    Something like this:

        $CI =& get_instance();
        $database = DatabaseManager::initDatabase();
        $user = &$database->getUsername();
        $active_group = &$database->getActiveGroup();
        $active_group = "vision_group";
        $user = "vision_user";
    

    Then,change the values linked too:

        $referencePass = "my-encrypted-and-encapsulated-pass-for-user-vision";
    
        //lumine management
        $LumConnManager = Lumine_ConnectionManager::getInstance();
        $LumConfList = $LumConnManager->getConfigurationList();
        $lumineConfig = current($LumConfList);
    
        $lumineConfig->connection->setPassword($referencePass);
        $lumineConfig->connection->setUser($user);
    

    And finally,overriding the original DB Object from CI:

       $dbObject = DB($active_group);
       $CI->db = $dbObject;
    

    ChangeDatabaseHook

    As Doctrine doesn't have a deep chain for this configuration,his values are changed just by the reference.

    It's important note that the active_group parameter defines the configuration group. By this reason,we have to deal with two groups. The default group and the 'limited group',and then override the default object with a object that holds the new active group - the group with restrictions to perform actions on database.

    We just need to change the user,pass and group params. Others configurations still the same.

    The PHP docs provides more information about returning references.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表