Как вы работаете с реляционной базой данных в Zend Framework? - PullRequest
1 голос
/ 31 мая 2011

Я использую Zend Framework для написания приложения, и у меня много проблем с работой моих моделей реляционных баз данных.Я прочитал краткое руководство и документы несколько раз, и я все еще не уверен, как это сделать.Я публикую картину взаимосвязей между различными таблицами, чтобы избежать необходимости объяснять все, так как английский не является моим родным языком, и я, как правило, не проясняю себя, когда пытаюсь объяснить ... сложные вещи.enter image description here

Таблицы press_releases, social_networking, blog_posts, rss_feed, directoryios, users и articulos все заданы как внешние ключи в таблице с именем planilla_users.Я закодировал свои настольные модели так, как показывает быстрый старт:

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

... и остальные, следуя формату:

class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{

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

У меня также есть модель Planilla.php со всемисеттеры и геттеры для информации, которая будет сохранена / обновлена ​​/ извлечена / удалена, ... однако ... Я совершенно не знаю, что делать с картографом.Я не знаю, как это должно работать, и, честно говоря, я еще не нашел хороший пример того, как сделать что-то подобное.Поэтому любая помощь будет в основном оценена.

1 Ответ

3 голосов
/ 31 мая 2011

Я бы посоветовал вам взглянуть на Doctrine , это объектно-реляционный картограф, который может очень хорошо интегрироваться с ZF.Я лично использую версию 1.2 с ZF 1.11.4 без проблем.

Здесь есть хороший скрин здесь , который объясняет, как интегрировать Doctrine в ZF.Доктрина может быть чем-то вроде свиньи, чтобы выучить ее, но как только вы ее поймете, это в конечном итоге сэкономит вам время.Doctrine также поставляется со скриптом командной строки, который может быть использован для преобразования баз данных в классы Doctrine.Если у вас есть отношения, установленные в базе данных, то Doctrine также может их забрать.

Я также слышал, что в ZF 2 будет включен Doctrine 2.0.

Метод, который я использую для создания классов Doctrine.это первая настройка доктрины в вашем файле appication.ini, добавьте эти строки где-нибудь под рабочим заголовком.

[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_Resource Freedom - это мое общее пространство имен в моей библиотеке (см.дерево папок ниже).Здесь у меня есть папка Zend, где я могу разместить свой дополнительный ZF-код, в том числе, если потребуется, переписать существующие функции ZF.Свобода - это название моей компании, твое, очевидно, будет отличаться.Эта строка должна изменить название вашей компании, например pluginpaths.Yourcompany_Zend_Application_Resource = "Yourcompany/Zend/Application/Resource"

Следующая строка - это место, где вы устанавливаете параметры подключения к базе данных 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/Doctrine и application/modules/default/models/Doctrine/Base соответственно (см. Дерево папок ниже).

Есть некоторыедругие строки, которые необходимо изменить, должны быть очевидны.

Вам также необходимо добавить следующие строки под заголовком разработки в application.ini.

[development : production]

//...

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

//...

Вы такженужен файл ресурсов Doctrine.php.Где это находится, зависит от вашей настройки, у меня это выглядит следующим образом.

-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 выглядит следующим образом (очевидно, игнорируйте * !!)

/**
* 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;
    }
}

Далеевам нужно будет создать файл doctrine-cli.php для начальной загрузки вашего приложения, он должен находиться в корне вашего библиотечного файла (см. дерево выше), мой выглядит следующим образом.

/**
 * 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 в вашей общей папке.

Теперь, надеюсь, вам следуетготов генерировать ваши файлы классов базы данных.Перейдите в окно терминала и введите следующее.

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

Если все прошло успешно, папки application/modules/default/models/Doctrine и application/modules/default/models/Doctrine/Base должны содержать классы для вашей базы данных.Как я упоминал выше, не изменяйте файлы в папке Base, вы можете использовать классы в родительской папке Doctrine для внесения изменений.Вы также заметите, что для каждой таблицы базы данных в папке Doctrine есть два класса, к одному из них добавляется таблица.Здесь я стараюсь размещать свой DQL-код, чтобы он не попадал в мои модели / контроллеры.Другие классы могут использоваться для внесения изменений в классы в базовой папке, также вы можете добавить здесь хуки и прослушиватели для добавления кода, специфичного для таблицы, такого как шифрование пароля или предварительная установка дат и т. Д.

Надеюсь, у меня естьобъяснил это достаточно ясно, потому что это свинья работы, чтобы получить работу, но так настроена моя.

Надеюсь, это поможет.

...