Функция ЧПУ на php. Создание человеческих ссылок в постах

 

Доброго времени суток дорогой читатель! Добро пожаловать на мой блог! Сегодня мы продолжим работу над циклом "Создать блог с нуля". Нам предстоит задать фундамент модуля ЧПУ, если быть точнее то нам понадобится php функция, которая по имени страницы определит нам id в таблице базе данных. Но прежде чем мы приступим к написанию функции нам необходимо будет создать и настроить файл htaccess. А так же отредактировать нашу таблицу в базе данных, создать новую колонку, в которой мы будем хранить имена страниц.

 

 

На файл htaccess мы сильно отвлекаться не будем, его работа не так уж и сложна, тем более если Вы знакомы с регулярными выражениями в php. Вот, что касается самого модуля ЧПУ, то он представлен в виде двух файлов ( ну можно и в один, но у меня почему то получилось два =) ) и "сети условий" по всему движку. Не пугайтесь, под термином "сети условий", я подразумеваю тот геморрой с автоматической смены ссылок по всему движку! Сегодня мы займемся лишь фундаментом, и добьемся того что бы пост, на странице нашего блога, был доступен по адресу с человеко-понятной ссылкой

Цели я указал в анонсе, так что сейчас пару слов для новоприбывших, и приступим =)

 

Для тех кто на блоге в первые

 

Если Вы на блоге в первый раз, то эта маленькая заметка именно для Вас! Пускай тема ЧПУ обширная и применима к любому проекту, Вам, именно в материале на этой странице, будет очень сложно выявить что-то полезное для себя, по причине того, что этот пост, как и большинство на моем блоге, является частью цикла статей "Создать блог с нуля". Цикл ориентирован на аудиторию которая хочет на практике научится программировать на php. Если Вы из таких, то добро пожаловать! Переходите по ссылке, что я дал Вам выше и приступайте к изучению изложенного мной материала

Если Вы собираетесь задержаться на моем блоге, то подпишитесь на RSS ленту блога через ридер, или же по почте

 

Новая колонка в таблице базы данных

 

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

Заходим в структуры таблицы blog, и после id создаем новую колонку

 

создаем новую колонку в таблице базы данных

 

Заполняем поля приблизительно вот так ( имя поля nameurl )

 

заполняем поля, создавая новую колонку в таблице базы данных

 

Теперь, необходимо заполнить новую колонку. У меня лишь одна запись в базе данных, поэтому для меня заполнение новой колонки не является проблемой =)

 

заполняю новую колонку в таблице базы данных

 

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

Я для тестовой странице использовал вот такое имя: dobro-pozhalovat.html

Ну чтож, с этой задачей мы справились, теперь приступим к самому файл htaccess

 

Создаем файл htaccess

 

Создавать лучше всего с помощью программы Notepad++, ибо в некоторых случаях виндоус ругается, что у файла нет имени, ведь имени и в правду нет =) только расширение .htaccess

На всякий случай я скину Вам файл, вот он. Этот файл необходимо поместить в корень нашего блога

 

правильное размещение файла htaccess

 

Содержимое файла следующее:

RewriteEngine on
RewriteRule ^post/([-a-z0-9]+.html)$ index.php?post=$1 [L]
RewriteRule ^category/([-a-z0-9]+.html)$ index.php?category=$1 [L]
RewriteRule ^contacts.html$ index.php?contact=1 [L]

Первая строчка включает возможность перенаправления с динамических ссылок на ЧПУ. Вторая отвечает за ссылки на посты. То есть если ссылка будет вот такого вида

http://rsblog.ru/post/dobro-pozhalovat.html

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

Третья строчка отвечает за ссылки к категориям

http://rsblog.ru/category/testovaya-kategoriya.html

Ну и последняя строчка отвечает за ссылку ведущая на форму обратной связи

http://rsblog.ru/contacts.html

Обратите внимание что регулярное выражение находится в скобках, если Вы знакомы с регулярками, то прекрасно знаете, что скобки это сохранение. Вопрос, куда переносятся сохраненные данные? Ответ: В переменную 1. Да, именно 1 (единица).

Если Вам нужны ЧПУ без .html то редактируйте регулярное выражение в файле htaccess, на такой вид ссылок, который Вам нужен!

Особо останавливаться тут не будем, я многое тут не знаю, поэтому долго разглагольствовать на эту тему не имею право, единственное что бы я еще добавил, это пару слов о флаге [L]. Я может и ошибаюсь, но как я понял этот флаг останавливает проверки, что идут ниже, это что-то типа break (прерывание работы всего цикла) у циклов.

Под итожу то что написано в файле htaccess: Условия, для каждого вида станиц которые есть у нашего движка, а именно

  • для постов
  • для категорий
  • для страницы контактов

Если Вы знакомы с регулярками, то разобраться в файле Вам не составит труда.

 

php функция chpu() - Алгоритм поиска id записи в таблице базы данных

 

Начнем с создания алгоритма поиска. Для этого нам понадобится знать в какой таблице искать и что искать. У Вас может возникнуть вопрос, что значит в какой таблице? Ведь таблица у нас одна - blog. Это не совсем так, сегодня мы рассматриваем только посты, но так же нам известно, что у категорий тоже есть свои ссылки, а таблица которая будет содержать имена категорий называется menu, именно поэтому алгоритм должен знать в какой таблице ему искать. Пускай функция chpu() на данном этапе будет работать лишь на половину, зато в следующих постах нам не придется редактировать ее (функцию).

Создаем файл chpu.php помещаем его в пользовательские модули нашего движка, и пишем в этом файле следующую функцию:

