在没有数据库连接的情况下实例化ActiveRecord模型

时间:2017-07-06 14:45:56

标签: php oop model-view-controller model phpactiverecord

我目前正在使用php-activerecord替换自制的hack-y MVC方法的模型组件。我有一个单独的页面,在数据库服务器关闭的情况下显示,该页面用于显示具有访客头像,名称和角色的用户徽章。代码如下:

match[0] = "<b>STATUS:</b> Cancel"
match[1] = "<b>STATUS:</b> Cancel"
当用户登录时,

if (Auth::$signed_in) echo Auth::$user->getAvatarWrap(); else echo (new \App\Models\User([ 'name' => 'Guest', 'role' => 'guest', 'avatar_url' => GUEST_AVATAR ]))->getAvatarWrap(); 设置为Auth::$signed_in,如果数据库中断,则不可能,因此true分支将使用预定义数据执行。< / p>

Pre-ActiveRecord这只会将属性添加到对象中,对else方法的调用将毫无问题地执行。现在,由ActiveRecord控制模型,无论出于何种原因,都会发生一组额外的调用。这可能是因为模型已经定义了关系,但我不确定。

getAvatarWrap

当我知道它找不到连接时,我如何告诉ActiveRecord停止寻找连接,并且它应该满足于我提供的数据?在停电期间,我是否必须挥手告别使用我的任何型号?

1 个答案:

答案 0 :(得分:0)

感谢a comment我发现了SQLite内存数据库,这些数据库让我走上了成功的道路。鉴于支持这种数据库的pull request已经收集了近一年的灰尘,我决定自己动手。
如果您稍后再阅读此内容,请务必检查所述PR是否已合并,如果有,请发表评论以便我可以更新此答案。

首先,我在GitHub上分叉了original repository存储库。我故意没有链接我的分叉,因为它最终会过时或删除,所以我建议你自己做一个分叉。然后,我使用了this answerthis answer的组合,从PR的提交者的分支中将魔法分支放入我的分支。您可以按下&#34;克隆或下载&#34;来获取<url>。分叉存储库主页上的按钮。

$ git clone <url>
$ git remote add target https://github.com/claytonrcarter/php-activerecord.git
$ git fetch --all
$ git checkout master
$ git merge --squash target/sqlite-memory-support
$ git commit -m "Add support for SQLite :memory: databases"
$ git push

现在我的fork已经对我的项目composer.json进行了最新更改,并将php-activerecord/php-activerecord块中的require版本更改为"dev-master",然后用我的前叉添加了一个repositories块。再次,使用fork的克隆URL替换<url>

{
    // ...
    "require": {
        // ...
        "php-activerecord/php-activerecord": "dev-master",
        // ...
    },
    "repositories": [
        {
            "type": "vcs",
            "url":  "<url>"
        }
    ]
}

但等等,这种乐趣并没有结束!现在我们已经支持内存SQLite DB适配器,我们实际上必须定义它。所以修改初始化配置:

ActiveRecord\Config::initialize(function ($cfg){
    $cfg->set_connections([
        'pgsql' => 'pgsql://'.DB_USER.':'.DB_PASS.'@'.DB_HOST.'/database?charset=utf8',

        // Add this line below. 'failsafe' can be changed to something else, of course
        'failsafe' => 'sqlite://:memory:',
    ], 'pgsql');
});

原来它pretty difficult热交换默认连接,所以我做了下一个最好的事情,并创建了一个将$connection设置为之前定义的failsafe。请注意,必须手动定义必填字段,因为lib无法知道允许您从空数据库使用哪些字段。有趣的是,主类上出现的$has_many和类似关系对子类没有负面影响。行为,所以我可以保持相对较短。

namespace App\Models;

/** @inheritdoc */
class FailsafeUser extends User {
    static $connection = 'failsafe';

    public $name, $role, $avatar_url;
}

最后,我不得不改变调用以使用新定义的类:

if (Auth::$signed_in)
    echo Auth::$user->getAvatarWrap();
else echo (new \App\Models\FailsafeUser([
    'name' => 'Guest',
    'role' => 'guest',
    'avatar_url' => GUEST_AVATAR
]))->getAvatarWrap();

低,看,脚本不再中断,我终于可以继续使用我的代码库的ActiveRecord -ification。如果您想亲自经历这种折磨,并拥有多个模型,您希望拥有一个&#34;离线&#34;那么你可能想要创建一个类型的抽象类来自动设置你在构造函数中传递的属性以及预先设置$connection,从而使子实例变得更加冗长。