PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи

Страниц (2): [1] 2 »

> Найдено сообщений: 19
Specter Отправлено: 29 Августа, 2014 - 22:59:42 • Тема: Именованные подмаски • Форум: Регулярные выражения

Ответов: 1
Просмотров: 179
Проблему решил. Удалите пожалуйста.
Specter Отправлено: 28 Августа, 2014 - 16:17:22 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
Sail пишет:
Specter пишет:
получить из relation_pt id тегов. Снова перебрать полученный массив, и только можно будет по id тегов из tags получить данные тегов

А вот тут-то и надо "join-ить"!

Да.
PHP:
скопировать код в буфер обмена
  1. $tags = $this->db->select('relation_pt.post_id, tags.title as tag_title, tags.slug as tag_slug, tags.id as tag_id')
  2.         ->join('tags', 'relation_pt.tag_id = tags.id', 'left')
  3.         ->where_in('post_id', $ids)
  4.         ->from('relation_pt')
  5.         ->get()->result_array();

На выходе массив
PHP:
скопировать код в буфер обмена
  1. Dump => array(3) {
  2.   [0] => array(4) {
  3.     ["post_id"] => string(2) "57"
  4.     ["tag_title"] => string(13) "windows phone"
  5.     ["tag_slug"] => string(13) "windows-phone"
  6.     ["tag_id"] => string(2) "27"
  7.   }
  8.   [1] => array(4) {
  9.     ["post_id"] => string(2) "57"
  10.     ["tag_title"] => string(8) "winphone"
  11.     ["tag_slug"] => string(8) "winphone"
  12.     ["tag_id"] => string(2) "28"
  13.   }
  14.   [2] => array(4) {
  15.     ["post_id"] => string(2) "58"
  16.     ["tag_title"] => string(8) "everbote"
  17.     ["tag_slug"] => string(8) "everbote"
  18.     ["tag_id"] => string(2) "29"
  19.   }
  20. }

Данные постов:
PHP:
скопировать код в буфер обмена
  1.  
  2. [0] => array(9) {
  3.     ["id"] => string(2) "58"
  4.     ["title"] => string(90) "Тайтл 1"
  5.     ["pubdate"] => string(19) "2014-08-27 21:16:49"
  6.     ["body"] => string(2156) "текст"
  7.     ["comments_num"] => string(1) "0"
  8.     ["cat_id"] => string(2) "12"
  9.     ["slug"] => string(17) "everbote-sodatiek"
  10.     ["cat_title"] => string(8) "Категорий 1"
  11.     ["cat_slug"] => string(12) "soft-coll-33"
  12.   }
  13.   [1] => array(9) {
  14.     ["id"] => string(2) "57"
  15.     ["title"] => string(118) "Тайтл2"
  16.     ["pubdate"] => string(19) "2014-08-27 21:15:29"
  17.     ["body"] => string(1320) "Текст"
  18.     ["comments_num"] => string(1) "0"
  19.     ["cat_id"] => string(2) "11"
  20.     ["slug"] => string(15) "win-phome-edlla"
  21.     ["cat_title"] => string(27) "WindowsPhone"
  22.     ["cat_slug"] => string(12) "news-windows"
  23.   }
  24. }
  25.  

Короче очень не удобно получается. И не понятно как засунуть в данные поста данные тегов?
Итого уже два запроса к бд и один цикл.
(Добавление)
Как вариант в результирующем массиве прямо указывать индекс от post_id.
Specter Отправлено: 28 Августа, 2014 - 15:23:43 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
Мелкий пишет:
Где много запросов? Два.
PHP:
скопировать код в буфер обмена
  1. $sGetPosts = "select post_id, /**/ from posts /**/";
  2. $rgPosts = array();
  3. foreach ($db->query($sGetPosts) as $rgPost) {
  4.     $rgPost['tags'] = array();
  5.     $rgPosts[ $rgPost['post_id'] ] = $rgPost;
  6.     }
  7.  
  8. if ($rgPosts) {
  9.     $sGetTags = "select post_id, tag_name from tags where post_id in (".join(',',array_keys($rgPosts)).")";
  10.     foreach ($db->query($sGetTags) as $rgTag) {
  11.         $rgPosts[ $rgTag['post_id'] ]['tags'] = $rgTag;
  12.         }
  13.     }

Для вашей структуры таблиц конкретные запросы было писать лениво, но суть должна быть ясна.

