где хранить большой статический массив в структуре MVC? - PullRequest
1 голос
/ 20 августа 2009

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

Ответы [ 3 ]

3 голосов
/ 20 августа 2009

Вы заявили, что хотите сохранить эти данные в формате YAML. В терминологии MVC теперь это ваш источник данных.

Вы можете хранить свои файлы YAML в любом месте системы, но, если вы хотите хранить их под контролем версий и не хотите, чтобы они были общедоступными, подходящее место будет в любом месте в вашем каталоге app/ за пределами app/webroot/.

Насколько я знаю, в настоящее время не существует каких-либо источников данных, предназначенных для чтения (и / или записи) из файлов YAML, так что это будет делом для вас, если вы хотите строго придерживаться структуры MVC.

Существует несколько примеров источников данных на github и в других местах , на которые вы можете ссылаться. Стоит отметить, что существует два распространенных подхода к созданию источников данных.

  • Простой подход (и наиболее распространенный) в основном связан с чтением / записью данных и, как правило, использует в своем источнике данных пользовательские методы, которые может вызывать модель. Это самый быстрый подход, позволяющий получать данные, которые не обязательно должны согласовываться со всеми соглашениями CakePHP.
  • Более продвинутый подход (и, возможно, предпочтение разработчикам тортов) заключается в правильном переопределении большинства методов в расширяемом классе (либо DataSource , либо, в случае баз данных, DboSource ). Это позволяет CakePHP творить чудеса при выполнении обычных задач, таких как find('list') или paginate().

Я бы лично посоветовал начать с простого подхода:

app/config/database.php:

var $yaml = array(
    'datasource' => 'yaml',
    'path' => 'data/yaml', // relative to app/ directory, no trailing slash
);

app/models/category.php

// app/models/category.php
class Category extends AppModel {

    public $useDbConfig = 'yaml';

    /**
     * cake should automatically set $model->table to 'categories' on construct
     * (http://api.cakephp.org/view_source/model/#l-419) hence $useTable will not
     * be necessary (convention over configuration)
     */
    // public $useTable = 'categories';

    /**
     * since datasource doesn't strictly adhere to cake's api, the core find 
     * method may cause errors. to combat this we can redefine this method with
     * a much simpler version, but functionality will be lost in doing so.
     */
    public function find($type = 'all', $options = array()) {
        // get an instance of our datasource
        $ds = ConnectionManager::getDataSource($this->useDbConfig);
        // $type is usually handled by model, but we will pass it to datasource
        $options['type'] = $type;
        // query the datasource
        return $ds->read($this, $options);
    }

}

app/models/datasources/yaml_source.php

class YamlSource extends DataSource {

    public function read(&$model, $queryData = array()) {
        // determine path to yaml file
        $yamlPath = APP . $this->config['path'] . DS . $model->table . '.yaml';
        // parse the yaml file
        $results = $this->_parseYaml($yamlPath);
        // perform any array manipulation (determined by $queryData)
        ...
        // handle $queryData['type'] (would normally have been done in Model)
        ...
        // return results in a typical Model data array
        return array($model->alias => array(
            $results // your results go here
        ));
    }

}

app/controllers/categories_controller.php

class PostsController extends AppController {

    /**
     * this is only needed if all actions use these models. Since Post model is
     * loaded automatically, we can just use Controller::loadModel() to get an
     * instance of Category model where needed.
     */
    //public $uses = array('Post', 'Category');

    public function edit($id) {
        $posts = $this->Post->read(null, $id);
        if (!$post) {
            $this->cakeError('error404');
        }
        $this->loadModel('Category');
        $categories = $this->Category->find('list');
        $this->set(compact('posts', 'categories'));
    }

}

Вы сможете расширять этот источник данных с течением времени (делая его более совместимым с API), так как вам нужны дополнительные функции (нумерация страниц, фильтры обратного вызова, отношения и т. Д.). Этот источник данных будет немедленно повторно использован любыми другими моделями ваших приложений.

0 голосов
/ 21 августа 2009

Я бы не стал это делать ни одним из этих способов. Я бы тоже не использовал YAML. Я хотел бы создать ваш "длинный массив PHP" как, ждать его, длинный массив PHP.

Нет большой разницы в том, чтобы хранить данные в виде массива PHP и сохранять их в виде YAML. Кроме того, если вы храните его как массив, вам не нужно преобразовывать его из YAML в массив, чтобы проходить через него.

Подходящим местом для этого массива является файл, который вы загружаете с помощью класса Configure. Например. /app/config/form.php:

<?php
$config = array(
  'Form' => array(
    ...
  )
);
?>

Затем вы можете загрузить массив из любого места в вашем приложении и получить к нему доступ

<?php
Configure::load('form'); // Loads app/config/form.php file and stores $config in Configure class
$form = Configure::read('Form');
foreach ($form as $field) {
  ...
}
?>

См. http://book.cakephp.org/view/415/load

0 голосов
/ 20 августа 2009

Более простой подход (читай: более простой), который все еще отвечает на ваш вопрос, но игнорирует тот факт, что вы хотите сохранить статические данные в файле yaml, будет выглядеть следующим образом:

// app/models/category.php
class Category extends AppModel {

    public $name = 'yaml';

    public $data = array(
        array(
            'id' => '1',
            'name' => 'Category 1',
        ),
        array(
            'id' => '2',
            'name' => 'Category 2',
        ),
        ...
    );

    public function find($type = 'all', $options = array()) {
        if ($type == 'all') {
            return $this->data;
        }
        // .. otherwise do some array manipulation on $this->data ..
        return $results;
    }
}

Этот подход не обладает такой же расширяемостью или возможностью повторного использования, как при использовании источника данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...