Одно тело и 2 конструкции цикла. Как?

Тема в разделе "PHP", создана пользователем Ewsen, 5 окт 2011.

Модераторы: latteo
  1. Ewsen

    Ewsen

    Регистр.:
    26 июл 2008
    Сообщения:
    163
    Симпатии:
    59
    Практически не имея знаний в PHP я намудрил такое
    PHP:
    if ( условие ) {
        while ( 
    $cat_posts->have_posts() )
        {
            
    $cat_posts->the_post();
                    
    // тело цикла
            
    }
    } else {
            foreach (
    $cat_posts as $post){
                    
    setup_postdata($post);
                    
    // тело цикла
    }
    }
    // тело цикла(одинаковое) - Достаточно большой кусок кода. Можно ли как-то сделать, чтобы тело цикла в коде было 1 раз, но применялось в разных конструкциях цикла.

    Или может другой вариант:
    в первом случае while ( $posts->have_posts() )
    $cat_posts формируется таким запросом
    PHP:
    $cat_posts = new WP_Query ...
    Я не могу понять что это за тип данных и как его можно перевести в массив, чтобы можно было использовать только только одну конструкцию цикла foreach ($cat_posts as $post)
     
  2. zzallexx

    zzallexx

    Регистр.:
    11 июн 2008
    Сообщения:
    1.037
    Симпатии:
    702
  3. t3s

    t3s

    Регистр.:
    16 фев 2008
    Сообщения:
    719
    Симпатии:
    290
    это стандартный запрос вордпресса

    вообще в вп содержится куча готовых функций, которые покрывают 80-90% потребностей начинающих разработчиков - возможно для вашей задачи уже существует готовый велосипед?
    попробуйте в гугле вбить codex wordpress

    можно предположить что вы хотите сделать для одних рубрик/страниц один вывод инфы, а для других - другой
    это можно сделать гораздо проще без условий - просто вписав код в разных файлах - например index.php и category.php
     
  4. Ewsen

    Ewsen

    Регистр.:
    26 июл 2008
    Сообщения:
    163
    Симпатии:
    59
    У меня есть многофункциональная тема для ВП со своими виджетами в functions.php Там очень удобно настраивается вывод постов с превью (за отображение отвечает тело цикла и оно большое, т. к. там предусмотрен вывод в несколько колонок, с тайтлом/без, с превью/без, дата, автор, описание и т.п.:(
    -вывод новых
    -вывод новых из категории
    -вывод новых текущей категории
    -рандомный вывод
    и все это до цикла с выводом собирается запросом
    PHP:
    $cat_posts = new WP_Query ...  
    проблема этого в том что всегда происходит сортировка постов либо по возрастанию либо по убыванию
    Но я хочу сделать еще вывод похожих новостей который очень умно выводит предидущие посты из текущей категории, а если их не хватает, то добирает первые из той же категории и при этом сортировки не происходит. То что мне и надо.
    Вот эта функция, которая возвращает массив с нужными постами:
    PHP:
    function show_previous_posts_from_category ($the_post_id$the_category_id 0$post_num) {

    $num 0;
    global 
    $wpdb;

    $sql "SELECT wposts.*
    FROM 
    $wpdb->posts wposts
    LEFT JOIN 
    $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
    LEFT JOIN 
    $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
    WHERE 
    $wpdb->term_taxonomy.taxonomy = 'category'
    AND 
    $wpdb->term_taxonomy.term_id = '$the_category_id'
    AND wposts.post_status = 'publish'
    AND wposts.post_type = 'post'
    AND wposts.ID < '
    $the_post_id'
    ORDER BY wposts.ID DESC
    LIMIT 
    $post_num";

    $result $wpdb->get_results($sqlOBJECT);
    global 
    $post;

    foreach (
    $result as $post) {
    setup_postdata($post);
    $cat_posts[] = $post;
    $num++;
    $save_ids[] = $post->ID;
    }
    if ( 
    $num $post_num || !$result ) {
    $need_more $post_num-$num;
    $save_ids[] = $the_post_id;
    $save_ids join (','$save_ids);
    $more_posts get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
    foreach (
    $more_posts as $post){
    setup_postdata($post);
    $cat_posts[] = $post;
    }
    }
    return 
    $cat_posts;
    Вопрос только как сделать чтобы при одном условии в цикле выводить посты собранные этой функцией, а при другом
    PHP:
    $cat_posts = new WP_Query ...  
    На этом сайте как раз рассмотрены 2 способа вывода похожих записей как у меня
    Перейти по ссылке
    В каждом из способов использованы разные конструкции циклов (в первом foreach ($more_posts as $post), во втором while ($my_query->have_posts())), а тело вывода постов можно сказать одинаковое (<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>)

    Только в моем случае тело вывода постов намного сложнее. Вот я и хочу объединить эти 2 способа поставив условие для применения одного или другого при этом тело цикла для вывода постов применить в коде 1 раз
     
  5. KooL

    KooL Писатель

    Регистр.:
    28 сен 2011
    Сообщения:
    4
    Симпатии:
    1
    Звучит глупо, но нельзя ли вынести тело обоих циклов в функцию раз оно одинаковое?
     
    Ewsen нравится это.
  6. Ewsen

    Ewsen

    Регистр.:
    26 июл 2008
    Сообщения:
    163
    Симпатии:
    59
    Вот что значит перемудрил... Как я раньше до этого не додумался. Это то что надо. Спасибо
     
  7. t3s

    t3s

    Регистр.:
    16 фев 2008
    Сообщения:
    719
    Симпатии:
    290
    проблема этого в том что вы элементарно ленитесь последовать совету

    если бы вбили в гугле фразу codex wordpress (или wordpress codex), то уже знали бы что в WP_Query() можно использовать кучу аргументов, например
    PHP:
    $query = new WP_Query'author=123' );
    выведет посты чувака с ником 123
    PHP:
    $query = new WP_Query("cat=4&orderby=rand");
    выведет рандомно посты из категории с ид 4
    и так далее (примеры оттуда)...

    а если желаете пользоваться "своей" функцией - то в вашем примере сортировка это ORDER BY wposts.ID DESC
    можете просто ее менять в зависимости от условий - к примеру ORDER BY wposts.post_date DESC отсортирует по дате, а "волшебное" слово RANDOM дернет посты без сортировки
     
  8. Ewsen

    Ewsen

    Регистр.:
    26 июл 2008
    Сообщения:
    163
    Симпатии:
    59
    Здесь я не соглашусь. Я перечитал информацию отсюда Перейти по ссылке
    WP_Query не заменит эту функцию
    PHP:
    <?php
    function show_previous_posts_from_category ($the_post_id$the_category_id 0$post_num) {
     
    $num 0;
    global 
    $wpdb;
     
    $sql "SELECT wposts.*
    FROM 
    $wpdb->posts wposts
    LEFT JOIN 
    $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
    LEFT JOIN 
    $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
    WHERE 
    $wpdb->term_taxonomy.taxonomy = 'category'
    AND 
    $wpdb->term_taxonomy.term_id = '$the_category_id'
    AND wposts.post_status = 'publish'
    AND wposts.post_type = 'post'
    AND wposts.ID < '
    $the_post_id'
    ORDER BY wposts.ID DESC
    LIMIT 
    $post_num";
     
    $result $wpdb->get_results($sqlOBJECT);
    global 
    $post;
    ?>
    <ul>
    <?php
    foreach ($result as $post) {
    setup_postdata($post);
    ?>
    <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
    <?php
    $num
    ++;
    $save_ids[] = $post->ID;
    }
    if ( 
    $num $post_num || !$result ) {
    $need_more $post_num-$num;
    $save_ids[] = $the_post_id;
    $save_ids join (','$save_ids);
    $more_posts get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
    foreach (
    $more_posts as $post){
    setup_postdata($post);
    ?>
    <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
    <?php
    }
    }
    ?>
    </ul>
    <?php ?>
     
    <?php
    $the_cat 
    get_the_category();
    $the_cat_id $the_cat[0]->cat_ID;
    show_previous_posts_from_category($post->ID$the_cat_id5);
    wp_reset_query();
    ?>
    т. к. она выводит именно предидущие посты
    PHP:
    AND wposts.ID '$the_post_id'
    а если их не хватает, то добирает из той же категории
    PHP:
    $more_posts get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
    и при этом не сортирует полученный массив

    В итоге в похожих новостях не будет мелькать постоянно свежая новость из категории