您如何在 Zend Framework 中使用关系数据库? [英] How do you work with a relational database in Zend Framework?

查看:23
本文介绍了您如何在 Zend Framework 中使用关系数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 zend 框架编写应用程序,但在使我的关系数据库模型正常工作时遇到了很多问题.我已经多次阅读快速入门和文档,但我仍然不确定如何执行此操作.我张贴了所涉及的不同表格之间关系的图片,以避免解释所有内容,因为英语不是我的第一语言,而且当我试图解释......非常复杂的事情时,我往往不会把自己说清楚.

I'm using the zend framework to write an app and I'm having lots of problems getting my relational database models to work. I've read the quickstart and the docs several times and I'm still not sure how to do this. I post a picture of the relationships between the different tables involved to avoid having to explain everything since English is not my first language and I tend not to make myself clear when I try to explain...well complex things.

在名为 planilla_users 的表中,press_releases、social_networking、blog_posts、rss_feed、directory、users 和 articulos 表都设置为外键.我按照快速入门显示的方式对表格模型进行了编码:

The tables press_releases, social_networking, blog_posts, rss_feed, directorios, users and articulos are all set as foreign keys in the table named planilla_users. I coded my table models the way the quickstart shows:

class Application_Model_DbTable_PlanillaUsers extends Zend_Db_Table_Abstract
{

protected $_name = 'planilla_users';
protected $_referenceMap = array(
    'User' => array(
        'columns' => 'users_id',
        'refTableClass' => 'Application_Model_DbTable_Users',
        'refColumns' => 'id'
    ),
    'Articulo' => array(
        'columns' => 'art_id',
        'refTableClass' => 'Application_Model_DbTable_Articulos',
        'refColumns' => 'id'
    ),...etc

...其余的格式如下:

...and the rest following the format of:

class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{

protected $_name = 'users';
protected $_dependentTables = array('Application_Model_DbTable_PlanillaUsers'); 

我还有一个模型 Planilla.php,其中包含用于存储/更新/检索/删除信息的所有 setter 和 getter,...但是...我对如何处理映射器完全空白.我不知道它应该如何工作,老实说,我还没有找到一个很好的例子来说明如何做这样的事情.因此,我们将不胜感激任何帮助.

I also have a model Planilla.php with all the setters and getters for the information to be stored/updated/retrieved/deleted,...however...I'm completely blank on what to do with the mapper. I don't know how it's supposed to work and I honestly haven't found a good example on how to do something like this yet. So any help would be mostly appreciated.

推荐答案

我给你的建议是看看 Doctrine,它是一个对象关系映射器,可以很好地与 ZF 集成.我个人使用 1.2 版和 ZF 1.11.4 没有问题.

My advice to you would be to have a look at Doctrine, it is an object relational mapper which can intergrate quite nicely with ZF. I personally use version 1.2 with ZF 1.11.4 with no problems.

有一个不错的屏幕投射 here 解释了如何将 Doctrine 插入 ZF.学说可能有点像猪,但一旦你理解了它,从长远来看,它会节省你的时间.Doctrine 还附带一个命令行脚本,可用于将数据库反向工程为 Doctrine 类.如果您在数据库上设置了关系,那么 Doctrine 也可以选择.

There is a nice screen cast here which explains how to intergate Doctrine into ZF. Doctrine can be a bit of a pig to to learn but once you understand it, it will save you time in the long run. Doctrine also comes with a command line script which can be used to reverse engineer databases into Doctrine classes. If you have the relations set on the database then Doctrine can pick that up too.

我还听说 ZF 2 将包含 Doctrine 2.0.

I also hear that ZF 2 will have Doctrine 2.0 included.

我用来创建 Doctrine 类的方法是首先在你的 appication.ini 文件中设置 Doctrine,在生产标题下的某处添加这些行.

The method I use to create the Doctrine classes is to first setup doctrine in your appication.ini file, add these lines somewhere under production header.

[production]

//...

; Doctrine settings
pluginpaths.Freedom_Zend_Application_Resource = "Freedom/Zend/Application/Resource"
resources.doctrine.connection_string = "mysql://username:password@localhost/database_name"
resources.doctrine.compiled = false ; use compiled version of Doctrine
resources.doctrine.cache = false ; use query cache

; Information required for models generator
resources.doctrine.models_path = APPLICATION_PATH "/modules/default/models/Doctrine"
resources.doctrine.module_directories[] = APPLICATION_PATH "/modules/default/models/Doctrine/base"  
resources.doctrine.module_directories[] = APPLICATION_PATH "/modules/default/models/Doctrine"

; Generator settings
resources.doctrine.generate_models_options.phpDocPackage = Your App Name
resources.doctrine.generate_models_options.phpDocSubpackage = Doctrine
resources.doctrine.generate_models_options.phpDocName = Your Company Name
resources.doctrine.generate_models_options.phpDocEmail = your@email.address
resources.doctrine.generate_models_options.pearStyle = true
resources.doctrine.generate_models_options.generateTableClasses = true
resources.doctrine.generate_models_options.generateBaseClasses = true
resources.doctrine.generate_models_options.classPrefix = "Model_Doctrine_"
resources.doctrine.generate_models_options.baseClassPrefix = "Base_"
resources.doctrine.generate_models_options.baseClassesDirectory =
resources.doctrine.generate_models_options.classPrefixFiles = false
resources.doctrine.generate_models_options.generateAccessors = false
//...

您会注意到顶部有一条线pluginpaths.Freedom_Zend_Application_ResourceFreedom 是我库中的通用命名空间(请参阅下面的文件夹树).我在这里有一个 Zend 文件夹,我可以在其中放置额外的 ZF 代码,这包括在需要时覆盖现有的 ZF 函数.Freedom 是我的公司名称,你的显然会有所不同.此行需要更改为您公司的名称,例如 pluginpaths.Yourcompany_Zend_Application_Resource = "Yourcompany/Zend/Application/Resource"

You will notice a line at the top pluginpaths.Freedom_Zend_Application_Resource Freedom is my generic namespace in my library (see folder tree below). I here I have a Zend folder where I can place my extra ZF code, this includes overiding existing ZF functions if required. Freedom is my company name, yours will obviously differ. This line will need to change to your company's name, for example pluginpaths.Yourcompany_Zend_Application_Resource = "Yourcompany/Zend/Application/Resource"

下一行是您放置数据库连接设置的位置 resources.doctrine.connection_string = "mysql://username:password@localhost/database_name"

The next line is where you place your database connection settings resources.doctrine.connection_string = "mysql://username:password@localhost/database_name"

接下来的三行:

resources.doctrine.models_path = APPLICATION_PATH "/modules/default/models/Doctrine"
resources.doctrine.module_directories[] = APPLICATION_PATH "/modules/default/models/Doctrine/Base"  
resources.doctrine.module_directories[] = APPLICATION_PATH "/modules/default/models/Doctrine"

告诉Doctrine在哪里放置生成的类,因为我使用模块化设置这些进入我的application/modules/default/models/Doctrineapplication/modules/default/models/Doctrine/Base 分别(见下面的文件夹树).

tell Doctrine where to place the classes generated, as I am using a modular setup these go into my application/modules/default/models/Doctrine and application/modules/default/models/Doctrine/Base respectively (see folder tree below).

还有一些其他行需要更改,这些应该是不言而喻的.

There are some other lines that will need changing, these should be self evident.

您还需要在 application.ini 的开发标题下添加以下几行.

You will also need to add the following lines under the development heading in your application.ini.

[development : production]

//...

; phpSettings
resources.doctrine.compiled = false ; use compiled version of Doctrine
resources.doctrine.cache = false ; use query cache

//...

您还需要资源文件 Doctrine.php.它的位置取决于您的设置,我的如下.

You will also need the resource file Doctrine.php. Where this is located depends on your setup, mine is as follows.

-Application
  -configs
  -layouts
  -modules
    -default // ZF default controller
      -controllers
      -models
        -Doctrine // folder for you generated classes
          -Base // Do not change the files in this folder
    -views
      -scripts
-Library
  -Doctrine // the doctrine application as downloaded
   doctrine-cli.php // you will need to create this (see below)
   Doctrine.php // come with the doctrine application
  -Freedom // my generic namespace, shared across multiple apps
    -Zend // place to overide/add ZF classes
      -Application
        -Resource
          *Docrine.php // the file below
  -Zend // ZF 1.11.4 (yours may differ)
  -ZendX // ZF extras

*Doctrine.php 文件如下(显然忽略*!!)

The *Doctrine.php file is as follows (obviously ignore the *!!)

/**
* Doctrine application resource
*
* @author Juozas Kaziukenas (juozas@juokaz.com)
*/
class Freedom_Zend_Application_Resource_Doctrine extends Zend_Application_Resource_ResourceAbstract
{
    /**
* Initialize
*/
    public function init()
    {
        $doctrineConfig = $this->getOptions();

        if (isset($doctrineConfig['compiled']) && $doctrineConfig['compiled'] == true &&
            file_exists(APPLICATION_PATH . '/../library/Doctrine.compiled.php'))
        {
            require_once 'Doctrine.compiled.php';
        }
        else
        {
            require_once 'Doctrine.php';
        }
        $loader = Zend_Loader_Autoloader::getInstance();
        $loader->pushAutoloader(array('Doctrine_Core', 'autoload'), 'Doctrine');

        $manager = Doctrine_Manager::getInstance();

        // set models to be autoloaded and not included (Doctrine_Core::MODEL_LOADING_AGGRESSIVE)
        $manager->setAttribute(
            Doctrine_Core::ATTR_MODEL_LOADING,
            Doctrine_Core::MODEL_LOADING_CONSERVATIVE
        );

        // enable ModelTable classes to be loaded automatically
        $manager->setAttribute(
            Doctrine_Core::ATTR_AUTOLOAD_TABLE_CLASSES,
            true
        );

        // enable validation on save()
        $manager->setAttribute(
            Doctrine_Core::ATTR_VALIDATE,
            Doctrine_Core::VALIDATE_ALL
        );

        // enable accessor override
        $manager->setAttribute(
            Doctrine_Core::ATTR_AUTO_ACCESSOR_OVERRIDE,
            true
        );

        // enable sql callbacks to make SoftDelete and other behaviours work transparently
        $manager->setAttribute(
            Doctrine_Core::ATTR_USE_DQL_CALLBACKS,
            true
        );

        // enable automatic queries resource freeing
        $manager->setAttribute(
            Doctrine_Core::ATTR_AUTO_FREE_QUERY_OBJECTS,
            true
        );

        // connect to database
        $manager->openConnection($doctrineConfig['connection_string']);

        // set to utf8
        $manager->connection()->setCharset('utf8');

        if (isset($doctrineConfig['cache']) && $doctrineConfig['cache'] == true)
        {
            $cacheDriver = new Doctrine_Cache_Apc();

            $manager->setAttribute(
                Doctrine_Core::ATTR_QUERY_CACHE,
                $cacheDriver
            );
        }

        return $manager;
    }
}

接下来,您需要创建 Doctic-cli.php 文件来引导您的应用程序,它应该位于您的库文件的根目录中(请参见上面的树),我的文件如下.

Next you will need to create the doctrine-cli.php file to bootstrap your application this should be located in the root of your library file (see tree above), mine is as follows.

/**
 * Doctrine CLI script
 *
 * @author Juozas Kaziukenas (juozas@juokaz.com)
 */

define('APPLICATION_ENV', 'development');
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../your/application'));

set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    './',
    get_include_path(),
)));