<?
function chpu($url,$dirDB)//функция ЧПУ
{
//$url - имя с помощью которого мы определим id
//$dirDB - режим, с помощью которого мы определим в какой таблице базы данных нам искать
//определяем запрос в зависимости от того какую страницу открывает пользователь (текст поста или категорию)
if($dirDB == "post")$sql = "SELECT id FROM blog WHERE nameurl = '$url'";//текст поста
if($dirDB == "category")$sql = "SELECT id FROM menu WHERE nameurl = '$url'";//категория

$result_index = mysql_query($sql);//Выводим из базы статью
$myrow_index = mysql_fetch_array($result_index);

if($myrow_index != "") return $myrow_index[id];//если найдена строчка в БД выводим id
else return "";//если нет, выводим пустоту
}
?>

Функция очень простая, так что не будет на ней останавливаться, тем более я уже не раз разъяснял логику поиска id в таблице.

 

Скрипт позволяющий определить какая страница открыта

 

Цель этого скрипта определить в каком режиме запустить функцию chpu(). Определить это можно по GET запросу который создает нам сервер при обращение к станице по ЧПУ. Если Вы внимательно смотрели содержимое файла htaccess, и приблизительно поняли его работу, то Вы должны догадаться, что сервер для себя определяет ссылку вот такого вида

http://rsblog.ru/index.php?post=dobro-pozhalovat.html

То есть, если пользователь обратился к станице с помощью ЧПУ то сервер создаст GET запрос post, создание такого запроса сигнализирует нам о том что пользователь обратился на страницу поста, стало быть функцию chpu() необходимо запускать в режиме поиска id в таблице blog

Создаем файл getchpu.php, сохраняем его в папке пользовательских модулей и пишем в нем следующий скрипт

<?
if($chpu == 1)//если блог работает в режиме вкл ЧПУ
{
include("moduls/chpu.php");
//GET ПЕРЕМЕННАЯ post
if(isset($_GET['post']))
{
if(!preg_match("/^[-a-z0-9]+\.html$/",$_GET['post']))//если имя не корректное,то переносим
{
header("location: ".$server_root);//на главную страницу
exit;
}
$blog = chpu($_GET['post'],"post");//по имени страницы достаем из бд id
if($blog == "")//если результат функции пустота, то переносим пользователя
{
header("location: ".$server_root);//на главную страницу
exit;
}
}
//GET ПЕРЕМЕННАЯ post
//GET ПЕРЕМЕННАЯ category
if(isset($_GET['category']))
{
if(!preg_match("/^[-a-z0-9]+\.html$/",$_GET['category']))//если имя не корректное,то переносим
{
header("location: ".$server_root);//на главную страницу
exit;
}
$cat = chpu($_GET['category'],"category");//по имени страницы достаем из бд id
if($cat == "")//если результат функции пустота, то переносим пользователя
{
header("location: ".$server_root);//на главную страницу
exit;
}
}
//GET ПЕРЕМЕННАЯ category
}
?>

Логика скрипта следующая:

  • Скрипт будет работать только в случае если блог работает в режиме вкл ЧПУ, то есть переменная chpu равна единице (это сделано для того чтобы режимы можно было поменять воздействуя лишь на одну переменную)
  • Далее подключается функция поиска id в базе данных
  • Дальше идут два варианта развития, и оба они работают по той же логике, то есть если существует GET запрос post или category то запускается проверка на корректность имени. Эта проверка поможет избежать простейших способов взлома нашего движка. Если проверка прошла успешно (если же нет, то нас перекинет на главную страницу) запускается функция chpu(), тем самым в переменную blog или cat (в зависимости от того какая часть скрипта будет работать =)) попадет id записи в базе данных. Если переменная пустая, то нас перекинет на главную страницу.

Если Вы создаете ссылки без .html, то Вам придется переделать регулярное выражение, ибо Ваши ссылки не пройдут проверки!

Тут есть один момент. Если Вы писали движок с самого начала курса, то у Вас скорее всего нет переменной server_root. Если Вы ставили копию движка, что я давал в посте "Установка нашей CMS", то эта переменная у Вас есть.

Если у Вас нет этой переменной, то откройте пользовательский файл index.php, и сразу после подключение к базе данных пропишите эту переменную

//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
$nameDB = "rsblog";//Название БД
$nameSERVER = "localhost";//Сервер
$nameUSER = "root";//Имя пользователя БД
$passUSER = "";//Пароль пользователя БД
mysql_select_db($nameDB, mysql_connect($nameSERVER,$nameUSER,$passUSER));

$server_root = "http://адрес_вашего_блога.ru/";
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)

Значение переменной является адрес Вашего блога. Эта переменная необходима была в админке для авторизации, тут же она необходима для реализации ЧПУ, в частности для тега <base> что мы применим чуть ниже.

 

Подключаем модуль ЧПУ к нашему движку

 

Открываем пользовательский файл index.php, и сразу после подключения к базе данных пишем вот такой код

$chpu = 1;//настройка включение выключение ЧПУ (1 - вкл; 0 - выкл)

//ЧЕЛОВЕКО-ПОНЯТНЫЙ УРЛ
include("moduls/getchpu.php");
//ЧЕЛОВЕКО-ПОНЯТНЫЙ УРЛ

Первая строчка, как Вы поняли, ручное включение режима ЧПУ. Вторая строчка, подключение скрипта позволяющая определить открываемую страницу, в этом же скрипте подключается алгоритм поиска записей.

Теперь в самом низу, перед строчкой

include("templates/index.html");//Подключение шаблона

Создаем переменную urlsite

$urlsite = $server_root;

Эта переменная необходима для того чтобы определить базовую ссылку сайта. В шаблоне index.html после строчки

<meta name="keywords" content="<?=$header_metaK?>">

вставляем вот такой тег

<base href="<?=$urlsite?>">

