Писане на прост, разширим двигател

Публикувано от beowulf13th на 06 септември 2011 г

Реших да споделя знанията си :) CMS въз основа на този пример, който написах през 2007 г. Оттогава тя е преминала през много промени. внимание. Твърде мързелив съм, за да разбера защо кавичките се преобразуват тук. Така че не забравяйте да промените кавичките на стандартни. Е да. Тук може да има много грешки. Защото пиша това почти по памет и не проверявам (да, толкова съм хитър и зъл). Да, и кодът е подреден в списъци, което не може да бъде много удобно за злите копи-пейсти! :) Коментарите са добре дошли.

Задача : да напишете проста система за управление на съдържанието, така че да можете бързо да добавите необходимите модули и да ги внедрите в системата.

Какво получаваме :

Това ще бъде проста CMS, която ще бъде написана на PHP5 с помощта на OOP. Ще използваме XSLT като машина за шаблони. Тези. Използвайки PHP, ние подготвяме XML за по-нататъшна XSL обработка. В резултат на това получаваме HTML, който поставяме на правилното място на страницата. Системата ще работи с помощта на mod_rewrite и псевдоними на страници за поддръжка.

Ние създаваме база данни.

Имаме нужда от няколко таблици в базата данни. Всички таблици ще имат префикси, за да се избегне конфликт с други подобни таблици в базата данни.

Първо, ще е необходимо да съхраним някъде нашите манипулатори на страници. Ние наричаме манипулатори тези класове, които ще създадат страница от определен тип за нас. Тези. Новини. Или например карта на сайта. Можете да направите това в един файл и да го включите. Недостатъкът на това е, че всеки път, когато добавите нов манипулатор, ще трябва да качите актуализиран файл на сървъра. Освен това, ако друг програмист добави свой собствен манипулатор там и вие не знаете за това, ще го презапишете. Ище lulz :)

Второ, ще е необходимо самите страници да се съхраняват някъде.

Така че да започваме. Създаваме таблица, в която ще съхраняваме манипулатори и таблица на страници:

След това добавяме ръчно (нямаме административен панел ;( ) два манипулатора и две страници, за да започнем. Един манипулатор е типични страници (да ги наречем така). Е, или просто страници, които можете да създавате колкото искате и да го наричате родител. Вторият манипулатор е манипулаторът на главната страница, нека го наречем Mainpage. В крайна сметка може да искаме нашата главна страница да е различна от всички останали, нали? таблици, от които се нуждаем.

След това създайте структура на директория на диска

Да започнем да програмираме :)

Създаваме файлове index.php, config.php, load.php, functions.php в корена.

config.php:

  1. $const = ""; // налични константи (очаквайте по-късно)
  2. $domain = "http://localhost:2000/"; // домейн, на който работи сайтът
  3. $pfx = "e"; // префикс на база данни
  4. $charset = "UTF-8"; // кодиране за заместване в html
  5. $db_charset = "UTF8"; // кодиране за свързване към базата данни
  6. $db_user = "потребител"; // потребителско име на база данни
  7. $db_pass = "потребител"; // парола
  8. $db_host = "localhost"; // хост на база данни
  9. $db_name = "двигател"; // самата база данни
  10. $db = нов mysqli(&$db_host, &$db_user, &$db_pass, &$db_name);
  11. $db->query("ЗАДАВАНЕ НА ИМЕНА");
  12. // зареждане на всички класове
  13. $classes_query_str = "ИЗБЕРЕТЕ `classpath`,`classname` ОТ `_handlers`";
  14. $classes_query = $db->заявка($classes_query_str);
  15. while($classes = $classes_query->fetch_object())
  16. if(file_exists($_SERVER[‘DOCUMENT_ROOT’].’/class/’.$classes->classpath))
  17. require_once $_SERVER[‘DOCUMENT_ROOT’].’/class/’.$classes->classpath;
  18. друго
  19. изход(«Име на клас на клас> не е намерено»);
  20. >

index.php:

load.php:

  1. заявка ($classes_query_str);
  2. while($classes = $classes_query->fetch_object())
  3. require_once $_SERVER[‘DOCUMENT_ROOT’].’/’.$classes->classpath;
  4. // създаваме перменни алясов, страници и id страници
  5. isset($_GET['страница'])? $page = clearVar($_GET['page']) : $page = 1;
  6. isset($_GET[‘псевдоним’])? $alias = clearVar($_GET[‘alias’]) : $alias = »;
  7. isset($_GET['uid'])? $uid = clearVar($_GET[‘uid’]) : $uid = 0;
  8. $страница = (int)$страница;
  9. $uid = (int)$uid;
  10. //получаваме информация за страницата
  11. $info_page = getPageInfo($alias,$uid,$page);
  12. // сега извикваме клас
  13. ако ($info_page)
  14. // ищем нужный обработчик
  15. $query_handler_str = «ИЗБЕРЕТЕ `име на клас` ОТ `_handlers` WHERE `id` =»;
  16. $query_handler = $db->заявка($query_handler_str);
  17. if($query_handler->num_rows fetch_object();
  18. $page = нов $handler->classname($info_page);
  19. отпечатайте $page->getContent();
  20. >
  21. >

Във файлаfunctions.php добавяме следните функции:

  1. /**
  2. * Извежда информация за переменната
  3. * @param $text информация за извода
  4. * @param $exit прекратяване на работата след извода
  5. */
  6. функция vardump($text, $exit = false)
  7. печат „ “;
  8. ако ($ изход)
  9. изход;
  10. >
  11. /**
  12. * Изрязва от переменни ненужни символи
  13. * @param $var переменна за почистване
  14. * @return чистапроменлива
  15. */
  16. функция clearVar($var)
  17. return str_replace('"',"",str_replace("'","",stripcslashes(trim(htmlspecialchars($var)))));
  18. >
  19. /**
  20. * Вземете информация за страницата
  21. * @param $alias псевдоним за страницата в базата данни
  22. * @param $uid id на страницата в базата данни
  23. * @param $page номер на страница в базата данни
  24. * @return масив с всички стойности
  25. */
  26. функция getPageInfo($alias,$uid,$page)
  27. глобален $db,$pfx;
  28. // ако е зададен псевдоним
  29. ако ($ псевдоним)
  30. $query_page_str = "ИЗБЕРЕТЕ * ОТ `_pages` WHERE `alias` = '' И `is_delete` = '0'"; // искане за псевдоним
  31. иначе // иначе
  32. $query_page_str = "SELECT * FROM `_pages` WHERE `is_mainpage` = '1'"; // поиска главната страница
  33. $query_page = $db->заявка(&$query_page_str);
  34. if($query_page->num_rows query(&$query_page_str);
  35. if($query_page->numRows fetch_object();
  36. ($uid == 0)? $info->page_id = 0 : $info->page_id = &$uid;
  37. $info->page_alias = &$alias;
  38. $info->page_pagenum = &$page;
  39. върне $info;
  40. >

Сега в папката/class създаваме два файла:

Parent.class.php:

  1. информация за страницата = &$информация;
  2. >
  3. /**
  4. * Съставя страница
  5. * @return unknown_type
  6. */
  7. функция getContent()
  8. глобален $домейн;
  9. ob_start();
  10. $head = $this->getDoctype();
  11. $head .= $this->getTitle();
  12. $head .= $this->getMetaInf();
  13. $head .= $this->getIncludes();
  14. $menu = $this->getMenu();
  15. $body = $this->getBody();
  16. require_once $this->template_page;
  17. $страница = ob_get_contents();
  18. $page .= $this->getLastTag();
  19. ob_clean();
  20. $страница = str_replace(«

/».$menu->псевдоним.»/»);

  • друго
  • $menuitem->setAttribute(«връзка»,»
  • /страница/».$menu->id.»/»);

  • if(!empty($menu->title_menu))
  • $menuitem->appendChild($doc->createTextNode($menu->title_menu));
  • друго
  • $menuitem->appendChild($doc->createTextNode($menu->title));
  • $root->appendChild($menuitem);
  • >
  • $xsl = нов DOMDocument;
  • $xsl->load($this->template_menu);
  • $xslt = нов XSLTпроцесор;
  • $xslt->importStylesheet($xsl);
  • връщане $xslt->transformToXML($doc);
  • >
  • /**
  • * Переопредлять в нови класове
  • * @връщане
  • */
  • функция getBody()
  • глобален $db,$pfx;
  • $query_body = $db->query(«SELECT `body` FROM `_pages` WHERE `id` = pageinfo[‘id’]>»);
  • $body_arr = $query_body->fetch_object();
  • върне $body_arr->тяло;
  • >
  • >
  • Сега създайте в папката/template папкатаParent, в която създайте файловеpage.php иmenu.xsl. Първият ще бъде шаблон на страницата, вторият ще бъде шаблон на менюто.

    page.php:

    menu.xsl:

    Така както у нас в системата е регистриран клас за главната страница, просто го определяме. Създавам в папката/class файлMainpage.class.php:

    Да работим над него, ние ще бъдем каквото и да е потомство. В този клас, като пример, можете да преопределите шаблон старници$template_page и в резултат ще бъде използван той, а не този, който е зададен вParent.

    Останало определяне на правилата rewrite’а. За това в директиваDocumentRoot апачи трябва да стоиAllowOverride All. Создаём.htaccess файл в основата на нашия сайт със следното съдържание:

    1. Rewrite Engine On
    2. #страници
    3. RewriteRule ^(.*)/(.*)/$ index.php?alias=$1&uid=$2 [QSA,L]
    4. RewriteRule ^(.*)/$ index.php?alias=$1 [QSA,L]

    QSA - ще ни позволи да добавим променливи от заявката към това GET правило. Тези. /page/1/?a=1 ще стане index.php?alias=page&uid=1&a=1.

    L - показва, че това е последното правило и не е необходимо повече да се прилага.

    И да. Ако сайтът не е в корена, тогава трябва да направитеRewriteBase /dirname или да добавите dirname към правилата.

    Можете също да създадете style.css файлове в папката/template (и да дефинирате active_menu и nonactive_menu там) и script.js - в противен случайfirebug ще се закълне (иматеfirebug, но как правите оформление? :) )

    Защо направих функцията vardump - вижте тук