require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$application->getBootstrap()
        ->bootstrap('doctrine')
        ->bootstrap('autoload');

// set aggressive loading to make sure migrations are working
Doctrine_Manager::getInstance()->setAttribute(
    Doctrine::ATTR_MODEL_LOADING,
    Doctrine_Core::MODEL_LOADING_AGGRESSIVE
);

$options = $application->getBootstrap()->getOptions();

$cli = new Doctrine_Cli($options['resources']['doctrine']);

$cli->run($_SERVER['argv']);

唯一需要更改的行是

define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../../your/application'));

所以它指向您的应用程序的根文件夹,类似于您的公共文件夹中 index.php 文件中的行.

so it points to your application's root folder, similar to the line in your index.php file in your public folder.

现在希望您应该准备好生成您的数据库类文件.转到终端窗口并输入以下内容.

Now hopefully you should be ready to generate your database class files. Goto a terminal window and entrer the following.

cd /home/path/to/library
php doctrine-cli.php generate-models-db

如果一切顺利,application/modules/default/models/Doctrineapplication/modules/default/models/Doctrine/Base 文件夹应该包含你的数据库.正如我上面提到的,不要更改 Base 文件夹中的文件,您可以使用父 Doctrine 文件夹中的类进行更改.您还会注意到 Doctrine 文件夹中的每个数据库表有两个类,一个以 Table 为后缀.在这里,我倾向于放置我的 DQL 代码以使其远离我的模型/控制器.其他类可用于更改基文件夹中的类,您也可以在此处添加钩子和侦听器以添加表特定代码,例如添加密码加密或预设日期等.

If all has gone well the folders application/modules/default/models/Doctrine and application/modules/default/models/Doctrine/Base should contain the classes for your database. As I mentioned above do not change the files in the Base folder, you can use the classes in the parent Doctrine folder to make changes. You will also notice that there are two classes per database table in the Doctrine folder, one is suffixed with Table. Here I tend to place my DQL code to keep it away from my models/controllers. The other classes can be used to make changes to the classes in the base folder, also you can add hooks and listeners here to add table specific code such as adding password encryption or presetting dates etc.

我希望我已经把它解释得足够清楚,因为它是一份工作的猪,但这是我的设置方式.

I hope I have explained it clearly enough as it is a pig of a job to get working but this is how mine is set up.

我希望这会有所帮助.

这篇关于您如何在 Zend Framework 中使用关系数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