Minimal 15.02.2011 19:28

Урок, пишем свой движок блога.Урок 3: Обзор папки include.

Продолжаем.

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


Переходим к обзору папки include - тут находятся подключаемые файлы.
Создаем в папке include следующие файлы config.php - отвечает за конфигурацию блога, core.php - ядро блога, filter.php - класс фильтрации данных, function.php - все функции блога, mysql.php - конфигурация базы данных и соединение, tags.php - содержит в себе функции всех служебных тегов, index.html - все тот же и пустой, и папку function - подключает функции блога.

В прошлом уроке был коммент:

Уже второй урок, а рабочего кода всё нет...
Работает совсем чуть-чуть, но работает. Это УЖЕ блог.


Хотите кода? без проблем вот код будет ниже, но отлаживать тогда будем вместе, а то смотрю не терпится.

--------------------------<скрин>-----------------------------------

---------------------------<код>------------------------------------

Файл config.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
&lt;?php

// Название сайта
define('CONFIG_NAME', 'minimal.name');
// Слоган сайта
define('CONFIG_SLOGAN', 'Пишем свой движок блога на PHP и mySQL.');
// Ключивые слова
define('CONFIG_KEYWORDS', 'PHP, MySQL, JavaScript, HTML, CSS');
// Описание сайта
define('CONFIG_DESCRIPTION', 'Это движок блога');
// Авторское право
define('CONFIG_COPYRIGHT', 'Авторские права');
// Счетчик посейщаемости
define('CONFIG_COUNTER', 'Тут счетчик');
// Шаблон сайта
define('CONFIG_THEMES', 'test');
// Локаль сайта
define('CONFIG_LANG', 'ru');
// Вывод кол-во новостей
define('CONFIG_SHOW_POST', 10);
// ВКЛ / ВЫКЛ - Режим отладки
define('CONFIG_DISPLAY_ERRORS', 1);
// Логин администратора
define('CONFIG_LOGIN', 'root');
// Пароль администратора
define('CONFIG_PASS', 'root');
// E-mail администратора
define('CONFIG_E_MAIL', 'statusfree@gmail.com');
// Физический путь до корневой директории скрипта
define('CONFIG_ROOT', str_replace('', '/', $_SERVER<'DOCUMENT_ROOT'>) .'/');
// Путь до корневой директории скрипта, по протоколу HTTP
define('CONFIG_HOST', 'http://'. $_SERVER<'HTTP_HOST'> .'/');
// Версия ядра
define('CONFIG_CORE_VERSION', 'v.1.0.0');

?&gt;




define( name, value ); - определяет именованную константу, имя константы задаётся параметром name; значение - параметром value.

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

Файл mysql.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&lt;?php

define ( "DB_LOCATION", "localhost" ); // Имя сервера
define ( "DB_USER", "root" ); // Имя пользователя
define ( "DB_PASSWORD", "" ); // Пароль
define ( "DB_NAME", "minimal" ); // Имя базы данных
define ( "DB_PREFIX", "minimal_blog" ); // Префикс базы данных

//* соединение с базой данных *//
@mysql_connect ( DB_LOCATION, DB_USER, DB_PASSWORD ) or die( 'Сервер базы данных недоступен.' );
@mysql_query ('set names utf-8');
@mysql_query ('set character_set_client=utf8');
@mysql_query ('set character_set_results=utf8');
@mysql_query ('set collation_connection=utf8_general_ci');
@mysql_select_db ( DB_NAME ) or die( 'В настоящий момент база данных не доступна.' );

//* установка русской локали *//
setlocale( LC_ALL, 'ru_RU.UTF-8' );

?&gt;




mysql_connect - Открывает соединение с сервером MySQL
mysql_query - Посылает запрос MySQL
mysql_select_db - Выбирает базу данных MySQL
setlocale - Устанавливает локаль

Файл tags.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
&lt;?php
if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

// контент страницы
$html = str_replace('{content}', $content, $html);

