Каркас для web-додатків, побудований на CodeIgniter

web-додатків
Напевно, багато веб-програмістів вивчали і, можливо, навіть використовували такий чудовий фреймворк якCodeIgniter. Мій вибір припав на нього через те, що у нього найнижчий поріг входження, він найпростіший у вивченні, хороша документація, швидкий і т.д. і т.п. Для найпростіших проектів саме «воно», щоб спробувати свої сили саме як розробник. Само собою, для більш серйозних проектів краще використовувати більш функціональні та наворочені фреймворки.

Це розширення дозволить нам усередині кожного модуля розташовувати свої моделі, контролери, юшки, що стосуються тільки цього модуля. Також можна всередині цих модулів створювати підпапки всередині папок моделей, контр-ів або хрусків, що дуже зручно для великих модулів, що мають багато файлів.

web-додатків
Більше того, це дозволяє нам завантажувати кілька контролерів або моделей з різних модулів та будувати зручну нам структуру (або запускати з однієї моделі контролер іншого модуля тощо). У цьому я, звичайно, нічого нового не відкрив. Тож ідемо далі. У базовому CI URL розбирається таким чином: example.com/class/function/ID

Тобто. перший сегмент - це контролер (клас), другий - функція в ньому, третій - параметр, що передається в функцію (може бути і четвертий і п'ятий). Щиро кажучи, навіть для середнього проекту це дуже незручно, тому я вирішив побудувати свою логіку обробки URL, що дає мені повну свободу дій. Для цього редагуємо файл routes.php у папці application/config та прописуємо до нього:

З цього видно, що в будь-якому випадку завантажуватиметься контролер main і запускатиметься функціяindex(). Далі створюємо файл у папціapplication/controllersі називаємо його "main.php". Не забуваймо, що ми встановили розширення HMVC,тому наші контролери тепер успадковуватимуться не відCI_Controller, а відMX_Controller. Цей контролер буде головним, і через нього проходитиме все. У той же час він буде дуже простим і просто передаватиме управління в інші модулі. Так виглядає функціяindex()у мене:

Останні два рядки з класу "tp" поки що чіпати не будемо. Базовий CI не використовує сесії PHP, а замість них зберігає дані в Cookies (вкидаючи новачків в оману, називаючи свою бібліотеку Session, хоча вона працює з Cookies). Я все ж таки вирішив використовувати рідні сесії PHP, хоча і не відмовився повністю від функціоналу, запропонованого CI для роботи з Cookies (використовую і те, і те).

Отже, перше, що я роблю, перевіряю на мову (проекти у мене найчастіше мультимовні).

Очевидно, перший сегмент в URL буде відповідати за мову. У файліapplication/config/config.phpвкажіть:

Щоб змінити мову конфігурації з контролера, використовуйте це

Якщо ви не використовуєте мультимовність, просто пропустіть це.

Функціяcheck_module()повинна перевірити другий сегмент УРЛу (чи перший, якщо ви не використовуєте мультимовність) на те, чи він є допустимим модулем, тобто. я заздалегідь у конструкторі прописую дозволені модулі, наприклад, так:

Потім у функції перевіряю:

Таким чином, якщо другий сегмент порожній, то вантажиться головна сторінка. Якщо в URL допустимий модуль, то він вантажиться, якщо ні, то викидає на 404. Далі я створюю 2 моделіtp.phpіcommon.phpв папціapplication/models, які будуть доступні у мене скрізь (прописую їх в автозавантажувачіapplication/config/autoload.php):

У «tp» будуть описані функції для роботи мого простенького шаблонізатора, що розширюєможливості дуже слабкого рідного. У «common» пишу всі інші функції, які часто використовуватимуться. Таким чином,$this->common->load_module($m)завантажуватиме модуль$m(другий сегмент з URL) і функціюindex( )у ньому. Тут все просто:

Кожен модуль, що завантажується з URL повинен використовувати якийсь шаблон усієї сторінки, наприклад такий

Основні шаблони всієї сторінки створюються в папціapplication/views/templates(папкаtemplatesстворюється вручну). Різні модулі можуть використовувати ті самі шаблони. Сам каркас контролера модуля виглядає так:

У нашому модуліNewsстворюємо 3 папки -controllers, models, views. У папціcontrollersстворюємо файлnews.phpі записуємо код, описаний вище. У функціїindex()вибудовуємо свою логіку. Я, наприклад, вантажу там модель news_model.php, що знаходиться в папці models модуля news. Вже в моделі описую функції для роботи з базою чи інші складні функції, пов'язані з цим модулем.

Зрештою весь результат, отриманий з модуля news, записується в міткуCONTENT, яка замінюється в шаблоні на цей результат. Щоб зрозуміти, як це відбувається, потрібно розповісти, як побудував логіку мого «шаблонізатора». Я лише розширив можливості базового «Парсера» і привів у «людський вигляд». Якщо ви не знаєте, як базовий працює, спочатку краще розберіться з цим.

Розглянемо модель «tp».

Тут є 2publicзмінні -$D,$tpl.$D– це наш глобальний масив, який врешті-решт замінить у шаблоні всі мітки виду на вміст$this->D[‘LABEL’], опрацьований у модулях. $tpl – це основний головний шаблон усієї сторінки,який прописується в кожному модулі з УРЛу і передається потім в головний контролер main, де викликається$this-tpt-load_tpl($this-tp-tpl).

Вище ми бачили функціюparse(). У цю функцію обов'язково повинні передаватися 2 параметри, перший - це мітка, в яку буде збережено результат (шматок html), другий - цей шматок html, що знаходиться в папці . Алеparse()перевірить цей html на наявність у ньому міток і пропрацює їх у разі потреби:

З цього всього має бути зрозуміло, що якщо створити всередині модуля news у папці views файлnews.tplі написати туди найпростіший html, наприклад

Потім запуститиexample.com/uk/news, то запуститися головний контролерmain.php, який передасть управління в модульnews, там завантажиться шаблонp_default .tpl(з коду вище).

Потім контролер модуляnewsзамінить вміст файлуapplication/modules/news/views/news.tplі виведе вміст шаблонуp_default.tplна екран. Але... це поки теоретично, адже ми не описали функції$this->tp->load_tpl($this->tp->tpl)і$this- >tp->print_page().

Функціяload_tpl()приймає як параметр шаблон, який є основним, тобто. шаблоном усієї сторінки (у папціviews/templates). Потім цей шаблон перевіряється на інші мітки, які можуть бути або модулями, або просто змінними (наприклад, заголовок або копірайт). Мітки у верхньому регістрі та з числами – це модулі, у нижньому – прості змінні. Якщо заміну міток не знайдено, то вони просто затираються (видаляються). Ось сам код:

Наприкінці нашого головного контролераmainвиконується функціяprint_page(), яка має вивестиопрацьований шаблон на екран:

Все вище описане я намагався якнайбільше спростити. Насправді, у мене все набагато складніше і розширеніше, але це ви зможете зробити самі (оскільки це, можливо, не всі дочитали до кінця). У моделі «tp» у мене ще купа будь-яких функцій для шаблонизатора, наприклад:

Зрозуміти їхню логіку нескладно. За допомогою$this->tp->assign('page_title', 'Головна сторінка'), наприклад, можна просто замінити на "Головна сторінка" у шаблоні.

Всередині шаблонів також можуть бути модулі, які можуть виводити щось, наприклад, останні новини або меню. У шаблоні вони вставляють усередині фігурних дужок, наприклад, або . Функція parse(), зустрівши таку мітку, перевірить, чи ця мітка є модулем, і якщо так, то замінить її на те, що видасть цей модуль. Такі модулі також розташовуються всередині папки modules і мають M-V-C. Головний контролер модуляheader, наприклад, виглядає так:

Слід зазначити, що першим пропрацює модуль, який завантажується з URL і є головним, потім підвантажується шаблон і parse() опрацьовує всі модулі всередині нього. Для наочності все, описане вище, зобразив на зображенні

каркас

Прошу пробачити за примітивну графіку, я все ж таки програміст, а не дизайнер.

Радий почути критику професіоналів.

Мій доопрацьований CodeIgniter можна завантажити звідси.