Дык, в два запроса не получится. Потому что нужно будет собрать связи из relation_pt. id постов допустим в переборе массива мы получили, далее нужно получить из relation_pt id тегов. Снова перебрать полученный массив, и только можно будет по id тегов из tags получить данные тегов.
Хм, тут как минимум 3 запроса и 3 цикла. Однако
Specter Отправлено: 28 Августа, 2014 - 15:05:41 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
подытожим(на будущее) :2 foreach + 2 запроса в бд легче и быстрее чем один с кучей джоинов?
Specter Отправлено: 28 Августа, 2014 - 14:43:16 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
А если допустим выводим конкретный пост, делать также 2 запроса?
или "лучше" будет сделать один запрос?
Specter Отправлено: 28 Августа, 2014 - 12:26:17 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
Спасибо за ответ.
Мелкий пишет:
Можно, но лучше не надо.
И вам и СУБД будет проще, если теги вытянете отдельным запросом:
сначала посты, собираете id постов, для которых надо достать теги, вторым запросом достаёте теги по этому списку постов.

Для всех постов нужно достать теги, но не у всех постов есть теги.
Так много запросов ведь получается, формируем массив из id постов, через where в relation_pt получаем все id тегов, что есть у поста, потом только забираем данные тегов.
Потом результирующий массив нужно будет перебрать и засунуть массив тегов туда.
Не много ли телодвижений? Мне нисколько не проще. Однако
Использую CI, поэтому предпочтительно иметь один большой массив.
Чисто в качестве обучения можете привести запрос, который получает данные за один раз, как описал я в начале темы?
Specter Отправлено: 28 Августа, 2014 - 11:57:12 • Тема: Выборка из нескольких таблиц • Форум: Работа с СУБД

Ответов: 11
Просмотров: 2097
Здравствуйте.
Есть 4 таблицы, хочу все необходимые данные получить из одного запроса в бд.
relation_pt - в ней привязки между post_id и tag_id, потому как у posts может быть несколько тегов.
Однако есть небольшая проблема. Поскольку тегов у записи может быть несколько, я бы хотел выдернуть массив этих тегов, т.е. результат получить в таком варианте:
PHP:
скопировать код в буфер обмена
  1.  
  2. 'title' => 'название поста',
  3. 'body' => 'текст поста'
  4. .....
  5. 'tags' => array(
  6.       0 => array(
  7.            id => id
  8.            title => title
  9.            slug => slug
  10.       ),
  11.       1 => array(
  12.            id => id
  13.            title => title
  14.            slug => slug
  15.       ),
  16. )
  17.  