Этот тег позволяет определить корень сайта, тем самым мы избавимся от глюка который мешает правильно определить пути к стилям. Если не поместить этот тег в код шаблона, то все страницы находящиеся по ЧПУ перестанут грузить стили, ява скрипты, и если я не ошибаюсь то и картинки

 

Заключение

 

Теперь при заходе на страницу http://rsblog.ru/post/dobro-pozhalovat.html я попадаю на страничку статьи

 

пример работы ЧПУ

 

а Вы? =)

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

Если у Вас есть какие вопросы, то пользуйтесь формой ниже

Если Вы еще не подписаны на мой блог, исправляйте дело и подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы точно не пропустите новые заметки на блоге

Всего Вам наилучшего! У меня Все!

Исходник

________

P.S.: В интернете нашел подборку довольно не плохих статей на тему веб-дизайн, если кто-то видит себя в будущем как дизайнера, то обязательно почитайте эти статьи, очень полезная информация.

 

Возможно Вам будут интересны следующие заметки

Комментарии (59)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Вы не подтвердили условия политики конфиденциальности.
dimfed, 24 Февраля 2013 г. 17:35 пишет:
Гость
дописываю блог свой. Воспользуюсь вашим методом ЧПУ, нравится мне он. Только вот функцию ЧПУ думаю стоит обезопасить. Посылаем сразу голый ГЕТ запрос (даже при условии регулярной предосторожности) пусть стоит в функции чпу = strip_tags($url); htmlspecialchars($url);
mysql_escape_string($url);
FLASH911, 05 Ноября 2013 г. 13:46 пишет:
Читатель
Здравствуйте, делаю ЧПУ на CMS, которая сделана в основном по вашим урокам. Не могу понять как сделать ЧПУ в категориях без .html, а в виде site/categoriya1/. Пытаюсь править .htacces и getchpu - получаю ошибки... Не могли бы Вы рассказать как это сделать? Заранее спасибо.
Алексей, 05 Ноября 2013 г. 15:31 пишет:
Автор
По идеи, нужно .html выпилить из следующих файлов:
1. .htaccess
2. getchpu
Далее файлы из админ панели. При условии что вы дошли до этой статьи
3. addcontent.php
4. allcontent.php
5. addmenu.php
6. eddmenu.php
Ответ для пользователя: FLASH911
FLASH911, 06 Ноября 2013 г. 20:18 пишет:
Читатель
А можно пример с исправленными первыми двумя файлами? А то вроде выкидываю .html, а он на главную скидывает.
Алексей, 07 Ноября 2013 г. 09:25 пишет:
Автор
Я так понял, что Вам нужно выпилить .html только для категорий. Тогда .htaccess должен выглядеть приблизительно вот так:
RewriteEngine on
RewriteRule ^post/([-a-z0-9]+.html)$ index.php?post=$1 [L]
RewriteRule ^category/([-a-z0-9]+)/$ index.php?category=$1 [L]
RewriteRule ^contacts.html$ index.php?contact=1 [L]
Сам файл getchpu.php будет выглядеть вот так:
if($chpu == 1)//если блог работает в режиме вкл ЧПУ
{
	include("moduls/chpu.php");
	//GET ПЕРЕМЕННАЯ post
	if(isset($_GET['post']))
	{
	    if(!preg_match("/^[-a-z0-9]+\.html$/",$_GET['post']))//если имя не корректное,то переносим
	    {
	        header("location: ".$server_root);//на главную страницу
	        exit;
	    }
	    
		$blog = chpu($_GET['post'],"post");//по имени страницы достаем из бд id
	    
		if($blog == "")//если результат функции пустота, то переносим пользователя
	    {
	        header("location: ".$server_root);//на главную страницу
	        exit;		
	    }
	}
	//GET ПЕРЕМЕННАЯ post
	//GET ПЕРЕМЕННАЯ category
	if(isset($_GET['category']))
	{
	    if(!preg_match("/^[-a-z0-9]+\/$/",$_GET['category']))//если имя не корректное,то переносим
	    {
	        header("location: ".$server_root);//на главную страницу
	        exit;
	    }
	    
		$cat = chpu($_GET['category'],"category");//по имени страницы достаем из бд id
	    
		if($cat == "")//если результат функции пустота, то переносим пользователя
	    {
	        header("location: ".$server_root);//на главную страницу
	        exit;		
	    }
	}
	//GET ПЕРЕМЕННАЯ category
}
Ответ для пользователя: FLASH911
FLASH911, 07 Ноября 2013 г. 09:37 пишет:
Читатель
К сожалению не заработало, может из-за того, что я выпилил /post/ из .htaccess? И теперь у меня сами посты отображаются без /post/?
Ответ для пользователя: Алексей
Алексей, 07 Ноября 2013 г. 09:42 пишет:
Автор
Да. Из-за этого. Данный ЧПУ определяет что открыто по словам /post/ и /category/. В RS-BLOG 2.8.0 сделано все немного по другому. Но там почти весь механизм по работе с ЧПУ переделан.
Ответ для пользователя: FLASH911
FLASH911, 07 Ноября 2013 г. 09:51 пишет:
Читатель
Поменял местами в getchpu пост и категории, а также закомментировал эти строки:
if(!preg_match("/^[-a-z0-9]+\/$/",$_GET['category']))//если имя не корректное,то переносим
{
	header("location: ".$server_root);//на главную страницу
	exit;
}
Теперь работает, но я так понимаю не производится проверка правильности адреса. Также хотелось бы убрать /category/ из адреса категории, если это возможно.
Алексей, 07 Ноября 2013 г. 09:57 пишет:
Автор
Вы получали копию RS-BLOG 2.8.0? Там реализованы ЧПУ вот такого вида:
http://site.ru/razrabotka-cms/uluchshenija/ - Категория
http://site.ru/razrabotka-cms/uluchshenija/funkcija-chpu.html - Заметка
Можете глянуть как там работает. Весь механизм в файлах (Если мне память не изменяет):
1. htaccess
2. getchpu.php
3. gettransform.php
Ответ для пользователя: FLASH911
FLASH911, 08 Ноября 2013 г. 17:16 пишет:
Читатель
Глянул, разобрался, большое спасибо за советы! Теперь вот думаю, а нужно ли все переводить на mysqli вместо mysql? Есть ли в этом смысл?
Алексей, 08 Ноября 2013 г. 20:23 пишет:
Автор
Смысл есть огромный, т.к. в будущих версиях php (в какой то версии выше 5.4) модуль mysql будет выпилен...
Ответ для пользователя: FLASH911
FLASH911, 09 Ноября 2013 г. 09:30 пишет:
Читатель
А у Вас на блоге не будет статей по теме перевода на MySQLi? А то mysqli для меня вообще темный лес...
Ответ для пользователя: Алексей
FLASH911, 09 Ноября 2013 г. 11:54 пишет:
Читатель
Хотелось бы хотя бы иметь представление как реализовать этот переход на уровне подключения и модуля новости главной.
Ответ для пользователя: Алексей
Алексей, 12 Ноября 2013 г. 10:36 пишет:
Автор
Все зависит от того как реализован механизм обращения к БД в системе. Если как в RS-BLOG, то переход будет вызывать некую попоболь, ибо обертки по работе с sql запросами нет, и придется в каждом файле прописывать вместо
mysql_query()
вот так
mysqli_query()
mysqli отличается от mysql (в плане работы с ними) не значительными деталями.
Например в mysql подключение к БД производилось вот так:
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
$nameDB     = "blog";//Название БД
$nameSERVER = "localhost";//Сервер
$nameUSER   = "root";//Имя пользователя БД
$passUSER   = "";//Пароль пользователя БД
mysql_select_db($nameDB, mysql_connect($nameSERVER,$nameUSER,$passUSER));	
//ПОДКЛЮЧЕНИЕ К БАЗЕ ДАННЫХ (БД)
А в mysqli будет производится вот так:
$nameDB     = "blog";//Название БД
$nameSERVER = "localhost";//Сервер
$nameUSER   = "root";//Имя пользователя БД
$passUSER   = "";//Пароль пользователя БД

