Расширяемая структура директорий в Yii

13 августа 2011

Это адаптированный вольный перевод вики-статьи The directory structure of the Yii project site. Дополнения и багфиксы приветствуются.

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

Общая структура

Ниже приведена полная структура директорий, которую мы будем использовать:

/
    backend/
    common/
        components/
        config/
            params.php
            params-local.php *
        lib/
            Pear/
            yii/
            Zend/
        migrations/
        models/
            Comment.php
            Extension.php
            ...
    console/
        commands/
            SitemapCommand.php
            ...
        config/
            main.php
            main-local.php *
            params.php
            params-local.php *
        runtime/
        yiic.php *
    frontend/
        components/
        config/
            main.php
            main-local.php *
            params.php
            params-local.php *
        controllers/
            SiteController.php
            ...
        lib/
        models/ 
            ContactForm.php
            SearchForm.php      
        runtime/
        views/
            layouts/
            site/
        www/
            assets/
            css/
            js/
            index.php *
    yiic
    yiic.bat

В командной разработке мы должны использовать какую-либо систему контроля версий (git, Subversion, Mercurial и т.д.) для кода разрабатываемого проекта. Файлы, помеченные звездочками в структуре директорий выше, не должны находиться в репозитории системы контроля версий (почему, поясняется ниже).

Директории верхнего уровня

На верхнем уровне мы имеем 4 директории:

  • backend: приложение-бэкэнд предназначенное для управления и администрирования всей системы;
  • frontend: приложение-фронтенд, которое содержит в себе основной функционал системы для конечных пользователей;
  • console: консольное приложение с консольными командами;
  • common: директория, содержащая все те вещи, которые используются в более чем одном приложении системы.

Мы делим всю систему на три приложения: backend, frontend и console. Если появится необходимость в добавлении нового приложения (например, приложение api, которое будет предоставлять API сайта в виде веб-сервиса), то нужно просто добавить новую директорию верхнего уровня с нужной внутренней структурой директорий. Директорию common мы используем для хранения файлов, которые будут использоваться в нескольких приложениях проекта.

Директории приложений

Структуры директорий всех приложений схожи. Приложения frontend и backend имеют следующие директории:

  • components: содержит компоненты (хелперы и виджеты) которые используются только в данном приложении;
  • config: настройки приложения;
  • controllers: тут находятся контроллеры приложения;
  • lib: здесь размещаются сторонние библиотеки, используемые только в данном приложении;
  • models: содержит в себе модели классов, специфичные для данного приложения;
  • runtime: хранит динамически генерируемые файлы во время выполнения приложения;
  • views: тут находятся шаблоны действий контроллеров;
  • www: корневая директория хоста веб-сервера данного приложения.

Структура директорий консольного приложения console выглядит иначе, потому как это приложение не нуждается в контроллерах, шаблонах и директории хоста веб-сервера (controllers, views и www соответственно). В отличие от других приложений консольное приложение содержит директорию commands в которой находятся файлы классов консольных команд.

Общая директория

Общая директория common содержит файлы, которые используются в нескольких приложениях. Например, каждому приложению требуется доступ к базе данных посредством ActiveRecord. Потому, мы должны хранить классы ActiveRecord моделей в общей директории common. Аналогичным образом дело обстоит и с хелперами и виджетами, которые используются более чем в одном приложении. Они тоже должны быть помещены в директорию common для того, чтобы избежать ненужного дублирования кода.

Чтобы упростить поддержку кода, организация структуры директорий в common примерно такая же, как и в приложениях. Например, вполне возможно, что там будут такие директории, как components, models, lib и прочие.

Чуть ниже будет рассказано о том, что приложения могут разделять между собой и конфигурации. Следовательно, мы должны хранить общие настройки в директории common.

Во время создания крупных проектов с длинным циклом разработки нам периодически приходится менять структуру базы данных. Потому мы используем функционал миграций базы данных для того, чтобы следить за изменениями в ней. Мы храним все эти миграции базы данных в директории migrations внутри общей директории common.

Конфигурации приложений

Приложения одной системы обычно разделяют некоторые общие настройки, такие, как параметры соединения с базой данных, параметры-переменные приложения и прочие. Для того, чтобы предовратить повторение кода, мы должны вычленить эти общие настройки из приложений и начать хранить их в одном общем месте. В нашем случае мы будем хранить их в директории config внутри common.

Разные разработчики одного проекта могут иметь разные рабочие окружения (операционные системы, настройки соединения с базой данных, директория проекта могут быть разными). Среда боевого сервера также отлична от сред разработчиков. Для того, чтобы разработчики не мешали друг другу особенностями своих сред, мы разделяем конфигурацию каждого приложения на две части: базовая конфигурация (например, main.php и params.php) и локальная конфигурация (например, main-local.php и params-local.php).

Базовая конфигурация должна храниться в системе контроля версий кода таким же образом, как и обычный файл исходного кода. Базовая конфигурация должна быть разделена между всеми разработчиками.