// заголовок страницы
$html = str_replace('{page_title}', $page_title, $html);

// ключивые слова страницы
$html = str_replace('{page_keywords}', $page_keywords, $html);

// описание страницы
$html = str_replace('{page_description}', $page_description, $html);

// Название сайта
$blog_name = CONFIG_NAME;
$html = str_replace('{blog_name}', $blog_name, $html);

// Слоган сайта
$blog_slogan = CONFIG_SLOGAN;
$html = str_replace('{blog_slogan}', $blog_slogan, $html);

// Путь до корневой директории скрипта, по протоколу HTTP
$blog_url = CONFIG_HOST;
$html = str_replace('{blog_url}', $blog_url, $html);

// Ключивые слова
$keywords = CONFIG_KEYWORDS;
$html = str_replace('{config_keywords}', $keywords, $html);

// Описание сайта
$description = CONFIG_DESCRIPTION;
$html = str_replace('{config_description}', $description, $html);

// Авторское право
$copyright = CONFIG_COPYRIGHT;
$html = str_replace('{copyright}', $copyright, $html);

// Счетчик посейщаемости
$counter = CONFIG_COUNTER;
$html = str_replace('{counter}', $counter, $html);

// Темы блога
$menu_category = get_menu_category();
$html = str_replace('{menu_category}', $menu_category, $html);

function get_menu_category()
{

$html = '';
$sql_menu_category = 'SELECT '.DB_PREFIX.'_category.id_category, '.DB_PREFIX.'_category.title_category, '.DB_PREFIX.'_category.url_category, COUNT('.DB_PREFIX.'_post.id_category) count_post FROM '.DB_PREFIX.'_category LEFT JOIN '.DB_PREFIX.'_post ON '.DB_PREFIX.'_post.id_category = '.DB_PREFIX.'_category.id_category GROUP BY '.DB_PREFIX.'_category.orders';
$res_menu_category = mysql_query( $sql_menu_category ) or die ('Ошибка: ' . mysql_error());
$html = $html.'<ul>'."\n";
if (mysql_num_rows($res_menu_category) == 0)
{
$html = $html.'<li>'.LANG_NOT_RECORDS.'</li>'."\n";
} else {
while( $menu_category = mysql_fetch_array( $res_menu_category ) )
{
$html = $html.'<li><a href="/category/'.$menu_category<'url_category'>.'.html">'.$menu_category<'title_category'>.'</a> <sup>'.$menu_category<'count_post'>.'</sup></li>'."\n";
}
}

$html = $html.'</ul>'."\n";
return $html;
}
?&gt;




Файл filter.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
&lt;?php
if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

class filter
{
public function html_filter($input)
{
$text = preg_replace('%&\s*\{<^}>*(\}\s*;?|$)%', '', $input);
$text = preg_replace('/<<>>/', '', $text);
if(!get_magic_quotes_gpc())
{
$text = addslashes($text);
}
$badwords = array('input', 'union', 'script', 'select', 'update', 'script', 'http://');
$text = str_replace($badwords, '', $text);
return $text;
}

public function latin($input)
{
if(preg_match('/<^a-z,A-z,0-9,_>/i', $input))
{
return true;
} else {
return false;
}
}

public function num($input)
{

if(preg_match('<^0-9>', $input))
{
return true;
} else {
return false;
}
}

public function text($input)
{
if(preg_match('<^a-z,A-Z,0-9,_,->ui', $input))
{
return true;
} else {
return false;
}
}

public function email($input)
{
$check = '/^<a-z0-9>+(\.</a-z0-9><a-z0-9>+)*';
$check.= '@(<-a-z0-9>+\.)+(<a-z>{2,3}';
$check.= '|info|aero|name)$/ix';

if (preg_match($check, $input))
{
return false;
} else {
return true;
}
}
}
?&gt;
</a-z></a-z0-9>




Файл core.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
&lt;?php

if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

// подключаем класс фильтрации
include ('include/filter.php');
// обьявляем класс фильтрации
$filter = new filter;
// подключаем функции блога
require ('include/function.php');
// загружаем шаблон
if ( is_file('themes/'.CONFIG_THEMES.'/main.tpl') )
{
$html = file_get_contents('themes/'.CONFIG_THEMES.'/main.tpl');
} else {
exit('Ошибка: Не найден шаблон main.tpl.');
}
// выводим заголовок страницы
$page_title = LANG_SHOW_LIST;
// выводим ключивые слова страницы
$page_keywords = '';
// выводим описание страницы
$page_description = '';
// выводим контент
$content = get_content( $filter );
// подключаем список тегов
include ('include/tags.php');
// выводим в выходной поток (браузер)
echo $html;

?&gt;




Файл function.php

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
&lt;?php

if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

function get_content( $filter )
{
if (isset( $_GET<'function'> ))
{
$value_function = $filter-&gt;html_filter( $_GET<'function'> );
if($filter-&gt;latin($value_function))
{
exit('Ошибка: Некорректное значение "function".');
} else {
$GET = array( 'show_list', 'show_post' );
if ( in_array( $value_function, $GET ) )
{
$get_function = $value_function;
} else {
$get_function = 'show_list';
}
}
} else {
$get_function = 'show_list';
}

switch ( $get_function )
{
case 'show_list':
include ('include/function/show_list.php');
return show_list ( $filter ); break;
case 'show_post':
include ('include/function/show_post.php');
return show_post ( $filter ); break;
default:
show_list ();
}
}
?&gt;




Файл function/show_list.php

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
&lt;?php

if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

function show_list ()
{
$html = '';

// навигация
$sql_total = 'SELECT COUNT(*) FROM '.DB_PREFIX.'_post WHERE 1';
$res_total = mysql_query( $sql_total );
$total = mysql_num_rows( $res_total );
if ( isset($get_page) )
{
$page = $get_page;
if ( $page &lt; 1 ) $page = 1;
} else {
$page = 1;
}

$cnt_pages = ceil( $total / CONFIG_SHOW_POST );
if ( $page &gt; $cnt_pages ) $page = $cnt_pages;
$start = ( $page - 1 ) * CONFIG_SHOW_POST;

// вывод
if ($total == 0)
{
// Если нет постов, выводим сообщение об этом
$html = $html.'<p>not</p>'."\n";

} else {
$sql_show_post = 'SELECT *, '.DB_PREFIX.'_post.id_post AS id_post, '.DB_PREFIX.'_post.title_post AS title_post, '.DB_PREFIX.'_category.title_category AS title_category, DATE_FORMAT(datetime_post, "%d|%m|%Y|%H|%i|%s") AS modified_datetime FROM '.DB_PREFIX.'_post, '.DB_PREFIX.'_category WHERE '.DB_PREFIX.'_category.id_category = '.DB_PREFIX.'_post.id_category ORDER BY datetime_post DESC LIMIT '.$start.', '.CONFIG_SHOW_POST.'';
$res_show_post = mysql_query( $sql_show_post ) or die ('Ошибка: ' . mysql_error());
while( $show_post = mysql_fetch_array( $res_show_post ) )
{
$title_category = $show_post<'title_category'>;
$url_category = 'category/'.$show_post<'url_category'>.'.html';
$title_post = $show_post<'title_post'>;
$url_post = 'category/'.$show_post<'url_category'>.'/post/'.$show_post<'url_post'>.'.html';
$text_short_post = $show_post<'text_short_post'>;
$array_datetime = $show_post<'modified_datetime'>;
$show_datetime = explode('|',$array_datetime);
$date_post = $show_datetime<0>.'.'.$show_datetime<1>.'.'.$show_datetime<2>;
$time_post = $show_datetime<3>.':'.$show_datetime<4>;
$html = $html.file_get_contents('themes/'.CONFIG_THEMES.'/function_show_list.tpl');
$html = str_replace('{title_category}', $title_category, $html);
$html = str_replace('{url_category}', $url_category, $html);
$html = str_replace('{title_post}', $title_post, $html);
$html = str_replace('{url_post}', $url_post, $html);
$html = str_replace('{text_short_post}', $text_short_post, $html);
$html = str_replace('{date_post}', $date_post, $html);
$html = str_replace('{time_post}', $time_post, $html);
}

// навигация
if ( $cnt_pages &gt; 1 )
{
// Проверяем нужна ли стрелка "В начало"
if ( $page &gt; 3 )
{
$startpage = '<a href="/page_1.html">1</a> ... ';
} else {
$startpage = '';
}

// Проверяем нужна ли стрелка "В конец"
if ( $page &lt; ($cnt_pages - 2) )
{
$endpage = ' ... <a href="/page_'.$cnt_pages.'.html">'.$cnt_pages.'</a>';
} else {
$endpage = '';
}

// Находим две ближайшие станицы с обоих краев, если они есть
if ( $page - 2 &gt; 0 )
{
$page2left = ' <a href="/page_'.($page - 2).'.html">'.($page - 2).'</a> | ';
} else {
$page2left = '';
}

if ( $page - 1 &gt; 0 )
{
$page1left = ' <a href="/page_'.($page - 1).'.html">'.($page - 1).'</a> | ';
} else {
$page1left = '';
}

if ( $page + 2 &lt;= $cnt_pages )
{
$page2right = ' | <a href="/page_'.($page + 2).'.html">'.($page + 2).'</a>';
} else {
$page2right = '';
}

if ( $page + 1 &lt;= $cnt_pages )
{
$page1right = ' | <a href="/page_'.($page + 1).'.html">'.($page + 1).'</a>';
} else {
$page1right = '';
}

// Выводим меню
$html = $html.'<p>Страницы: '.$startpage.$page2left.$page1left.'<b>'.$page.'</b>'.$page1right.$page2right.$endpage.'</p>'."\n";
}
}
return $html;
}
?&gt;




Файл БД

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
--
-- База данных: `minimal`
--

-- --------------------------------------------------------

--
-- Структура таблицы `minimal_blog_category`
--

CREATE TABLE IF NOT EXISTS `minimal_blog_category` (
`id_category` int(11) NOT NULL AUTO_INCREMENT,
`title_category` varchar(250) CHARACTER SET utf8 NOT NULL,
`url_category` varchar(250) CHARACTER SET utf8 NOT NULL,
`orders` int(11) NOT NULL,
PRIMARY KEY (`id_category`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

--
-- Дамп данных таблицы `minimal_blog_category`
--

INSERT INTO `minimal_blog_category` (`id_category`, `title_category`, `url_category`, `orders`) VALUES
(1, 'Тестовая', 'test', 1),
(2, 'PHP', 'php', 2),
(3, 'mySQL', 'mysql', 3);

-- --------------------------------------------------------

--
-- Структура таблицы `minimal_blog_post`
--

CREATE TABLE IF NOT EXISTS `minimal_blog_post` (
`id_post` int(11) NOT NULL AUTO_INCREMENT,
`id_category` int(11) NOT NULL,
`title_post` varchar(250) CHARACTER SET utf8 NOT NULL,
`url_post` varchar(250) CHARACTER SET utf8 NOT NULL,
`text_short_post` text CHARACTER SET utf8 NOT NULL,
`text_full_post` longtext CHARACTER SET utf8 NOT NULL,
`keywords_post` text CHARACTER SET utf8 NOT NULL,
`description_post` text CHARACTER SET utf8 NOT NULL,
`datetime_post` datetime NOT NULL,
PRIMARY KEY (`id_post`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Дамп данных таблицы `minimal_blog_post`
--

INSERT INTO `minimal_blog_post` (`id_post`, `id_category`, `title_post`, `url_post`, `text_short_post`, `text_full_post`, `keywords_post`, `description_post`, `datetime_post`) VALUES
(1, 1, 'Test', 'test', 'тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест ', 'тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест тест ', 'test', 'test', '2011-02-15 21:30:13'),
(2, 1, 'test2', 'test2', 'тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест ', 'тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест тестовая новость тест ', 'test2', 'test2', '2011-02-15 21:31:40'),
(3, 3, 'ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ', 'tralya_lya_lay', 'ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ ', 'ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ', 'ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ', 'ТРАЛЯ ЛЯЛЯ ТРАЛЯ ЛЯ-ЛЯЯЯ ЛЯ ЛЯ', '2011-02-15 23:10:41'),
(4, 2, 'Пост как пост!', 'post_kak_post', 'Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! ', 'Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! Пост как пост! ', 'post', 'post', '2011-02-15 23:15:30');




ДОМАШНИЕ ЗАДАНИЕ
По совету exelens я даю домашние задание, раз тут все такие ГУРУ кода.

Задание!
Дописать функцию вывода ключевых слов, и описания для каждого поста.
Кто справится получит уважу от меня и exelens, да и от всех пользователей.
Сколько дать времени?

На все про все вам сутки, если не справитесь тогда я сам напишу.
И будет видно кто тут якается а кто пишет реально.


ПРОДОЛЖЕНИЕ СЛЕДУЕТ!

Урок 1 / Урок 2


Тэги: blog cms mysql php Урок
+ 0 -
Похожие Поделиться

Minimal 15.02.2011 19:32 #
Для ребят кто не особо шарит, извините, подробное описание кода будет позже.
_DM_ 15.02.2011 20:00 #
Константы вы любите использовать, а вот в этом случае вам чем то они не угодили...
if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');

Жаль полноценного шаблонизатора нету, интересно как реализовали бы. Можно уж было и пых код в шаблонах явным образом держать в таком случае. А то одна нога <- здесь, другая -> там.
Minimal 15.02.2011 20:04 #
да все как то в попыха, да в попыха все ;)
в будущем все реализуем
wiz 16.02.2011 08:41 #
Лучше не пыхай, а потерпи и выкладывай сразу готовый пост, а не эти полуфабрикаты.
Minimal 15.02.2011 20:21 #
есть какие нибудь идеи ?
_DM_ 15.02.2011 20:37 #
Если вы насчёт первой строки - в index.php можно задавать константу, и в остальных скриптах если она не определена, делать exit.

А насчёт шаблонизатора одну идею уже описал :) То, чем в большинстве случаев маленькие странички и обходятся... шаблоны, содержащие php код.
Все иные варианты предполагают уже более комплексный подход к разработке, и желательно не структурный.
_DM_ 15.02.2011 20:42 #
Хотя... как то помню просили на коленке собрать примитивный шаблонизатор, но лишь бы в php коде не было никакого упоминания HTML.
В таком случае для элементов типа ul li отделались загрузкой шаблона элементов li, который пустили по циклу, а потом обернули это всё в шаблон-обёртку ul + шаблон ошибок/не существующих элементов.
Minimal 15.02.2011 20:51 #
спасибо за мысли
skylex 15.02.2011 21:35 #
ну или в .htaccess прописать

<Files *>
Order Deny,Allow
Deny from all
</Files>
Minimal 15.02.2011 21:52 #
да, про это я писал, спасибо.
inst 16.02.2011 19:04 #
Константы вы любите использовать, а вот в этом случае вам чем то они не угодили...
if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!');
А судя по этому комменту, такой подход вообще лучше не использовать.
_DM_ 16.02.2011 20:21 #
А кто сказал что именно так реализовывать надо? :) Зачем какие то проверки на подключаемые файлы делать, если можно примитивный boolean в константу внести в index.php
inst 16.02.2011 21:46 #
да это понятно. Тут Я в какой-то степени согласен, однако лишняя константа на то и лишняя, чтоб попытаться от неё избавиться :)
_DM_ 16.02.2011 21:54 #
А в чём она лишняя?
В данном примере вся конфигурация на константах, о них ничего не хотите сказать?
inst 17.02.2011 19:44 #
Я думал, наша дискуссия уже вышла за рамки данного примера.

И да, хочу, Я в своём коде вообще избавился от констант при конфигурации в пользу класса-синглтона. Я уже говорил об этом.
inst 15.02.2011 22:46 #
Простыню из str_replace'ов в файле tags.php можно заменить на один вызов strtr.

Типа как-то так:
$html = strtr( $html, array(
'{content}' => $content,
'{page_title}' => $page_title,
// ...
'{menu_category}' => get_menu_category()
) );
Так ты и от лишних переменных избавишься, и чисто визуально, как по мне, такой код проще сопровождать.

А вообще, про шаблонизатор уже сказали.


Также, про фильтры рекомендую почитать, например, на phPRO (если конечно с енглишом всё норм). Всё-таки, если есть в языке такая стандартная плюшка, то зачем её игнорировать?
Minimal 15.02.2011 22:53 #
Спасибо, здоровый ответ, применю обязательно твой совет. +1
_DM_ 16.02.2011 03:17 #
phPRO... фильтры на пыхе мрачные, к тому же легко осуществимы вручную, что как минимум занимательно. Фильтры все устоены на прегматчах тех же...
Можно узнать, почему выбран strtr, а не str_replace?
inst 16.02.2011 09:36 #
фильтры на пыхе мрачные

В топике тоже не слишком весёлые, кстати.

Фильтры все устоены на прегматчах тех же

Каюсь, не знал. Всё-таки языковые фичи, думал, все на Си.
Но... Всё-таки, если есть в языке такая стандартная плюшка, то зачем её игнорировать? Всё равно ведь ничего сложнее использоваться в этой CMS не будет.
Впрочем это всего лишь моё мнение.

Можно узнать, почему выбран strtr, а не str_replace?

В str_replace надо два массива. Или Я ошибаюсь?
inst 16.02.2011 09:47 #
В str_replace надо два массива.
Имеется ввиду вместо одного.
_DM_ 16.02.2011 15:27 #
strtr предназначен в первую очередь для посимвольной замены. В таком случае работает значительно быстрее.

Документация PHP:
php.net/strtr
php.net/str_replace

Пример str_replace c одним массивом:
$string = "Line 1\nLine 2\rLine 3\r\nLine 4\n";
$search = array( "\r\n", "\n", "\r" );
$replace = "<br />";
$newString = str_replace( $search, $replace, $string );
echo $newString;

Более конкретных цифр по производительности вам не скажу, если вас заинтересует эта тема, поищите в интернетах str_replace vs strtr. Есть сравнение производительности в примерах и даже с графиками :)
_DM_ 16.02.2011 16:16 #
Немного не то понял под фразой "вместо одного массива". Да, необходимо два массива. Но никакой трудности в этом не вижу.
kstep 16.02.2011 16:52 #
Трудность есть. Трудность восприятия.
Гораздо легче читается

$string = strtr($string, array(
'{one}' => $one,
'{two}' => $two,
'{three}' => $three
));

чем

$string = str_replace(array(
'{one}', '{two}', '{three}'
),
array(
$one, $two, $three
), $string);

В первом случая явно видно, что на что заменяется, во втором — надо пропарсить глазами два списка и сопоставить их.

_DM_ 16.02.2011 17:05 #
Разве сложно сделать динамическую подстановку переменных?
kstep 16.02.2011 17:32 #
Не совсем понял, что имеется в виду. Интерполяция типа "${one} or ${two}"?
_DM_ 16.02.2011 17:51 #
В данном случае вариантов много. Как один из них:
$variables = array();
$variables<'one'> = "real one";
$variables<'two'> = $two;
$variables<'three'> = "fifty-five";

addVariable( $variables );
А в конце проходит обработчик выходящего потока, заменяя ключи на их значения.
inst 16.02.2011 18:25 #
KISS же
inst 16.02.2011 18:32 #
+ этот массив, например, в будущем можно вообще парсить из ini-файла, где-нибудь рядом с темой
inst 16.02.2011 18:34 #
это скорее к #cmnt98051 был ответ
_DM_ 16.02.2011 18:41 #
Вот только не надо ini файлов делать... их ещё не хватало... :)
_DM_ 16.02.2011 16:09 #
Не так давно где-то натыкался на обсуждение фильтра e-mail адресов. В итоге выясинилось что он не правильно работает.
Но... Всё-таки, если есть в языке такая стандартная плюшка, то зачем её игнорировать? Всё равно ведь ничего сложнее использоваться в этой CMS не будет.

Согласен, но раз заголовок гласит нам что это "Урок", то я бы не ограничивался в этом плане фильтрами. Лучше про прегматчи те же рассказать как они работают, ещё и ссылки прицепить на объяснение их синтаксиса.

Вот к примеру:
$check = '/^+(\.+)*';
$check.= '@(<-a-z0-9>+\.)+({2,3}';
$check.= '|info|aero|name)$/ix';
Мы здесь видим режимы i - (case insensitive) и x - (free spacing mode). Вот я лично не понимаю зачем нужен здесь X если regex написан без пробелов и переноса каретки.
/x активирует режим "free-spacing mode". В данном режиме пробелы в regex игнорируются и не экранированный символ # начинает комментарий.

Это нужно для регулярок вида:
# Match a 20th or 21st century date in yyyy-mm-dd format
$regex = "/^(19|20)\d\d # year
<- /.> # separator
(0<1-9>|1<012>) # month
<- /.> # separator
(0<1-9>|<12><0-9>|3<01>) # day $/ix"
kirpichtion 16.02.2011 07:23 #
Такое громкое название "Ядро блога", а вы код видели? :) Ну и добавил бы его к index.php? Все равно же на коленке писано :) И еще вопрос по существу: а если я возжелаю (чисто теоретически) две базы данных использовать? Как твой код решит мою задачу?
wiz 16.02.2011 08:40 #
Чисто теоретически не возжелаешь.
Minimal 16.02.2011 10:02 #
Повторяю еще раз, для тех кто не понял еще, да там мало кода, но это только сейчас, ведь это еще не блог, это только первый запуск, там еще много что придется дописать.

P/S вот он пример коммента "абы ляпнуть", коммент не несет не какой смысловой нагрузки.
wiz 16.02.2011 08:42 #
Код лучше выложить на какой-нибудь кодохостинг. Вы ведь знакомы с системами контроля версий?
kstep 16.02.2011 15:54 #
Смотрю я на это всё, и вижу у этого «движка» целый букет детских болезней. Тут отсутствие гибкости, и недостаточность SQL-абстракции (mysql_query() без указания коннекта к базе с захардкоженным SQL), и отсутствие нормальной шаблонизации (упрётесь вот в циклы и условия в шаблонах, упрётесь же, а нормально разделить логику отображения и бизнес-логику при текущей архитектуре очень сложно, если вообще реально)...

Такие поделки писал, наверное, каждый, кто начинал писать сайты на пыхыпе. И как пример движка, написанного новычком, вполне сойдёт. Но учиться писать на этом примере явно не стоит.
Minimal 17.02.2011 10:46 #
Философов тут хватает, лучше что нибудь реальное бы предложил, или идеи подкинул, этот код писан гопом (на коленке), как говорится без всяких ТЗ, много не продумано на 100%.
Я взялся писать это по причине, того что что нечем было заняться вечером.
Предложил вам быстрый код, а вы теперь думайте, а не ждите готовенького идеального блога.

Это бесплатный сыр, а не заказной продукт где надо чтоб были все грани гладкие.
kstep 17.02.2011 11:12 #
Прежде чем писать шедевры самому, предлагаю сперва изучить то, что уже сделано хорошо. Тот же CodeIgniter минималистичный возьми, распечатай и почитай в метро. Или PureMVC какой. Поверь мне, их далеко не дураки писали. Разберись, попробуй несколко идей оттуда. МакКоннела какого почитай для комплекта, он много дельных книг кроме всего прочего советует, так что можешь и по ним потом пройтись. Вот после этого посмотри на свой теперешний код и ты пойм?шь, как его вижу я.
DropSQL 18.02.2011 20:12 #
насколько я понимаю они решили изучить основы php... фреймворки это очень хорошо, сам юзаю Yii :) Но для обучения чистого php можно начать и так как они решили :)
они = он :)
kmarks 18.02.2011 14:02 #
Совет: используйте mysqli_, а лучше PDO.
DropSQL 18.02.2011 19:23 #
Почему вы такии противники классов? шаблонизатор - можно заюзать один класс, хотябы самый элементарный и избавиться от этого мусора:

$html = $html.file_get_contents('themes/'.CONFIG_THEMES.'/function_show_list.tpl');
$html = str_replace('{title_category}', $title_category, $html);
$html = str_replace('{url_category}', $url_category, $html);
...
$html = str_replace('{time_post}', $time_post, $html);

Защита от SQL inj - это PDO
Фильтр xss лучше сразу заюзать htmlpurifier, если учить новичков, то сразу не забывать учить готовые разработки которые очень хороши в даном вопросе.
or die ('Ошибка: ' . mysql_error());
это очень плохой вариант, лучше юзать исключения (try{}catch(){})
в function/show_list.php строка if (stristr($_SERVER<'SCRIPT_FILENAME'>, basename(__FILE__))) exit('Ошибка: Доступ запрещен!'); бесплезна, потому как внутри функция которая на этой же странице не вызывается
Вот ссылка на говно-шаблонизатор который я писал года 3 назад дет :) хотябы так... если нужно могу дописать, хотя в таком давно не нуждаюсь :)

if ( is_file('themes/'.CONFIG_THEMES.'/main.tpl') )
{
$html = file_get_contents('themes/'.CONFIG_THEMES.'/main.tpl');
} else {
exit('Ошибка: Не найден шаблон main.tpl.');
}

Подобных конструкций и подавно лучше избегать, так как проще сделать чтот вроде мини шаблонизатор и сделать обработчик, а лучше глобальный try{}catch(){}
В общем думаю на сегодня хватит комментариев :) если что пишите, с удовольствием поучавствую в обучении :)
_DM_ 22.02.2011 13:03 #
К сожалению конструкция try catch очень сильно проигрывает по скорости в пыхыпе, но для маленьких сайтов без нагрузки конечно пойдёт.
DropSQL 22.02.2011 15:51 #
Что за глупости? В ОЧЕНЬ высоконагруженых проектах используют в плодь до фреймворков, не гвооря уже о try{}catch(){}. Если брать реально то и сам по себе php довольно медженный и т. д. :) Уже давно никто на мелочи не смотрит.
http://www.stay.com/ - довольно высоконагруженый, yiiframework, то что смог првиести на вскидку.
А вообще не выдумывайте :) Не стоит себе портить жизнь мелочами...
p.S. это не значит что на оптимизацию не стоит вообще обращать внимание, но такие мелочи...
DropSQL 22.02.2011 15:52 #
медженный - тормознутый :)
_DM_ 22.02.2011 16:20 #
Просто не надо их везде кидать =) в примере, который вы привели в них нету критической необходимости... проверять входящие данные - да, но вот шаблоны никак не выдадут ошибку если мы не меняем файловую систему.
DropSQL 22.02.2011 17:31 #
Вот пример зачем могут быть эти случаи в шаблоне... а в catch вывести нужный шаблон с нужной ошибкой, а не тупой текст из exit();
Так что вот, теперь понимаешь зачем оно может быть в шаблонах? :) и это ещё мелочи :)