$db = mysqli_connect(
        $nameSERVER,
        $nameUSER,
        $passUSER,
        $nameDB
);
Изменения как видите небольшие. Да, кстати хочу заметить, что результат функции mysqli_connect() (который помещен, в моем примере, в переменную $db) теперь обязателен. Сейчас поясню на примере почему он обязателен.
В mysql обращение к БД производилось вот так:
$result   = mysql_query("SELECT * FROM table");
$myrow    = mysql_fetch_array($result);
В mysqli обращение к БД выглядит вот так:
$result   = mysqli_query($db, "SELECT * FROM table");
$myrow    = mysqli_fetch_array($result);
Как видно на примере для mysqli очень важно знать с какой БД (выбранная БД лежит в переменной $db) ему необходимо работать.

Вот собственно и все отличия. Ну по крайней мере с процедурным подходом.
Ответ для пользователя: FLASH911
FLASH911, 12 Ноября 2013 г. 17:52 пишет:
Читатель
Огромное спасибо! А то напутали меня тут, что нужно только в ООП работать.
Ответ для пользователя: Алексей
dlegame, 14 Ноября 2013 г. 15:39 пишет:
Читатель
Привет, Алексей! у меня к тебе просьба. помоги пожалуйста
я вот начал изучать Javascript и вот написал вот такой код:
$(document).ready(function() {
	$(function() {
        $("#initpl").toggle(function (){
			$(".getWrapper").css({width: "initial", minWidth: "initial", margin: "10px"})
			$(".getHead").css({width: "initial"})
			$(".getContents").css({width: "initial"})
			$(".getWrapper .getContents .getCol1").css({width: "100%"})
			$(".comments_content").css({width: "initial"})
			$(".commcont").css({width: "auto", minWidth: "100%"})
			$(".comment_cont02").css({width: "auto"})
			$("#header #wrp .headpanel .heads .wrass").css({width: "95%"})
            $("#initpl").text("Уменьшить шаблон")
            .stop();
        }, function(){
			$(".getWrapper").css({width: "900px", minWidth: "900px", margin: "10px auto 10px auto"})
			$(".getHead").css({width: "900px"})
			$(".getContents").css({width: "900px"})
			$(".getWrapper .getContents .getCol1").css({width: "699px"})
			$(".comments_content").css({width: "680px"})
			$(".commcont").css({width: "680px", minWidth: "680px"})
			$(".comment_cont02").css({width: "527px"})
			$("#header #wrp .headpanel .heads .wrass").css({width: "960px"})
            $("#initpl").text("Увеличить шаблон")
            .stop();
        });
    });
});
и этот код увеличивает короче шаблон и уменьшает и вот я хотел бы сохранять это все в кукисы ну чтобы при обновление страницы оставалось все как после нажатие "Увеличить шаблон"
вот демо: http://udiscuz.sibwebgroup.ru/optimizaciya-udiscuz.shtml
Заранее очень благодарю!
Ответ для пользователя: Алексей
Алексей, 14 Ноября 2013 г. 16:05 пишет:
Автор
Воспользуйтесь плагином для jquery. Плагин называется jquery.cookie, позволяет создавать куки прямо из скрипта javascript.
Вот ссылка на плагин, а вот дока
Ответ для пользователя: dlegame
dlegame, 14 Ноября 2013 г. 16:46 пишет:
Читатель
Да что-то неполучается подключить =(
Ответ для пользователя: Алексей
Алексей, 14 Ноября 2013 г. 17:11 пишет:
Автор
Попробуйте подключить либо более древнюю версию jquery.cookie, либо подключите новую версию jquery
Ответ для пользователя: dlegame
dlegame, 14 Ноября 2013 г. 17:17 пишет:
Читатель
Дак ладно бы было проблема в версиях но я не могу понять как вообще туда и что подключать и вставлять в код =(
Ответ для пользователя: Алексей
Алексей, 14 Ноября 2013 г. 18:11 пишет:
Автор
Записывайте состояние шаблона в куку, вот так:
$.cookie('tpl', 'состояние', { path: '/' });
А в php по куке ($_COOKIE['tpl']) определяйте какую ширину шаблона грузить.
Ответ для пользователя: dlegame
dlegame, 20 Ноября 2013 г. 13:48 пишет:
Читатель
Вообщем перевел я на MySQLi (uDiscuz! fork for RS Blog) и пишет короче такую ошибку:
Warning: mysqli_query() expects parameter 1 to be mysqli, null given in Z:\home\udiscuz.ru\www\source\modules\returnconfig.php on line 18

Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, null given in Z:\home\udiscuz.ru\www\source\modules\returnconfig.php on line 19

Warning: Invalid argument supplied for foreach() in Z:\home\udiscuz.ru\www\source\modules\menu.php on line 35
Template file for uDiscuz! not fount - file: templates//menu.tpl
в файл source/sql/connect.php добавил:
var_dump( $db );
он отобразил:
object(mysqli)#1 (18) {
	["affected_rows"]		=> int(0)
	["client_info"]		=> string(78) "mysqlnd 5.0.8-dev - 20102224 - $Id: 65fe78e70ce53d27a6cd578597722950e490b0d0 $"
	["client_version"]		=> int(50008)
	["connect_errno"]		=> int(0)
	["connect_error"]		=> NULL
	["errno"]			=> int(0)
	["error"]			=> string(0) ""
	["field_count"]		=> int(0)
	["host_info"]		=> string(20) "localhost via TCP/IP"
	["info"]			=> NULL
	["insert_id"]		=> int(0)
	["server_info"]		=> string(6) "5.5.25"
	["server_version"]		=> int(50525)
	["stat"]			=> string(130) "Uptime: 948 Threads: 1 Questions: 52 Slow queries: 0 Opens: 35 Flush tables: 1 Open tables: 4 Queries per second avg: 0.054"
	["sqlstate"]		=> string(5) "00000"
	["protocol_version"]	=> int(10)
	["thread_id"]		=> int(19)
	["warning_count"]		=> int(0)
}
Что я неправильно делаю?))) а вот файлы модулей. посмотрите: http://rghost.ru/50304259
Ответ для пользователя: Алексей
dlegame, 20 Ноября 2013 г. 14:06 пишет:
Читатель
Решил проблему так:
например вот есть функция у модуля:
function returnconfig()
{

$result_page = mysqli_query($db, "SELECT configblog FROM page WHERE id='1'");
$myrow_page = mysqli_fetch_array($result_page);

global $maxSQL;
$maxSQL++;

return $myrow_page['configblog'];
}
и перед
$result_page = mysqli_query($db, "SELECT configblog FROM page WHERE id='1'");
добавляем:
global $db;
Алексей, 20 Ноября 2013 г. 14:08 пишет:
Автор
Попробуйте в файле /modules/returnconfig.php написать вот так:
function returnconfig()
{
    global $db; // делаем переменную с подключением видимой для функции
    $result_page = mysqli_query($db, "SELECT configblog FROM page WHERE id='1'");
    $myrow_page  = mysqli_fetch_array($result_page);

    global $maxSQL;
    $maxSQL++;

    return $myrow_page['configblog'];
}
Если это поможет то проблема в том, что переменная $db не известна в функции returnconfig()
Ответ для пользователя: dlegame
dlegame, 20 Ноября 2013 г. 14:15 пишет:
Читатель
А вот кодировка хромает и вот как её выставить правильно? в MySQLi
Ответ для пользователя: Алексей
Алексей, 20 Ноября 2013 г. 14:27 пишет:
Автор
Вместо:
mysqli_query($db, "SET NAMES 'cp1251'");
Попробуйте использовать:
mysqli_set_charset($db, "cp1251");
Ответ для пользователя: dlegame
dlegame, 20 Ноября 2013 г. 14:34 пишет:
Читатель
я использую форк в кодировке UTF-8 и я воспользовался таким вариантом:
@mysqli_query($db, "SET NAMES 'utf8'");
Нормальный вариант? а то я слыхал о том что использование @ не рекомендуется
Ответ для пользователя: Алексей
Алексей, 20 Ноября 2013 г. 14:47 пишет:
Автор
Все равно для mysqli рекомендую использоваться функцию mysqli_set_charset(), т.е. вот так:
mysqli_set_charset($db, "utf8");
По поводу символа @
Во-первых я понятие не имею, зачем Вы его используете в данном месте.
Во-вторых данный символ просто глушит вывод ошибки. Обычно его используют для того что бы написать свой собственный, детализированный обработчик ерроров.
Ответ для пользователя: dlegame
dlegame, 20 Ноября 2013 г. 14:57 пишет:
Читатель
Вставил, работает. спасибо =)
а вот вопрос насчёт оптимизации SQLi запросов...
у меня после очистки кеш идёт:
<!-- Общее количество MySQLi запросов 13 -->
после заполнение кешом:
<!-- Общее количество MySQLi запросов 7 -->
и вот вы решали такую проблему? я слышал можно это сделать через JOIN но я хз что и как...гуглил и нашел статью на хабре но я нечего не понял
Ответ для пользователя: Алексей
Алексей, 20 Ноября 2013 г. 17:35 пишет:
Автор
JOIN это оператор объедения нескольких таблиц в одном запросе.
например вот так выглядел бы оптимизированный модуль последних комментариев

