<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ZCMS</title> <style type="text/css"> pre { background: #f5f5f5; padding: 5px; } code { color: #0000ff; } </style> </head> <body> <h1>ZCMS</h1> <p> <strong>Интернет-магазин на PHP и MySQL с использованием концепции MVC</strong> </p> <h2>Общая информация</h2> <p> Приложение построено с использованием концепции <a href="https://ru.wikipedia.org/wiki/Model-View-Controller">Model-View-Controller</a>: </p> <ul> <li>Общедоступная часть сайта <ul> <li>контроллеры: <a href="https://github.com/tokmakov/zcms/tree/master/app/controller/frontend">app/controller/frontend</a></li> <li>модели: <a href="https://github.com/tokmakov/zcms/tree/master/app/model/frontend">app/model/frontend</a></li> <li>представление: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/frontend">view/tinko/frontend</a> <ul> <li>js-, css-файлы, изображения, шрифты: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/frontend/resource">view/tinko/frontend/resource</a></li> <li>шаблоны: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/frontend/template">view/tinko/frontend/template</a></li> </ul> </li> </ul> </li> <li>Административная часть сайта <ul> <li>контроллеры: <a href="https://github.com/tokmakov/zcms/tree/master/app/controller/backend">app/controller/backend</a></li> <li>модели: <a href="https://github.com/tokmakov/zcms2/tree/master/app/model/backend">app/model/backend</a></li> <li>представление: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/backend">view/tinko/backend</a> <ul> <li>js-, css-файлы, изображения, шрифты: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/backend/resource">view/tinko/backend/resource</a></li> <li>шаблоны: <a href="https://github.com/tokmakov/zcms/tree/master/view/tinko/backend/template">view/tinko/backend/template</a></li> </ul> </li> </ul> </li> </ul> <h2>Структура классов</h2> <ul> <li>Абстрактый класс <a href="https://github.com/tokmakov/zcms/blob/master/app/Base.php">Base</a>, родительский для всех контроллеров и моделей <ul> <li>Абстрактый класс <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/Base_Controller.php">Base_Controller</a>, наследующий Base <ul> <li>Абстрактный класс <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/frontend/Frontend_Controller.php">Frontend_Controller</a>, наследующий Base_Controller</li> <li>Абстрактный класс <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/backend/Backend_Controller.php">Backend_Controller</a>, наследующий Base_Controller</li> </ul> </li> <li>Абстрактый класс <a href="https://github.com/tokmakov/zcms/blob/master/app/model/Base_Model.php">Base_Model</a>, наследующий Base <ul> <li>Абстрактый класс <a href="https://github.com/tokmakov/zcms/blob/master/app/model/frontend/Frontend_Model.php">Frontend_Model</a>, наследующий Base_Model</a></li> <li>Абстрактый класс <a href="https://github.com/tokmakov/zcms/blob/master/app/model/backend/Backend_Model.php">Backend_Model</a>, наследующий Base_Model</a></li> </ul> </li> </ul> </li> </ul> <p> Все контроллеры общедоступной части сайта наследуют <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/frontend/Frontend_Controller.php">Frontend_Controller</a>, все контроллеры административной части сайта наследуют <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/backend/Backend_Controller.php">Backend_Controller</a>. </p> <p> Все модели общедоступной части сайта наследуют <a href="https://github.com/tokmakov/zcms/blob/master/app/model/frontend/Frontend_Model.php">Frontend_Model</a>, все модели административной части сайта наследуют <a href="https://github.com/tokmakov/zcms/blob/master/app/model/backend/Backend_Model.php">Backend_Model</a>. </p> <h2>Вспомогательные классы</h2> <ul> <li><a href="https://github.com/tokmakov/zcms/blob/master/app/include/Database.php">Database</a> предоставляет доступ к базе данных</li> <li><a href="https://github.com/tokmakov/zcms/blob/master/app/include/Router.php">Router</a> анализирует $_SERVER['REQUEST_URI'], чтобы узнать, какой контроллер должен быть запущен в работу</li> <li><a href="https://github.com/tokmakov/zcms/blob/master/app/include/Register.php">Register</a> хранит все объекты приложения, чтобы везде иметь к ним доступ</li> <li><a href="https://github.com/tokmakov/zcms/blob/master/app/include/Config.php">Config</a> хранит все настройки приложения, чтобы везде иметь к ним доступ</li> <li><a href="https://github.com/tokmakov/zcms/blob/master/app/include/Cache.php">Cache</a> кэширует данные, класс-обертка для <a href="https://github.com/tokmakov/zcms/blob/master/app/include/FCache.php">FCache</a> и <a href="https://github.com/tokmakov/zcms/blob/master/app/include/MCache.php">MCache</a></li> </ul> <h2>Настройки приложения</h2> <ul> <li>Общие настройки <a href="https://github.com/tokmakov/zcms/blob/master/app/config/config.php">app/config/config.php</a></li> <li>Настройки базы данных <a href="https://github.com/tokmakov/zcms/blob/master/app/config/database.php">app/config/database.php</a></li> <li>Подключение css-файлов <a href="https://github.com/tokmakov/zcms/blob/master/app/config/css.php">app/config/css.php</a></li> <li>Подключение js-файлов <a href="https://github.com/tokmakov/zcms/blob/master/app/config/js.php">app/config/js.php</a></li> <li>Настройка Content Delivery Network <a href="https://github.com/tokmakov/zcms/blob/master/app/config/cdn.php">app/config/cdn.php</a></li> <li>Настройка кэша <a href="https://github.com/tokmakov/zcms/blob/master/app/config/cache.php">app/config/cache.php</a></li> <li>Настройка meta-тегов <a href="https://github.com/tokmakov/zcms/blob/master/app/config/meta.php">app/config/meta.php</a></li> <li>Настройка постраничной навигации <a href="https://github.com/tokmakov/zcms/blob/master/app/config/pager.php">app/config/pager.php</a></li> <li>Настройка маршрутизации <a href="https://github.com/tokmakov/zcms/blob/master/app/config/routing.php">app/config/routing.php</a></li> </ul> <h2>Как формируется страница</h2> <ol> <li>Все запросы перенаправляются на <a href="https://github.com/tokmakov/zcms/blob/master/index.php">index.php</a>, см. файл <a href="https://github.com/tokmakov/zcms/blob/master/.htaccess">.htaccess</a> <pre><code># одна точка входа, все запросы (кроме файлов и директорий) на /index.php RewriteCond %{REQUEST_FILENAME} !^favicon.ico RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*) index.php</code></pre> </li> <li>Экземпляр класса <a href="https://github.com/tokmakov/zcms/blob/master/app/include/Router.php">Router</a> анализирует $_SERVER['REQUEST_URI'], чтобы узнать, какой контроллер должен быть запущен в работу</li> <li>Вызывается метод контроллера request(), который определен в классе <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/Base_Controller.php">Base_Controller</a> <pre><code>try { // экземпляр класса роутера $router = Router::getInstance(); // получаем имя класса контроллера, например Index_Page_Frontend_Controller $controller = $router->getControllerClassName(); // параметры, передаваемые контроллеру $params = $router->getParams(); // создаем экземпляр класса контроллера $page = new $controller($params); // формируем страницу $page->request(); } catch (Exception $e) { // если произошла какая-то ошибка $page = new Error($e); die(); }</code></pre> </li> <li>Метод request() вызывает последовательно методы input() и output() <pre><code>abstract class Base_Controller extends Base { .......... public function request() { $this->input(); if ($this->notFoundRecord) { return; } $this->output(); } .......... }</code></pre> </li> <li>Метод input(), который определен в Base_Controller и переопределен в дочерних классах: <ul> <li>получает от модели данные, необходимые для формирования страницы, и сохраняет их в переменных $headVars, $headerVars, $menuVars, $centerVars, $leftVars, $rightVars, $footerVars</li> <li>получает имена файлов шаблонов отдельных частей страницы и сохраняет их в переменных $headTemplateFile, $headerTemplateFile, $menuTemplateFile, $centerTemplateFile, $leftTemplateFile, $rightTemplateFile, $footerTemplateFile</li> </ul> </li> <li>Метод output(), который реализован в классах Frontend_Controller и Backend_Controller, вызывает метод render(), передавая ему полученные от модели данные и имена файлов шаблонов <pre><code>abstract class Frontend_Controller extends Base_Controller { protected function output() { $this->headContent = $this->render( $this->headTemplateFile, $this->headVars ); .......... $this->centerContent = $this->render( $this->centerTemplateFile, $this->centerVars ); .......... $this->footerContent = $this->render( $this->footerTemplateFile, $this->footerVars ); // сборка страницы из отдельных частей html-кода $this->pageContent = $this->render( $this->wrapperTemplateFile, array( 'headContent' => $this->headContent, 'headerContent' => $this->headerContent, 'menuContent' => $this->menuContent, 'centerContent' => $this->centerContent, 'leftContent' => $this->leftContent, 'rightContent' => $this->rightContent, 'footerContent' => $this->footerContent ) ); } }</code></pre> </li> <li>Метод Base_Controller::render() «прогоняет» данные через шаблон, а сформированный html-код отдельных частей страницы сохраняет в переменных $headContent, $headerContent, $menuContent, $centerContent, $leftContent, $rightContent, $footerContent</li> <li>Метод output() в самом конце еще раз вызывает метод render(), чтобы произвести окончательную сборку страницы из отдельных частей html-кода <pre><code>$this->pageContent = $this->render($this->wrapperTemplateFile, array(...));</code></pre> </li> </ol> <p> <strong>Как поключаются css и js файлы?</strong> Сначала подключаются базовые файлы, т.е. те файлы, которые должны быть подключены ко всем страницам сайта. Дальше подключаются файлы, заданные для родительского класса, например для абстрактного класса Catalog_Frontend_Controller. Наконец, подключаются файлы, заданные для этого класса, например, Product_Catalog_Frontend_Controller. </p> <p> Пример подключения CSS-файлов (см. файлы <a href="https://github.com/tokmakov/zcms/blob/master/app/config/css.php">app/config/css.php</a> и <a href="https://github.com/tokmakov/zcms/blob/master/app/config/js.php">app/config/js.php</a>): </p> <pre><code>'css' => array( // CSS файлы, подключаемые к странице 'frontend' => array( // общедоступная часть сайта 'base' => array( // css-файлы, подключаемые ко всем страницам сайта 'reset.css', 'common.css', ), '<span style="color: #ff0000;">index</span>-<span style="color: #009900;">index</span>' => 'jquery.slider.css', // только для главной страницы, формируемой <span style="color: #009900;">Index</span>_<span style="color: #ff0000;">Index</span>_Frontend_Controller '<span style="color: #ff0000;">page</span>' => 'page.css', // для страницы, которую формирует Index_<span style="color: #ff0000;">Page</span>_Frontend_Controller '<span style="color: #ff0000;">catalog</span>' => 'catalog.css', // для страниц, которые формируют дочерние классы <span style="color: #ff0000;">Catalog</span>_Frontend_Controller '<span style="color: #ff0000;">catalog</span>-<span style="color: #009900;">product</span>' => array( // только для страницы, которую формирует <span style="color: #009900;">Product</span>_<span style="color: #ff0000;">Catalog</span>_Frontend_Controller 'product.css', 'jquery.lightbox.css', ), ), 'backend' => array( // административная часть сайта .......... ), ) </code></pre> <p> Здесь важно понимать, что у некоторых абстактных классов есть только один дочерний класс, например: Page_Frontend_Controller и Index_Page_Frontend_Controller. А у других абстрактных классов есть несколько дочерних классов, например у Catalog_Frontend_Controller: </p> <ol> <li>Index_Catalog_Frontend_Controller (главная страница каталога)</li> <li>Product_Catalog_Frontend_Controller (страница товара каталога)</li> <li>Category_Catalog_Frontend_Controller (страница категории каталога)</li> <li>Maker_Catalog_Frontend_Controller (страница производителя каталога)</li> </ol> <p> Запись вида </p> <pre><code>'catalog' => 'catalog.css', // для всех страниц каталога 'catalog-index' => 'catalog-index.css' // только для главной страницы каталога </code></pre> <p> имеет смысл, а запись вида </p> <pre><code>'page' => 'page.css' 'page-index' => 'lightbox.css' </code></pre> <p> не будет ошибочной, но сбивает с толку — потому что подразумевает, что page.css подключается для всех дочерних классов Page_Frontend_Controller. Но у Page_Frontend_Controller только один дочерний класс, поэтому либо так </p> <pre><code>'page' => array( 'page.css', 'lightbox.css' ) </code></pre> <p> либо так </p> <pre><code>'page-index' => array( 'page.css', 'lightbox.css' ) </code></pre> <p> <strong>Какие шаблоны будут использованы?</strong> Eсли для контроллера Index_Page_Frontend_Controller существует файл view/tinko/frontend/template/page/wrapper.php, то будет использован именно он, а не view/tinko/frontend/template/wrapper.php. Если существует view/tinko/frontend/template/page/index/wrapper.php, то будет использован он, а не view/tinko/frontend/template/page/wrapper.php. Аналогично для файлов header.php, menu.php, center.php, left.php и т.д. </p> <p> Т.е. шаблоны по умолчанию, расположенные в папке view/tinko/frontend/template, переопределяются шаблонами, расположенными глубже в иерархии директорий. Шаблон по умолчанию view/tinko/frontend/template/wrapper.php будет переопределен шаблоном view/tinko/frontend/template/catalog/wrapper.php. А шаблон view/tinko/frontend/template/catalog/wrapper.php, в свою очередь, будет переопределен шаблоном view/tinko/frontend/template/catalog/product/wrapper.php. </p> <h2>Кэширование</h2> <p> Данные могут кэшироваться на двух логических и двух физических уровнях. Логический уровень определяет, в каких местах приложения кэшируются данные. Физический уровень кэширования определяет, где хранится кэш: в оперативной памяти или в файлах. </p> <ul> <li><strong>Логический уровень</strong> <ul> <li>кэширование на уровне данных</li> <li>кэширование на уровне шаблонов</li> </ul> </li> <li><strong>Физический уровень</strong> <ul> <li>кэширование в оперативной памяти</li> <li>кэширование с использванием файлов</li> </ul> </li> </ul> <p> <strong>Логический уровень</strong> кэширования — на уровне данных и на уровне шаблонов: </p> <ul> <li><em>Кэширование на уровне данных</em> происходит при получении от модели данных, необходимых для формирования страницы: <ul> <li>Кэширование запросов к БД: если при вызове методов класса <a href="https://github.com/tokmakov/zcms/blob/master/app/include/Database.php">Database</a> fetchAll(), fetch(), fetchOne() параметр $cache установлен в true. Такое кэширование часто используется в методах классов моделей, если метод содержит только вызов метода класса Database.</li> <li>Кэширование данных в методах моделей: если метод класса модели содержит не только вызов метода БД, но и производит (сложные) вычисления.</li> <li>Кроме того, иногда идет обращение к кэшу напрямую, чтобы записать/получить какие-то данные. Экземпляр класса Cache доступен практически везде, см. <a href="https://github.com/tokmakov/zcms/blob/master/app/Base.php">Base::__construct()</a></li> </ul> </li> <li><em>Кэширование на уровне шаблонов</em> используется, когда контроллер получил от модели данные и «прогоняет» их через шаблон, см. метод <a href="https://github.com/tokmakov/zcms/blob/master/app/controller/frontend/Frontend_Controller.php">Fronthend_Controller::render()</a>.</li> </ul> <p> Обычно, чтобы ускорить работу приложения и снизить нагрузку на сервер, достаточно включить кэширование на уровне данных — либо с использованием файлов, либо в оперативной памяти. Дополнительное включение кэширования на уровне шаблонов еще немного ускоряет работу, но резко увеличивает размер кэша (как файлового, так и в оперативной памяти — если он включен). </p> <p> <strong>Физический уровень</strong> кэширования — с использованием файлов и в оперативной памяти: </p> <p> Если кэширование <a href="https://github.com/tokmakov/zcms/blob/master/app/config/cache.php">разрешено</a>, оно всегда использует файлы. Дополнительно можно включить кэширование в оперативной памяти. Нельзя включить только кэш в оперативной памяти и не использовать при этом файловый кэш. Но, допускается использовать только файловый кэш. Кэш в оперативной памяти — «быстрый», файловый кэш — «медленный», они дополняют друг друга. </p> <p> Если приложение работает под высокой нагрузкой на выделенном сервере, можно снизить нагрузку и увеличить производительность, включив кэш в оперативной памяти, в дополнение к файловому. Для этого устанавливаем демон <a href="http://memcached.org/">Memcached</a> и расширение PHP <a href="http://php.net/manual/ru/book.memcache.php">memcache</a>. В этом случае физический кэш будет двухуровневый: сперва данные запрашиваются из оперативной памяти, а потом из файлового кэша. </p> <h2>Обмен данными с 1С</h2> <p> Образец XML-файла для выгрузка каталога на сайт <a href="https://github.com/tokmakov/zcms/blob/master/catalog.xml">catalog.xml</a>, выгрузка заказов с сайта: <a href="https://github.com/tokmakov/zcms/tree/master/app/controller/frontend/exchange">app/controller/frontend/exchange</a> </p> <hr> <p> <a href="http://www.tinko.info/">Демо-сайт</a> </p> </body> </html>

版权声明:

1、该文章(资料)来源于互联网公开信息,我方只是对该内容做点评,所分享的下载地址为原作者公开地址。
2、网站不提供资料下载,如需下载请到原作者页面进行下载。
3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考学习用!
4、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。