Локальная конфигурация не должна помещаться в систему контроля версий кода и может существовать только в рабочей директории каждого разработчика. Разработчик имеет полную свободу действий в его локальном конфигурационном файле.

Для слияния базовой и локальной конфигураций в бутстрап-скрипте index.php мы можем воспользоваться следующим кодом:

require('path/to/yii.php');
$local=require('path/to/main-local.php');
$base=require('path/to/main.php');
$config=CMap::mergeArray($base, $local);
Yii::createApplication($config)->run();

Алиасы путей

Для того, чтобы облегчить обращение к файлам других приложений мы можем создать корневой алиас пути site который указывает на корневую директорию всей системы с 4 приложениями в ней. В результате мы можем использовать алиас site.frontend.models.ContactForm для того, чтобы указать на класс ContactForm который был объявлен в приложении frontend.

Развертывание

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

Боевой сервер можно рассматривать как отдельного разработчика, средой разработки которого и является сам сервер.

Для начала мы чекаутим новую или обновляем уже существующую рабочую копию из системы контроля версий в нужное место на боевом сервере.

Затем мы создаем или изменяем локальную конфигурацию, специфичную для боевого сервера (задатем параметры соединения с базой данных, например). Также возможно нам понадобится установить значение константы YII_DEBUG в ложное значение в бутстрап-файле index.php.

Потому как каждое приложение мы держим в отдельных директориях то, при необходимости все приложения можно развернуть на разных физических серверах.


Егор

№ 900

Егор

14 декабря 2011, 11:03

Спасибо, неплохой перевод) +1 бы кликнул
resurtm

№ 1845

resurtm

1 января 2012, 22:55

Не за что. Кнопки сделаю чуть позже, как руки дойдут.
Alex

№ 1855

Alex

19 января 2012, 14:56

Я не понял каким образом мне получить доступ к админке. Bootstrap для админки расположен в backend/www/index.php?
resurtm

№ 1856

resurtm

19 января 2012, 18:50

Да, все верно. Бутстрап бэкэнда там и находится.

Чуть позже выложу рабочий пример с такой структурой директорий, чтобы было понятнее.
Rustamich

№ 1870

Rustamich

29 апреля 2012, 02:26

посмотреть бы рабочий пример, не могу понять, это всё выносится из папки protected или это в ней такая структура? потом нужно настраивать mod_rewrite для доступа к главной сайта или как вообще всё происходит?
metalguardian

№ 1880

metalguardian

7 мая 2012, 21:27

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

№ 3171

Chifu

4 июня 2012, 19:53

Да, было бы намного понятней с рабочим примером. Пожалуйста, сделайте доброе дело, выложите рабочий пример, и запостите это всё на Хабр, если там ещё этого нету :)
Олег

№ 3288

Олег

18 июля 2012, 14:53

Подскажите пожалуйста!!! у Вас папке common/config 2 файла

params.php
params-local.php

В папке frontend/components/config/ теже 2 файла
params.php
params-local.php

Они одинаковы по содержанию? Если да, то для чего нужно дублировать их? ))
Alex.Sh

№ 3294

Alex.Sh

25 июля 2012, 00:24

У кого-нибудь есть возможность показать рабочий пример с данной архитектурой?

Возникают ли какие-то неудобства при работе с такой структурой?

Спасибо
Anton

№ 3295

Anton

25 июля 2012, 00:48

Да, примера определённо нехватает :)
Alex.Sh

№ 3299

Alex.Sh

25 июля 2012, 15:02

В оригинальной версии статьи тоже пока никто деталей реализации не выложил, очень жалко.

Также интересно удобно ли оформлять в таком-же стиле мобильную версию сайта, если она сильно от десктоп отличается.
Bagration

№ 3317

Bagration

31 июля 2012, 16:22

Судя по структуре директорий и наличию файликов yiic и yiic.bat - то все это добро находится папке protected (ну не в папке с фреймворком же) :)

А вот рабочего примера, пусть и абстрактного очень сильно не хватает :(
Alex.Sh

№ 3318

Alex.Sh

31 июля 2012, 18:51

Это все в корне находится. И как я понимаю путь до веб рут устанавливается с помощью сервера.

Думаю адаптация для шаред хостингов не должна быть очень сложной, если статья будет обновляться это можно включить.
resurtm

№ 3330

resurtm

10 августа 2012, 15:20

Clevertech сделали долгожданный пример к переводу и оригиналу: https://github.com/clevertech/YiiBoilerplate :)
Alex.Sh

№ 3331

Alex.Sh

10 августа 2012, 18:15

Отлично!
А что можно придумать для использования такой схемы на шаред хостингах, где нет доступа к конфигам апач для установки алиасов?
Aibolit

№ 3349

Aibolit

31 августа 2012, 18:04

@Alex.Sh:
Обычно на шаред хостингах есть возможность создавать субдомены. Создайте субдомен (например admin.yoursite.com) и укажите в качестве корневой папки путь backend/www из данного бойлерплейта.