p.s: только я его не тестил, может какую синтаксическую ошибку допустил.
Ответ для пользователя: dlegame
dlegame, 20 Ноября 2013 г. 18:09 пишет:
Читатель
Все работает) спасибо...но вот что то я понять немогу в чем я закосячил?)))
вот оригинал:
$result_meta = mysqli_query($db, "SELECT title,meta_d,meta_k FROM page WHERE id='1'");
$myrow_meta = mysqli_fetch_array($result_meta);
вот переписан мною:
	$sql = ""
		."SELECT"
			." news.title			AS news_title,"
			." news.meta_d			AS news_meta_d,"
			." news.meta_k			AS news_meta_k,"
		." FROM"
			." page"
		." WHERE"	
		."     id		= '1'"
	;

$result_meta = mysqli_query($db, $sql);
$myrow_meta = mysqli_fetch_array($result_meta);	

$maxSQL++;

	if($myrow_meta != "")
	{
		$headerMETA[0] = $myrow_meta['news_title'];
		$headerMETA[1] = $myrow_meta['news_meta_d'];
		$headerMETA[2] = $myrow_meta['news_meta_k'];
		$headerMETA[3] = $myrow_meta['news_title'];
		$headerMETA = implode("[META]",$headerMETA);
		
		writeCACHE("news_meta",$headerMETA);
	}
}
что неправильно я делаю?) ибо он получает пустые значение из базы
Ответ для пользователя: Алексей
Алексей, 20 Ноября 2013 г. 20:18 пишет:
Автор
Попробуйте вот так:
	$sql = ""
		."SELECT"
			." news.title			AS news_title,"
			." news.meta_d			AS news_meta_d,"
			." news.meta_k			AS news_meta_k"
		." FROM"
			." page"
		." WHERE"	
			."id				= '1'"
	;