Использую join`ы, однако как можете предположить, в результате получаю один последний тег.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT `posts`.`id`, `posts`.`title`, `posts`.`pubdate`, `posts`.`body`, `posts`.`comments_num`, `posts`.`cat_id`, `posts`.`slug`, `categories`.`id` AS cat_id, `categories`.`title` AS cat_title, `categories`.`slug` AS cat_slug, `tags`.`id` AS tag_id, `tags`.`title` AS tag_title, `tags`.`slug` AS tag_slug
  2. FROM (`posts`)
  3. LEFT JOIN `categories` ON `posts`.`cat_id` = `categories`.`id`
  4. LEFT JOIN `relation_pt` ON `posts`.`id` = `relation_pt`.`post_id`
  5. LEFT JOIN `tags` ON `relation_pt`.`tag_id` = `tags`.`id`
  6. ORDER BY `pubdate` DESC
  7. LIMIT 10


Вопрос: Есть ли возможность получить результат с массивом тегов? И как?
Мб есть более производительное решение?
Спасибо!
Specter Отправлено: 10 Августа, 2014 - 17:32:53 • Тема: Получение данных из адресной строки • Форум: Вопросы новичков

Ответов: 9
Просмотров: 391
DelphinPRO пишет:
Извиняюсь, невнимательно прочел. Вы и так регами парсите.
Но всё же - что насчет штатных средств системы?

Я использую Codeigniter.
Штатный роутинг имеет вид /controller/method/var/var и т.д.
Реализация роутинга идет чере /controller/method/.
Данная реализация меня не устраивает.
Пока остановился на таком костыле
PHP:
скопировать код в буфер обмена
  1.  
  2.                 $uri = $this->uri->uri_string();
  3.                
  4.                 $pattern = $this->routes_rules['category'];
  5.                 $pattern = str_replace(':id', '[0-9]+', str_replace(':slug', '[a-zA-Z0-9_-]+', $pattern));     
  6.                
  7.                 preg_match ('#^'.$pattern.'$#', $uri, $matches);
  8.  
  9.  
  10.                 if(count($matches) > 2){
  11.                         if(is_numeric($matches[1])){
  12.                                 $id = $matches[1];
  13.                                 $slug = $matches[2];
  14.                         }else{
  15.                                 $id = $matches[2];
  16.                                 $slug = $matches[1];
  17.                         }
  18.                 }else{
  19.                         if(is_numeric($matches[1])){
  20.                                 $id = $matches[1];
  21.                                 $slug = null;
  22.                         }else{
  23.                                 $id = null;
  24.                                 $slug = $matches[1];
  25.                         }
  26.                 }
  27.  

Реализация убогая конечно, мб есть более красивый вариант?
Specter Отправлено: 10 Августа, 2014 - 15:52:41 • Тема: Получение данных из адресной строки • Форум: Вопросы новичков

Ответов: 9
Просмотров: 391
DelphinPRO пишет:
Если у вас готовая система, то в ней должны быть штатные методы для получения этих данных.

Ну и если хочется руками, то для правила (:id)-(:slug)



как-то так. Возможно регулярка неточная, но смысл должен быть понятен

А если захочется (:slug)-(:id) ?
Я получаю все данные исходя из руглярки
PHP:
скопировать код в буфер обмена
  1. $pattern = str_replace(':id', '[0-9]+', str_replace(':slug', '[a-zA-Z0-9_-]+', $pattern));     
  2. preg_match ('#^'.$pattern.'$#', $uri, $matches);
  3.  

но в matches я не могу четко определить, есть ли id, есть ли slug и т.п.
Specter Отправлено: 09 Августа, 2014 - 14:39:56 • Тема: Получение данных из адресной строки • Форум: Вопросы новичков

Ответов: 9
Просмотров: 391
Object пишет:
Ну тогда нужно в каких-то конфигах описывать в каком шаблоне, что за чем следует. У Вас же не будет несколько шаблонов работать одновременно. Например в одном шаблоне первым идет контроллер, потом метод, потом параметры, а в другом наоборот, сначала метод потом контроллер. Хотя везде сначала идет контроллер потом метод. Как может быть метод без контроллера?

Правила динамически цепляются при инициализации. С этим проблем нет. Все структурировано.
Мне нужно получить значения id и slug, исходя из правил роутинга, чтобы получить данные из бд.
Грубо говоря мне нужно получить значения id и slug.
Есть какое либо правило в переменной.
Правило мб: (:id)-(:slug), или (:slug)-(:id), или (:slug), или (:id)
Мы знаем это правило.
Есть значение урла, сформированного исходя из этого правила.
Например правило (:id)-(:slug) -> урл: 22-news-nokia
В переменную $id нужно получить 22, а в $slug = news-nokia
Другой вариант, правило (:slug) -> урл:news-nokia
В $id = null; $slug = news-nokia
Specter Отправлено: 09 Августа, 2014 - 13:27:36 • Тема: Получение данных из адресной строки • Форум: Вопросы новичков

Ответов: 9
Просмотров: 391
Object пишет:
Specter пишет:
Поэтому я не могу точно сказать что находится в массиве.
Значит это кривая реализация. Чтобы не иметь гемора, нужно четко структурировать Ваши урлы.

Вот основы роутинга в MVC:


Наверное меня неправильно поняли. Допустим в админке я выбрал шаблон формирование урлов (:id)-(:slug), все ссылки поменяли вид на данный шаблон. Но чтобы избежать дублирования страниц мне необходимо проверить значения id и slug на предмет принадлежности к одной и той же записи.
Что вы понимаете под "четко структурировать Ваши урлы."?
Я хочу иметь возможность менять урлы, но с привязкой к конкретному контролеру/методу.
Specter Отправлено: 09 Августа, 2014 - 12:37:25 • Тема: Получение данных из адресной строки • Форум: Вопросы новичков

Ответов: 9
Просмотров: 391
Добрый день.
есть правила формирование урлов:
(:id)-(:slug) или например (:slug)-(:id), или просто (:slug) или просто (:id)
т.е. урлы будут такими
1-news-rusiia
или
news-russia-1
или
news-rusiia
или
1
Проблема заключается в том, как вытянуть (:slug) и (:id).
Делаю так
PHP:
скопировать код в буфер обмена
  1.  
  2. $uri = 'тут значение адресной строки';
  3. $pattern = $this->routes_rules['category']; // получаем шаблон для формирования ссылки
  4. $pattern = str_replace(':id', '[0-9]+', str_replace(':slug', '[a-zA-Z0-9_-]+', $pattern)); // делаем регулярку
  5.  preg_match ('#^'.$pattern.'$#', $uri, $matches);
  6. // в $matches теперь массив
  7.  

Тут я в тупике, подскажите более рациональное решение, чем плодить кучу условий по проверке.
Исходя из шаблона формирования урлов в $matches[1] или $matches[2] будут всегда разные данные. Поэтому я не могу точно сказать что находится в массиве.
Таким образом сложно получить на выходе :
$id, $slug
Подскажите как решть данную проблему.
Specter Отправлено: 04 Августа, 2014 - 16:32:08 • Тема: Правила роутинга из бд Codeigniter • Форум: CMS и фреймворки

Ответов: 0
Просмотров: 987
Добрый вечер.
Подскажите как реализовать динамический роутинг, исходя из правил записанных в бд.
В таблице routes 3 поля. Name, и Route, Controller соответственно.
Например:
category | id-slug | category
post | /category/slug.html | post
Из бд достаем, обрабатываем. Получаем например для post: '(:num)-(:any)/(:any).html'
Как эти правила подключать? В файле routes.php? - как мне вариант не очень, поскольку придется подключать бд, и все обрабатывать в этом файле.
Производный класс от CI_Routes? - не пойму как реализовать.
Подскажите пожалуйста логику, пример кода.
Благодарю.
Specter Отправлено: 25 Июля, 2014 - 22:24:45 • Тема: Два разных массива, определить отличие • Форум: Вопросы новичков

Ответов: 3
Просмотров: 176
for пишет:
Попробуй клаузулу WHERE. Если больше чем одно значение хочешь вытащить то в связке с IN.

Как раз таки использую ее. На выходе массив:
PHP:
скопировать код в буфер обмена
  1. $ar2 = array([0]=>Array
  2.         (
  3.             ['id'] => 1,
  4.             ['title'] => козел
  5.         )
  6.  
  7.     [1] => Array
  8.         (
  9.             ['id'] => 2,
  10.             ['title'] => волк
  11.         ));

$this->db->where_in('titles', $ar1);
Specter Отправлено: 25 Июля, 2014 - 18:01:22 • Тема: Два разных массива, определить отличие • Форум: Вопросы новичков

Ответов: 3
Просмотров: 176
Здравствуйте.
Ближе к сути.
Есть два массива:

PHP:
скопировать код в буфер обмена
  1.  
  2. // 1 массив
  3. $ar1 = array('хомяк', 'козел', 'волк');
  4. // 2 массив
  5. $ar2 = array([0]=>Array
  6.         (
  7.             ['id'] => 1,
  8.             ['title'] => козел
  9.         )
  10.  
  11.     [1] => Array
  12.         (
  13.             ['id'] => 2,
  14.             ['title'] => волк
  15.         ));
  16.  

Как узнать есть ли "хомяк" в первом массиве?
Есть более изящное решение чем через foreach?
На выходе хорошо бы получить 2 массива
PHP:
скопировать код в буфер обмена
  1.  
  2. $re1 = array(id,id);
  3. $re2 = array("хомяк", и т.д.);
  4.  

Затык у меня один простой массив, второй многомерный ассоц.
----
М.б. есть возможность избежать перебора массивов, правильно сформировав запрос к бд?
Использую CI.
Запрос пишу таким образом
PHP:
скопировать код в буфер обмена
  1.  $this->db->where_in('titles', $ar1);

В итоге получаю второй массив ar2. Хорошо было бы получить последовательные данные от бд, т.е.
PHP:
скопировать код в буфер обмена
  1. $ar2 = array(
  2.  
  3. [0]=>Array
  4.         (
  5.             ['id'] => null/false,
  6.             ['title'] => null/false
  7.         ),
  8. [1]=>Array
  9.         (
  10.             ['id'] => 1,
  11.             ['title'] => козел
  12.         ),
  13.  
  14.     [2] => Array
  15.         (
  16.             ['id'] => 2,
  17.             ['title'] => волк
  18.         ));

Есть идеи?

Страниц (2): [1] 2 »
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB