2009-10-31 80 views
3

我试图写有CakePHP的web应用程序,像大多数web应用,我想创建检测数据库是否已初始化安装程序,如果没有,执行安装过程。自动化数据库表的创建

此过程将完全自动化(假定数据库本身已存在,并且通过匿名帐户授予完全管理访问权限,不需要密码......这是针对沙箱环境的,因此不用担心安全问题) ,所以如果数据库表已经被创建和初始化,它就需要能够检测到(不管请求!),如果没有,则透明地执行初始化,然后提供用户的原始请求。

我认为写了一种Bootstrap控制器,通过它来路由所有的请求,并且运行一个SQL查询来确定数据库表是否存在,但这看起来很麻烦(并且控制器需要一个相应的模型,这里就是这种情况)。另一种可能性是重写AppModel并在其中放置相同的测试,但我不确定如何执行此操作,因为这些行中没有任何文档。

在此先感谢!

tl; dr版本:什么是J2EE servlet的“init()”方法的CakePHP等价物(或者如何编写用于CakePHP的等价物)?

回答

3

退房的AppError类 - 可能是有,你可以重写,并从那里运行创建数据库表的SQL缺少数据库表的错误?

+0

这实际上正是我正在研究的内容 - 要么将错误页面中的链接提供给将自动填充表格的脚本,要么只是在错误类中进行,如果这是生成的错误。谢谢! – Magsol 2009-10-31 20:52:24

+0

@Magsol你究竟是怎么实现这个的?我很好奇。 – khany 2014-05-30 09:38:14

+0

很难确定 - 这是前一段时间 - 但我确信我创建了一个AppError类,并用代码覆盖missingTable错误函数以生成数据库模式。拿一点盐吧:我怀疑CakePHP在5年内发生了很大变化! – Magsol 2014-05-30 15:37:09

2

你真的想数据库存在每个请求核查?这似乎非常浪费。

它会检查它会建立数据库,然后下一个万个请求它将再次,即使该数据库具有当然的这个时候,设立了检查每个人的第一次!

这是一个更好的主意,要求任何人安装您的应用程序做一些设置。您应该在每次请求期间提供一个单独的脚本,该脚本的执行时间为,而不是,但在安装期间由该人员手动运行。


重新您对使用CakePHP做到这一点的最好办法评论,有你看着蛋糕的数据库架构迁移的支持?

http://book.cakephp.org/view/734/Schema-management-and-migrations

+0

我非常喜欢那个;我想我正在寻找一个J2EE servlet的“init()”方法的CakePHP等价物,如果这样的事情存在或可以写的话。尽管单独的脚本也可以工作,但是仍然需要在主应用程序中检查数据库表是否存在,如果不存在,则建议用户运行该脚本。 – Magsol 2009-10-31 04:55:50

+0

我认为针对不存在的表的任何查询都会很好地揭示这一事实。 – 2009-10-31 05:21:21

+0

看,我这里的重点是我不熟悉CakePHP框架。我了解网络编程的原则和范例;我只是不确定如何在CakePHP环境中实现它们。在这方面的任何建议是我正在寻找的。 – Magsol 2009-10-31 14:40:31

2

像这样的事情可能会做你要找的东西,但确实需要每个模型的额外查询。

<?php 
class AppModel extends Model { 
    var $create_query = false; 

    function __construct($id = false, $table = null, $ds = null) { 
     parent::__construct($id, $table, $ds); 

     if (!empty($this->create_query)) { 
      $this->query($this->create_query); 
     } 
    } 
} 
?> 

然后,您只需要在模型中添加var $create_query = 'CREATE TABLE IF NOT EXISTS ...;`。 MySQL CREATE TABLE documentation有关于IF NOT EXISTS的更多信息。

但是,我不确定这是不是试图调用查询()太早。或前检查,看看表已经存在,它会是。否则,CakePHP会出错而不是创建表。关于这个主题没有太多的文档,你最好直接去看看cake/libs/model/model.php的更多信息。

更新:上面的代码所写是行不通的。

在深入研究Model类后,Model :: __构造调用Model :: setSource()。 Model :: setSource()检查表是否存在,如果不存在则抛出错误。要使用此方法,那就是您必须重写并插入查询的位置。下面的代码可能需要不同,具体取决于您使用的CakePHP版本。

<?php 
function setSource($tableName) { 
    // From Model::setSource(). I believe this is needed to make query() work. 
    $this->setDataSource($this->useDbConfig); 

    // Create our table if we have a create query 
    if (!empty($this->create_query)) { 
     $this->query($this->create_query); 
    } 

    // Now call the parent 
    parent::setSource($tableName); 
} 
?> 
1

我曾想过在某个时间点做这件事,并提出了一个很好的方法来做到这一点。

首先,注意:我相信你的应用程序需要写访问app/config/database.php,所以你可以写出正确的信息。我有一个解决方法,但让我解释安装程序的工作方法。

PHP脚本可以自己重写自己(或删除自己)。由于脚本被加载到内存中,并且字节码被执行,所以一旦它完成工作,它就不依赖于文件。所以理论上你可以拥有一些重写AppError类来运行一个特定的控制器(比如你的SetupWizardController)和所有常规CakePHP的东西。一旦你经历了整个向导,写下其他所需的database.php文件/设置,覆盖AppError和AppController文件(我可以看到你需要AppController以不同的方式工作,如果应用程序未在某些情况下安装)那些存储在app/vendors/myapp中的地方。该脚本已完成执行,现在您的检查不会在后续运行中发生。

这将摆脱比尔卡尔文提出的问题,利用AppError,并使安装程序。

另一种方法是在应用程序中包含环境的概念。假设你将你的环境存储在app/config/environment.php中。该文件将被授予写入权限(并且该权限将在安装结束时被删除),或者可能被覆盖。无论如何,只要有人试图部署应用程序,它就会存在,并且database.php会自动从environment.php文件导入数据库。然后,database.php类的构造函数将使用environment.php中指定的那个覆盖它的$ default数据库。 database.php中的$ default将引用一个NoDB数据源,您可以在AppController中检查它(我认为您可以实例化一个虚拟模型并检查它的数据源),然后推送所需的安装程序。显然你也可以在这之后覆盖AppController。