Контент


Наша первая страница на Kohana

Итак, настало время написать что-то свое. Давайте попробуем создать стартовую страницу своего будущего блога.

Для этого необходимо:

  • Набросать шаблон (VIEW) и прикинуть, какие динамические данные мы хотим получить от системы (т.е. от контроллера)
  • Создать контроллер, инициализировать в нем все данные для шаблона.
  • Так как мы хотим использовать и модели, какие-то данные для шаблона будем брать из СУБД (конечно же это будет MySQL)

Создаем шаблон страницы

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

application/views/index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?=$title?></title>
<link rel="stylesheet" href="/css/index.css" type="text/css" media="screen" />
</head>
<body>
<div id='wrapper'>
    <div id='header'>
        <h1><?=$title?></h1>
    </div>
    <div id='page'>
    <div id='content'><?=$content?>
    </div>
    <div id='sidebar'>
        <ul class='menu'>
            <?foreach ($menus as $menu): ?>
            <li><a href="<?=$menu['link']?>"><?=$menu['title']?></a></li>
            <?endforeach;?>
        </ul>
    </div>
    </div>
</div>
<div id='footer'>
Made in Russia, 2009
</div>
</body>
</html>

CSS-файл стилей (шаблон будет искать в папке /css/index.css):

html, body {
  margin:0;
  padding:0;
  width:100%;
  height:100%;
}
#wrapper {
  position:relative;
  min-height: 100%;
  height: auto !important;
  height: 100%;
  width: 760px;
  margin: 0 auto;
}
#content {
  float: left;
  width: 500px;
  overflow: hidden;
}
#page {
  overflow: hidden;
  padding-bottom: 75px;
  zoom: 1;
}
#sidebar {
  width: 200px;
  float: left;
  overflow: hidden;
}
#footer {
  position: relative;
  height: 70px;
  clear: left;
  width: 760px;
  margin: 0 auto;
  margin-top: -70px;
  background: #ddd;
}
#header {
  height: 150px;
  width: 100%;
  overflow: hidden;
  background: #ddd;
}

Как вы видите, в шаблон php-переменные вставляются стандартным способом — через вставки <? ?> (или <?php ?>). Это позволяет не только выводить значения переменных, но и проверять выполнение логических условий и реализовывать циклы. Вообще переменная в шаблоне может быть чем угодно, в том числе и другим шаблоном. В нашем случае это переменная $content.

Можно было также применить хэлперы типа HTML для построения странички (например, при формировании ссылок), но мне лично проще и привычнее использовать родные тэги разметки.

Создаем модель получения данных

Поскольку мы решили извлекать часть данных из СУБД, необходимо создать модель. Конечно, соединение с базой данных и выполнение запросов осуществимо и из контроллера, но ведь мы хотим реализовать MVC. :) А это значит, что контроллер слишком «важен», чтобы самостоятельно заниматься подобной черной работой. Он даже знать не должен, каким образом и откуда берутся данные (из какой СУБД, а возможно и из файлов).

Модели в Kohana должны иметь название вида Название_Model и храниться в файле /application/models/название.php (имя файла с маленькой буквы). Модель должны предоставить контроллеру интерфейс для работы с БД. Поскольку обычной практикой изучения фреймворков является создание блога, будем писать модель работы со статьями.

Создадим простенькие таблички:

DROP TABLE IF EXISTS `articles`;
CREATE TABLE  `articles` (
  `article_id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(255) collate utf8_unicode_ci NOT NULL default '',
  `text` text collate utf8_unicode_ci NOT NULL,
  `author_id` int(10) unsigned NOT NULL,
  `ts` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `category_id` int(10) unsigned NOT NULL,
  PRIMARY KEY  (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
DROP TABLE IF EXISTS `authors`;
CREATE TABLE  `authors` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(256) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
DROP TABLE IF EXISTS `categories`;
CREATE TABLE  `categories` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(256) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
ALTER TABLE `articles` ADD CONSTRAINT `FK_articles_authors` FOREIGN KEY `FK_articles_authors` (`author_id`)
    REFERENCES `authors` (`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;
 
ALTER TABLE `articles` ADD CONSTRAINT `FK_articles_categories` FOREIGN KEY `FK_articles_categories` (`category_id`)
    REFERENCES `categories` (`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;
 
INSERT INTO `categories`(`name`) VALUES
   ('Категория 1'),
   ('Категория 2'),
   ('Категория 3');
 
INSERT INTO `authors`(`name`) VALUES
   ('Автор 1'),
   ('Автор 2'),
   ('Автор 3');
 
INSERT INTO `articles`(`title`, `text`, `author_id`, `category_id`) VALUES
   ('Статья 1', 'Текст статьи 1', 3, 2),
   ('Статья 2', 'Текст статьи 2', 2, 3),
   ('Статья 3', 'Текст статьи 3', 1, 1),
   ('Статья 4', 'Текст статьи 4', 1, 2);

Мы создали таблицы для статей, авторов и категорий статей, связали их между собой внешними ключами и ввели туда несколько тестовых значений. Итак, набросаем каркас нашего класса:

application/models/article.php

<?php defined('SYSPATH') OR die('No direct access allowed.');
class Article_Model extends Model {
 
    public function __constructor()
    {
        parent::__construct();
    }
 
    /**
     * Возвращает статью по ее идентификатору.
     * Если статья не найдена, возвращаем FALSE.
     *
     * @param   integer  идентификатор статьи
     * @return  mixed    объект с параметрами статьи либо FALSE если не найдена
     */
    public function get_article($article_id)
    {
    }
 
    /**
     * Возвращает список статей по идентификатору категорий.
     * Если категория не указана, возвращает все статьи.
     * Если статьи не найдены, возвращаем FALSE.
     *
     * @param  integer  идентификатор категории
     * @return mixed    массив статей либо FALSE если не найдены
     */
    public function get_articles($category_id = NULL)
    {
    }
}

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

Метод get_article:

     public function get_article($article_id)
     {
        if (!is_numeric($article_id)) return FALSE;
        $article = $this->db->where('article_id', $article_id)->get('articles');
        return $article->current();
     }

Что происходит в этом методе? Сперва мы проверяем входные данные (т.е. $article_id), если идентификатор не передан или это не число, возвращаем FALSE. Далее делаем выборку по идентификатору. Мы используем т.н. «построитель запросов» (Database Query Builder, описание), он позволяет пошагово добавлять условия запроса. Таким образом, $this->db->where(‘article_id’, $article_id)->get(‘articles’) сперва указывает условие выборки (метод where), а затем выполняет сам запрос (метод get с первым параметром — имя таблицы MySQL).

Может возникнуть вопрос, откуда взялся объект $this->db. Обратите внимание, что в конструкторе нашей модели мы указали $parent::__construct(), т.е. сделали вызов родительского конструктора. А в конструкторе класса Model_Core (файл system/libraries/model.php, если интересно) эта самая переменная и инициализируется с учетом дефолтных настроек (вспоминаем файл application/config/database.php). Если мы захотим использовать другие настройки БД, надо совершить инициализацию переменной $this->db в конструкторе до вызова родительского, например так:

$this->db = Database::instance('other_db');

Что будет, если инициализировать ее после родительского конструктора, оставляю вам как самостоятельную работу ;) Далее слегка обрабатываем результат выборки, чтобы не передавать лишних объектов. Метод current() возвращает текущую запись (по умолчанию первая). Если записей нет, возвращает FALSE.

Ну, теперь мы с вами стали опытными Query Builder‘ами, и второй метод не предоставит нам никаких сложностей в написании:

     public function get_articles($category_id = NULL)
     {
        if (is_numeric($category_id)) $this->db->where('category_id', $category_id);
        $articles = $this->db->get('articles');
        if ($articles->count() == 0) return FALSE;
        else return $articles;
     }

Все предельно просто — проверяем параметры, выполняем запрос, возвращаем результат. Подробнее об объекте, возвращаемом методом get(), я напишу в отдельной статье, а Вы можете почитать о нем в оффициальной документации. Почему я предпочитаю вернуть FALSE? Дело в том, что проверка как правило идет уже в шаблоне, и он выглядит намного чище и понятнее, если делать в нем проверку булевской переменной, чем обращаться к методам каких-то классов, например, if ($articles->count() == 0) ….

Создаем контроллер

Всему, что я написал выше, приходилось верить на слово, т.к. у нас пока что нет главного связующего звена — контроллера. Исправим эту оплошность и сперва опять-таки набросаем каркас класса:

application/controllers/blog.php

<?php defined('SYSPATH') OR die('No direct access allowed.');
 
class Blog_Controller extends Template_Controller {
 
  public $template = 'index';
 
  public function __construct()
  {
      parent::__construct();
  }
 
  public function index()
  {
  }
 
  public function view_article($id = NULL)
  {
  }
 
}

Контроллеры, работающие с шаблонами, рекомендуется наследовать от базового класса Template_Controller. Переменная $template содержит имя шаблона (будет разыскиваться в папке application/views/) без расширения. Метод view_article() будет показывать информацию о статье, а index() — перечень статей по категории. В частности, http://localhost/blog или http://localhost/blog/index будет выводить полный список статей (т.к. идентификатор категорий пропущен).

Конструктор:

      parent::__construct();
      $this->article = new Article_Model;
      $this->template->menus = array
      (
          'main' => array
          (
              'title'   =>  'Главная страница блога',
              'link'    =>  '/',
          ),
          'article' => array
          (
              'title'   =>  'Статья "Наша первая страница на Kohana"',
              'link'    =>  '/2009/01/13/nasha-pervaya-stranica-na-kohana/',
          ),
      );

В конструкторе мы заполнили статичные переменные (массив ссылок для sidebar’а $menus) и инициализировали модель Article_Model, чтобы в дальнейшем каждый метод контроллера мог просто обращаться к переменной $this->article.

Реализация метода index():

  public function index()
  {
      $this->template->content = new View('blog/articles');
      $this->template->title = 'Стартовая страница';
      $this->template->content->articles = $this->article->get_articles();
  }

Что мы видим? Идет заполнение переменных шаблона $this->template (т.е. созданного нами в начале статьи index.php). Переменная $content в свою очередь тоже является шаблоном (файл должен находиться в application/views/blog/articles.php) и имеет переменную $articles (массив статей). Как раз для получения списка статей мы и используем модель Article_Model (которая доступна нам через $this->article).

Добьем контроллер методом view_article():

public function view_article($id = NULL)
  {
      $this->template->title = 'Просмотр статьи';
      $this->template->content = new View('blog/article');
      $this->template->content->article = $this->article->get_article($id);
  }

Думаю, тут уже все понятно. Напоследок приведу исходники двух новых шаблонов (application/views/blog/article.php и application/views/blog/articles.php):

<? if ($article):?>
      <h2><?=$article->title?></h2>
      <h3>Написана <?=$article->ts?></h3>
      <?=$article->text?>
    <? else: ?>
    <h2>Статья не найдена</h2>
    <? endif; ?>

и

<ul>
<? foreach($articles as $article): ?>
<li><a href='/blog/view_article/<?=$article->article_id?>'><?=$article->title?></a></li>
<? endforeach;?>
</ul>

соответственно.

Можно приступить к проверке нашего контроллера в действии. Наверняка вы захотите сделать его доступным по умолчанию (правильно, зачем нам этот неактуальный welcome на стартовой странице). Для этого подправим application/config/routes.php следующим образом:

$config['_default'] = 'blog/index';

Теперь список статей будет доступен не только по адресу http://localhost/blog/, но и по более короткому http://localhost/. У второй статьи будет URL http://localhost/blog/view_article/2, а у третьей категории статей — http://localhost/blog/index/3.

Критикуем URL’ы

Не знаю, как вам, а мне лично кажется, что доступ с указанием метода index() не совсем логичен и удобен. Если view_article() вполне говорит сам за себя, то index() смотрится как кот в мешке. Поэтому предлагаю немного переделать наш контроллер:

  public function index()
  {
      url::redirect('blog/view_articles');
  }
 
  public function view_articles($id = NULL)
  {
      $this->template->content = new View('blog/articles');
      $this->template->title = 'Список статей';
      $this->template->content->articles = $this->article->get_articles($id);
  }

Мы просто перенаправляем пользователя со стартовой страницы на нужный нам метод контроллера. Кроме понятного URL есть и другие плюсы. Например, часто в меню навигации по сайту текущий раздел выделяется каким-либо образом. Теперь и при открытии стартовой страницы раздел «статьи» будет выделяться.

Пожалуй, на этом все. В следующей статье мы добавим возможность создания собственной статьи.

Постскриптум или работа напильником

После выполнения всех вышеперечисленных действий может оказаться, что стартовая страница перенаправляет нас куда-то на http://localhostindex.php/что-то-там. Проверьте настройки в файле application/config/config.php (параметр $config['site_domain'] скорее всего пустая строка, измените на ‘/’).

Следующий шаг — избавление от index.php в адресе. Откуда он взялся? Дело в том, что в хэлпере url, который мы использовали, метод redirect() анализирует полученный URL и дополняет его до абсолютного, если он относительный (как в нашем случае) с помощью метода url::site(). Вот тут-то и возникает проблема, изначально в нем базовый путь к сайту прописывается с index.php. Выход — замена метода своим.

Update. Исправление данного неудобства я перенес в соответствующую категорию «напильник», но в итоге выяснилось, что достаточно просто поменять параметр $config['index_page'] в config.php с index.php на пустую строку.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в учебник.

Теги: , .


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

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Alex_XS пишет:

    Хорошая статья. Спасибо!
    ——————————————
    На мой взгляд. Нехватает только названий файлов в коде.

    К примеру как на: http://learn.kohanaphp.com/2008/03/26/blog-tutorial-1/

    //models/post.php <<— Название файла
    class Post_Model extends ORM{
    protected $has_many=array(‘comments’);
    }
    или архива папки application того что получилось в итоге.

  2. BIakaVeron пишет:

    Вам спасибо :) Обоснованную критику принимаю с радостью.
    Честно говоря, не хотелось писать имена файлов прямо в коде, поэтому старался их приводить перед кодом, в основном тексте. Сейчас пробегусь, добавлю, где не хватает.

    А по поводу архивов — все-таки когда сам все вписываешь ручками, быстрее обучаешься. Это же не готовая CMS, которую распаковал и готово, это просто набор каких-то первых действий с фреймворком. В будущем я планирую открытое написание небольшой CMS с кодами в code.google.com и публикацию заметок о процессе кодинга.

  3. Alex_XS пишет:

    После выполнения всех выше указаных действий, наблюдаю следующую картину:
    — работает только главная страница, на ней кракозябрами выведено содержимое тега , заголовок и две нижних ссылки. Ссылки на статьи 1-4 выглядят правильно, но уже после нажатия на них появляется Error 404.
    Или я где-то ошибся или еще осталось описать пару шаманских действий которые заставят тестовый блог заработать. Нормальный рабочий процесс.
    Спасибо.

  4. BIakaVeron пишет:

    1. Кракозябры — проверьте кодировку. Я (и фреймворк в целом) использую UTF-8.
    2. Насчет УРЛов — какие формируются? Те, что я привел в статье, не факт что работают :) Это же для примера. Хотя в принципе ссылка на корень должна отображаться.
    Не про то подумал… А просмотр списка статей (view_articles) по категориям работает? Также попробуйте явно вызвать метод index контроллера blog.

  5. Alex_XS пишет:

    1. Ссылки следующего вида:
    «Статья 1″ — http://localhost/blog/view_article/1

    2. http://localhost/blog/index
    http://localhost/blog/index.php
    http://localhost/blog/view_articles
    Выдают Error 404

  6. BIakaVeron пишет:

    Наверное проще будет, если Вы мне на почту вышлете архив с классами (адрес в «Обратной связи»).

  7. idGreen пишет:

    У меня такой вопрос, А не могли бы вы описать или создать тему как создавать дизайн и все такое по кахане. Она мне очень понравилась. Хочу ее познать поближе, только вот на русском языке вообще нет инфы и доки. Буду очень рад почитать статью про Создание дизайна(шаблона под кохану) и пример создания сайта на кохане и как прикрутить шаблон.

  8. BIakaVeron пишет:

    Наверное Вы путаете что-то. Сайт, созданный на Кохане ничем не будет отличаться от сайтов на других фреймворках или на чистом php. Шаблон применяется к уже готовому html-коду, так что тут все методы те же, что и для других сайтов.

  9. vgray пишет:

    [..]Контроллеры, работающие с шаблонами, рекомендуется наследовать от базового класса Web_Controller[..]

    Наверное Template_Controller

    Спасибо за отличный блог. Я только начал кохану изучать, и ваш блог отличный источник информации.

  10. BIakaVeron пишет:

    Да, конечно. Сперва создавал свой базовый контроллер поверх Template_Controller, вот он и остался в статье.
    Спасибо, исправил.

  11. pridumal пишет:

    Спасибо, очень интересный материал. Подписался.

    Относительно вывода «кракозябрами» — пожалуй лучше в листинге запросов к БД дописать строчку
    SET NAMES UTF8;
    так, чтоб в дальнейшем подобные вопросы не возникали…

  12. pridumal пишет:

    И еще вот… Похоже на очепятку.
    «
    CSS-файл стилей (шаблон будет искать в папке /css/index.php)
    »
    Может быть, всё же, index.css?
    Этот камент можно удалить:-)

  13. vgray пишет:

    не могу понять одной вещи,
    предположим что у меня есть некие действия которые нужно выполнять каждый раз ( например проверка прав пользователя) логично это вынести в отдельный класс, и от этого класса наследовать уже все другие контроллеры
    Должно получится что-то типа

    class Website_Controller extends Template_Controller …
    class Article_Controller extends Website_Controller

    получается, что пользователь сайта может вызвать напрямую Website_Controller просто набрав его в строке браузера?

    или как-то можно отделить такие Контроллеры-Родители от обычных шаблонов? ( я пробовал их перемещать в папку libraries, но получал ошибку).

    не знаю че

  14. BIakaVeron пишет:

    @pridumal
    1. В методе connect() драйвера БД прописана установка кодировки, там были скорее проблемы с некорректной кодировкой хранящихся данных в UTF-таблице.
    2. Спасибо, прозевал. Машинально index.php подпихнул

    @vgray
    Сделайте его абстрактным ;)

  15. egoholic пишет:

    У меня та же проблема, что и у Alex_XS , ссылки на статьи и index.php/blog/ не работают… Title и ссылки справа отображаются не корректно, пока кодировку не изменишь на Windows -1251, при этом ссылки на статьи перестают отображаться корректно. Что делать?

    P.S. Спасибо за отличные статьи, только начинаю постигать Kohana Framework

  16. BIakaVeron пишет:

    egoholic
    Проверьте кодировку, в которой Вы скрипт набивали. Скорее всего это не юникод, а cp-1251. По поводу работы ссылок — насколько я помню, та проблема решилась использованием .htaccess (в указанном мной примере я уже избавился от использования index.php в ссылках).
    Если не решится, напишите на почту, найдем проблему.

  17. Юрий пишет:

    public function get_articles($category_id = NULL)
    {
    if (is_numeric($category_id)) $this->db->where(‘category_id’, $category_id);
    $articles = $this->db->get(‘articles’);
    if ($articles->count() == 0) return FALSE;
    else return $articles;
    }

    Непонятен мне этот момент. А именно то, что сначала идет такой вызов:
    $this->db->where(‘category_id’, $category_id)
    а затем:
    $articles = $this->db->get(‘articles’)
    В чем вся соль? Ведь по сути первый вызов ничего не делает. Разъясните :(

  18. BIakaVeron пишет:

    Почитайте про Query Builder (на оф.сайте или в данном блоге). Собственно методы типа where(), from(), limit() и т.д. не вызывают немедленно запрос к БД, а только подготавливают объект Database, добавляя различные условия запроса. А вот метод get() помимо установки имени таблицы для выборки инициирует обращение к БД.

  19. Мáкса пишет:

    Вань, приветствую!
    Во-первых позволь от души тебя поблагодарить за твои труды. Твой блог и все что ты пишешь — это бесценно, особенно с учетом того, что «Kohana» пока не очень популярна (хотя сам фреймворк мне очень понравился, впрочем как и CI) и информацию приходится выковыривать буквально по крупицам, а на русском языке — так вообще по атомам. Я тебе желаю огромных успехов, огромный заряд позитивного драйва, чтобы хватило на долго. Не забрасывай блог, как я, он у тебя очень полезный :)
    Во-вторых, я относительно новичек в использовании фреймоворков (обычно я либо юзал CMF ModX, либо просто кодил «процедурно»), поэтому твой раздел «Учебник» для меня оказался отличной находкой. Здесь тебе — огромное человеческое СПАСИБО!
    А в-третьих у меня вопрос по этому топику: сделал все как по инструкции, однако при вызове основного метода (главной страницы) у меня выводится в браузер нераспарсенный PHP-код представления index.php (views/index.php) 8O Куда копать?

  20. Мáкса пишет:

    :idea: Проблема решена! Сто миллионов раз СПАСИБО Ивану! :D
    В общем, оказалось несколько два бага:
    1. Интерпретатор PHP не был настроен (php.ini) на обработку коротких тэгов <? (вместо <?php ) Либо изменяйте тэги, либо в php.ini установите short_open_tag = On
    2. Т.к. мой проект лежит не в корне сайта (кстати, на это стоит закладываться по умолчанию), то все абсолютные пути в файлах представлений нужно изменить на относительные!

  21. glebiuskv пишет:

    :cry: никто не подскажет? при выводе данных из БД mssql как объекта, пишет что неизветный параметр StdClass::id при выводе масивом начинаються проблемы с кодировкой( отображаються вопросы)
    Может кто сталкивался?
    В CodeIgniter теже данные отображаються нормально.

  22. BIakaVeron пишет:

    1. Посмотрите настройки конфигурации database.php, там есть параметр object, отвечающий за то, в каком виде будет возвращаться результат. Возможно там что-то не так.
    2. Kohana везде использует UTF-8, у вас там юникод в БД?

  23. glebiuskv пишет:

    >>Kohana везде использует UTF-8, у вас там юникод в БД?

    Точно этого не может мне сказать даже ее администратор но с учетом того что это MSSQL наверное winndows -1251. Но я думал что в конфиге коханы с помощью Set_names gjghfdbnm

  24. glebiuskv пишет:

    —с помощью Set_names поправить
    Ссори :oops:

  25. BIakaVeron пишет:

    1. Кохана при подключении отправляет set names.
    2. Кохана и для вывода на экран использует utf.

    Проще всего проверить — на самой странице поменяйте кодировку в браузере (например, на cp1251).

  26. glebiuskv пишет:

    В базе кодировка win -1251 и выводит в ней. :|
    Как заставить его на лету преобразовывать в ютф?

  27. glebiuskv пишет:

    iconv(‘windows-1251′, ‘UTF-8′,$row['description']) не самый удобный путь. но работает. Можно ли сделать так чтобы все данные из бд проходили через это автоматом?

  28. BIakaVeron пишет:

    1. Вообще идеальный вариант — изменить кодировку БД на юникод.
    2. К сожалению, первый вариант не всегда возможен, поэтому попробуйте в config/database.php указать кодировку cp1251.

  29. glebiuskv пишет:

    ->>>
    1. Вообще идеальный вариант — изменить кодировку БД на юникод.
    —К сожалению не реально.

    ->>>
    2. К сожалению, первый вариант не всегда возможен, поэтому попробуйте в config/database.php указать кодировку cp1251.

    — с помощью character_set? непомогает (вобще никакой реакции что не ставь хоть полную галиматью пропишу … ощущение что оно вобще не работает)

  30. BIakaVeron пишет:

    Почистите папку cache. Иногда кэшируются конфиги, а так вообще-то на основании указанной там кодировки должен отправляться ‘set names’ запрос…

  31. glebiuskv пишет:

    нет в кэше ничего:(

  32. BIakaVeron пишет:

    Попробуйте вручную вызвать коннект ($this->db->connect()), затем $this->db->query(«SET NAMES ‘cp1251′»), далее обычную выборку.

  33. glebiuskv пишет:

    Забыл написать :: База MSSQL

    character_set неподдерживаеться в драйвере. так что :cry: а жаль, мне понравилась система.

  34. BIakaVeron пишет:

    Напишите на форуме, может помогут. Не стоит отказываться от фреймворка после первой же проблемы.

  35. pokemon пишет:

    Хочу попробовать воплотить все на KO3.
    Не могу понять, где хранить модели?
    Пробовал сюда
    application\models\
    и сюда
    application\classes\models

    результат один и тот же «Class ‘Article_Model’ not found»
    Подскажите что делаю не так?
    первый день общения с kohana, до этого был небольшой опыт с ci.

    Спасибо :)

  36. BIakaVeron пишет:

    В Ko3 есть изменения в файловой структуре. Модели должны лежать в classes/model, имя класса начинается с Model_. Соответственно могут (и на 99% должны) быть еще изменения в теле контроллеров, моделей и шаблонов.
    Проще по аналогии создать пример на Ko3, чем переделывать данный, который все же был сделан для 2.3.4.

  37. pokemon пишет:

    Спасибо.
    Нашел хороший пример для ko3, возможно кому будет полезен — http://github.com/icyleaf/cactus



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.