$result_meta	= mysqli_query($db, $sql);
$myrow_meta	= mysqli_fetch_assoc($result_meta);

$myrow_meta	= $myrow_meta[0];

$maxSQL++;

	if($myrow_meta != "")
	{
		$headerMETA[0]	= $myrow_meta['news_title'];
		$headerMETA[1]	= $myrow_meta['news_meta_d'];
		$headerMETA[2]	= $myrow_meta['news_meta_k'];
		$headerMETA[3]	= $myrow_meta['news_title'];
		$headerMETA	= implode("[META]",$headerMETA);

		writeCACHE("news_meta",$headerMETA);
	}
}
Ответ для пользователя: dlegame
Алексей, 20 Ноября 2013 г. 21:36 пишет:
Автор
А не, так работать не будет. Привык уже работать с обверткой. Нужно писать примерно вот так:
    $sql = ""
        ."SELECT"
            ." news.title			AS news_title,"
            ." news.meta_d			AS news_meta_d,"
            ." news.meta_k			AS news_meta_k"
        ." FROM"
            ." page"
        ." WHERE"	
            ."id				= '1'"
    ;

	$result_meta	= mysqli_query($db, $sql);
	$myrow_meta		= mysqli_fetch_assoc($result_meta);

	$maxSQL++;

    if($myrow_meta != FALSE) {
			
		while ($myrow_meta = mysqli_fetch_assoc($result_meta)) {

			$headerMETA[0]	= $myrow_meta['news_title'];
			$headerMETA[1]	= $myrow_meta['news_meta_d'];
			$headerMETA[2]	= $myrow_meta['news_meta_k'];
			$headerMETA[3]	= $myrow_meta['news_title'];
			$headerMETA		= implode("[META]",$headerMETA);
		
		}
		
        writeCACHE("news_meta",$headerMETA);
    }
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 05:42 пишет:
Читатель
Ок, спс...дома проверю =) ибо сейчас на работе...
Ответ для пользователя: Алексей
dlegame, 21 Ноября 2013 г. 13:33 пишет:
Читатель
Вот что пишет
Parse error: syntax error, unexpected $end in Z:\home\udiscuz.ru\www\source\modules\news.php on line 173
Ответ для пользователя: Алексей
dlegame, 21 Ноября 2013 г. 13:38 пишет:
Читатель
Эту проблему решил но теперь вот такая фигня вылезла:
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in Z:\home\udiscuz.ru\www\source\modules\news.php on line 33

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at Z:\home\udiscuz.ru\www\source\modules\news.php:33) in Z:\home\udiscuz.ru\www\source\modules\adminbar.php on line 19
посмотрите пожалуйста: http://rghost.ru/50327456
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 13:42 пишет:
Автор
Тут есть еще одно замечание. Я сразу не увидел, но таблица в запросе называется page, а поля берутся из таблицы news. Вот так правильней:
    $sql = ""
        ."SELECT"
            ." page.title			AS news_title,"
            ." page.meta_d			AS news_meta_d,"
            ." page.meta_k			AS news_meta_k"
        ." FROM"
            ." page"
        ." WHERE"	
        ."     id		= '1'"
    ;
Z:\home\udiscuz.ru\www\source\modules\news.php on line 173
Что в этой строчке?
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 13:58 пишет:
Читатель
Все ошибки ушли, но вот титлы и метаданные пустые данные...вот этот файл:
http://rghost.ru/50327775
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 14:21 пишет:
Автор
Я надеюсь Вы кэш чистили?
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 14:40 пишет:
Читатель
всегда чищу когда делаю какие то изменения
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 14:52 пишет:
Автор
Вот, измененный файл. Должно сработать
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 15:01 пишет:
Читатель
неработает. пустые значение
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 15:09 пишет:
Автор
Сложно без возможности запустить =(
Попробуйте вот этот файл
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 15:18 пишет:
Читатель
Все спасибо работает))) а вот можете поделиться инфой где вы учились писать такие SQL запросы к базе?)
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 15:28 пишет:
Автор
С начало читал книгу Мартина Грубера "Понимание SQL". После, много практики на работе =)
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 15:33 пишет:
Читатель
Начал за вывод новости и вот опять мне пэхопэ говорит что ошибку допустил...а где хз
<?php
/* 

 uDiscuz! - (c) 2013-2099.
 
 Powered by SibWeb Group
 
 Official site: www.udiscuz.net
 
 License GNU/GPL v 2

 */

if(!defined('MYADMIN')) die('');

$headerMETA = readerCACHE("post_meta_".$blog,3600);

if($headerMETA == FALSE)
{
	
    $sql = ""
        ."SELECT"
            ." page.title			AS page_title,"
            ." page.meta_d			AS page_meta_d,"
        ." FROM"
            ." page"
        ." WHERE"	
        ."     page.id		        = '1'"
    ;

    $result_meta	= mysqli_query($db, $sql);
    $myrow_meta		= mysqli_fetch_assoc($result_meta);
	
	$maxSQL++;

	if($myrow_meta != FALSE)
	{
		
    $sql = ""
        ."SELECT"
            ." news.title			AS news_title,"
            ." news.meta_d			AS news_meta_d,"
            ." news.meta_k			AS news_meta_k"
        ." FROM"
            ." blog"
        ." WHERE"	
        ."     news.id		        = '$blog'"
    ;

    $result_meta_blog	= mysqli_query($db, $sql);
    $meta_blog		= mysqli_fetch_assoc($result_meta_blog);		
		
		$maxSQL++;

		$headerMETA[0] = $meta_blog['news_title']." - ".$myrow_meta['page_title'];
		$headerMETA[1] = $myrow_meta['page_meta_d'];
		$headerMETA[2] = $meta_blog['news_meta_k'];
		$headerMETA[3] = $myrow_meta['page_title'];
		
		$headerMETA = implode("[META]",$headerMETA);
		
		writeCACHE("post_meta_".$blog,$headerMETA);
	}
}

$headerMETA = explode("[META]",$headerMETA);

$header_title = $headerMETA[0];
$header_metaD = $headerMETA[1];
$header_metaK = $headerMETA[2];
$title_origin = $headerMETA[3];

function blog($blog,$canon,$chpu,$morepostACTIV)
{

global $db;

include("./source/modules/aut.php");

include("./source/modules/bbeditor.php");

include ("./source/lang/news.php");

if (checketHESH() === TRUE) $sql = "SELECT * FROM blog WHERE id='$blog'";
else $sql = "SELECT * FROM blog WHERE id='$blog' AND pablick='1'";

$result_index = mysqli_query($db, $sql);
$myrow_index = mysqli_fetch_array($result_index);

$newloock = $myrow_index['loock'] + 1;
$up_loock = mysqli_query ($db, "UPDATE blog SET loock='$newloock' WHERE id='$blog'");

global $maxSQL;
$maxSQL = $maxSQL + 2;

if($myrow_index != "")
{
$sm_read = getTPL('text.tpl');

if($myrow_index['meta_k'] != "")
{
 $sm_read = str_replace("{meta_k}",$myrow_index['meta_k'],$sm_read);
}
else $sm_read = str_replace("{meta_k}",$lang['not_tags'],$sm_read);

$text = str_replace("[end]","",$myrow_index['meta_d']);

if($morepostACTIV == 1)
{
include("./source/modules/morepost.php");
$more = morepost($chpu,$myrow_index['cat'],$blog);
$sm_read = str_replace("[_morepost]",$more,$sm_read);
}
else $sm_read = str_replace("[_morepost]","",$sm_read);

$datePOST = date("c",$myrow_index['date_b']);

$sm_read = str_replace("{canon}",$canon,$sm_read);
$sm_read = str_replace("{news}",mynews($text),$sm_read);
$sm_read = str_replace("{titles}",$myrow_index['title'],$sm_read);
$sm_read = str_replace("{author}",$myrow_index['author'],$sm_read);
$sm_read = str_replace("{date}",$datePOST,$sm_read);
$sm_read = str_replace("{comm}",$myrow_index['comm'],$sm_read);
$sm_read = str_replace("{cat}",get_catalog($myrow_index['cat']),$sm_read);
$sm_read = str_replace("{authors}",$lang['author'],$sm_read);
$sm_read = str_replace("{data_add}",$lang['data_add'],$sm_read);
$sm_read = str_replace("{comments_counter}",$lang['comments_counter'],$sm_read);
$sm_read = str_replace("{cate}",$lang['cate'],$sm_read);
$sm_read = str_replace("{tags}",$lang['tags'],$sm_read);
$sm_read = str_replace("{form_comments}",$lang['form_comments'],$sm_read);
}
else
{
$sm_read = "<p align='center'>".$lang['not_found']."</p>";
}
$result[0] = $sm_read;
$result[1] = $myrow_index['viewcomm'];
return $result;
}
function get_catalog($catalog_id = 0)
{
    include ("./source/lang/news.php");

    $catalog_link = "".$lang['not_cat']."";
    
    $catalog_id = (int)$catalog_id;
    
    if ($catalog_id == 0)
        return $catalog_link;
    
    global $station_menu;
    
    if (empty($station_menu) OR !is_array($station_menu))
        return $catalog_link;
        
    $path = array(); 
    $name = array();
    
    foreach ($station_menu as $key => $station)
        if ($station[0] == $catalog_id) {

            if ($station[3] != '')
                break;
            
            $path[] = $station[1]; 
            $name 	= $station[2]; 
            
            if ($station[4] != 0)
                get_path($path, $station[4], $station_menu);
            
            break;
        }
    
    if (empty($path))
        return $catalog_link;
    
    $catalog_link = '/'.implode('/', array_reverse($path));
    
    return "<a onClick=\"expandit('loading')\" href=\"".$catalog_link."\">".$name."</a>";
}
function get_path(&$path, $podmenu, $station_menu)
{
    foreach ($station_menu as $key => $station)
        if ($station[0] == $podmenu){
            $path[] = $station[1]; 

            if ($station[4] != 0)
                get_path($path, $station[4], $station_menu);
            
            break;
        }
}
?>
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 16:43 пишет:
Автор
Скорее всего дело во втором запросе. Он должен быть примерно таким:
    $sql = ""
        ."SELECT"
            ." blog.title			AS news_title,"
            ." blog.meta_d			AS news_meta_d,"
            ." blog.meta_k			AS news_meta_k"
        ." FROM"
            ." blog"
        ." WHERE"	
        ."     blog.id		        = '".$blog."'"
    ;
Ответ для пользователя: dlegame
dlegame, 21 Ноября 2013 г. 17:31 пишет:
Читатель
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in Z:\home\udiscuz.ru\www\source\modules\view_news.php on line 32
Вот что пишет =( а вот файл сам:
http://rghost.ru/50331479
Ответ для пользователя: Алексей
Алексей, 21 Ноября 2013 г. 17:36 пишет:
Автор
В ошибке говорится о функции mysqli_fetch_array(). А в файле используется функция mysqli_fetch_assoc()
Ответ для пользователя: dlegame
dlegame, 25 Ноября 2013 г. 13:36 пишет:
Читатель
уже прошло много времени и не какой информации об новой системе RS-Site...
Когда уже вы сделаете релиз?
и сделайте пожалуйста небольшой обзор перед тем как вы опубликуете RS-Site
и расскажите о его приемуществах. заранее спасибо! =)
Алексей, 25 Ноября 2013 г. 21:24 пишет:
Автор
Я уже работаю над этим. В ближайшее время конечно не обещаю, но уже совсем скоро.
Ответ для пользователя: dlegame
dlegame, 26 Ноября 2013 г. 18:05 пишет:
Читатель
    $mod = array(); //базовые
    $mod[] = 'author';	
    $mod[] = 'navi';
    $mod[] = 'headers';
    $mod[] = 'comments';
    //$mod[] = 'separator';
    $mod[] = 'blogConsole';
    $mod[] = 'window';

    foreach ($mod as $module) {
        $new_mod=mysql_query('INSERT  into '.PREFIX.'modules (name) values ("'.$module.'");') or die(mysql_error());
        $rank = mysql_insert_id();
        $r=mysql_query('UPDATE '.PREFIX.'modules SET
            rank = "'.$rank.'"
            WHERE id="'.$rank.'"')  or die(mysql_error());
    }
Алексей, подскажите почему этот код не работает? ибо короче в таблицу не добавляется =(
Алексей, 27 Ноября 2013 г. 10:21 пишет:
Автор
Попробуйте убрать ";" в INSERT запросе
Ответ для пользователя: dlegame
japson, 07 Июля 2014 г. 19:55 пишет:
Гость
Алексей здравствуйте.
При включенном ЧПУ неправильно обрабатывает якоря на странице. Т.е. ссылки типа http://japson.ru/#mechta.
Подскажите, пожалуйста, мне в данном случае как решить проблему: что-то вписать в htaccess или в getchpu() обработчик писать?
Спасибо заранее.
Игорь, 06 Ноября 2014 г. 16:01 пишет:
Гость
Я прочитал внимательно статью, вывел из таблицы url, через запрос GET в браузере у меня выходит такая ссылка view-index.php?url=avto-konjern-honda.html как убрать эту хрень view-index.php?url= в файле htaccess ????
Евгений, 08 Апреля 2015 г. 23:43 пишет:
Гость
//$url - имя с помощью которого мы определим id
//$dirDB - режим, с помощью которого мы определим в какой таблице базы данных нам искать
//определяем запрос в зависимости от того какую страницу открывает пользователь (текст поста или категорию)
if($dirDB == "post")$sql = "SELECT id FROM blog WHERE nameurl = '$url'";//текст поста
if($dirDB == "category")$sql = "SELECT id FROM menu WHERE nameurl = '$url'";//категория



Вот подскажите мне, непонятливому, где Вы объявляете переменные $dirDB и $url??? Не могу найти.

Алексей, 09 Апреля 2015 г. 09:57 пишет:
Автор
Посмотрите внимательно файл getchpu.php. Там вызывается функция chpu() с двумя параметрами ($url и $dirDB). Вот например вырезка из кода:
$blog = chpu($_GET['post'],"post");//по имени страницы достаем из бд id
Ответ для пользователя: Евгений
Игорь, 23 Марта 2016 г. 12:22 пишет:
Гость
Очень интересная и хорошо написанная статья ! Все предельно понятно. Спасибо за статью !
Сергей, 19 Января 2017 г. 03:29 пишет:
Гость
Приветствую автора движка блога.
Зашёл на ваш сайт с поисковика по запросам с ЧПУ. Прочитал, описание и комментарии. При чтении описания попалась на глаза ссылка которая вела на страничку с пробной версией блога. Заинтересовался скачал, вкинул на денвер посмотрел.
Вещь нормальная. Минимализм на 5 с плюсом как раз такой и искал. один недостаток что все прикрасы что вы описываете на вашем сайте нужно вкручивать самому. А не охота да и возраст уже не тот чтобы по долгу разбираться во всех тонкостях.
Лет пять назад попался бы мне ваш сайт тогда бы может ещё и потрудился.