Hello. I deduce articles on the site using a cycle:

$last_news = mysql_query("SELECT * FROM `news` ORDER BY `id` DESC"); while ($lnews = mysql_fetch_assoc($last_news)) { //разметка } 

I need to get this markup on the page

 <div id="r_block"> тут три статьи </div> <div id="r_block"> тут три статьи </div> <div id="r_block"> тут три статьи </div> 

And each time there were 3 articles in the r_block block

How to implement it in my cycle? I would be grateful for the help.

    4 answers 4

    Count the displayed articles and based on the remainder of the division of the line number by 3 arrange the required markup. Something like this:

     $last_news = mysql_query("SELECT * FROM `news` ORDER BY `id` DESC"); $num=0; while ($lnews = mysql_fetch_assoc($last_news)) { if($num % 3 == 0) { echo '<div id="r_block">'; } //разметка if($num % 3 == 2) { echo '</div>'; } $num++; } if($num % 3 != 0) { echo '</div>'; } 
    • Thank you very much. Now I realize myself and accept the answer - iKey
    • one
      @Denis, I would look at the answer below, Ipatiev, and this answer is minus for brawl and for laziness, you must put brackets. And then more and more people write in PHP how to js spit on parentheses and it’s better that way ?: Write what are three whole characters, etc. - Naumov
    • @Naumov I do not understand, you are talking about some brackets, after echo, whatever the function looked like ... Yes, you can. Or do you mean something else? - Mike
    • @Naumov And yes, of course I saw the answer Ipatiev. And personally, I don’t like the modern style of PHP in which because of the heap of tags the program code is not visible. Debugging someone else's code becomes unbearable. - Mike
    • @Mike what? tags you just output them to echo , curly braces {} . and in general it is better not to interfere with logic and representation. Now the servers are cheap and powerful, and the interpreters are faster, let's say the same php7 on which this solution will not work, plus there are a lot of ways of caching and server implementation of the site functions written in C ++ and working several times faster. So it is worth choosing from the ratio of speed and reliability and ease of support. server solutions such as sphinx search, varnish caches, etc. - Naumov
    1. PDO should be used instead of mysql_query.
    2. Instead of output on the spot, use a template.

    Therefore, we do this:

    first get the data you need

     $sql = "SELECT * FROM `news` ORDER BY `id` DESC LIMIT 15"; $last_news = $pdo->query($sql)->fetchAll(); 

    then break this array into pieces of three lines

     $out = array_chunk($last_news, 3); 

    and finally output in the pattern

     <?php foreach($out as $chunk): ?> <div id="r_block"> <?php foreach($chunk as $row): ?> <div> <a href="<?=$row['url']?>"><?=$row['title']?></a> </div> <?php endforeach ?> </div> <?php endforeach ?> 

    The approach described in another answer was used in the last century, when no one knew how to write in PHP. And now, writing this way, mixing work with the database, HTML and calculating on your fingers how many lines to print each time - this once again confirms the reputation of PHP as a wretched language that everyone despises. Don't do that.

    • I completely agree, unless array_chunk($last_news, 3) can be array_chunk($last_news, 3) right in the foreach. - Zhukov Roman
    • Elegant solution! - Kernel Panic
    • one
      @ZhukovRoman Why is it there to complicate reading and debugging, so you just put a breakpoint on the $out variable and see the array in xdebug and idea ... - Naumov 2016 at 1:15 pm
    • : o_O someone else such answers are minus, guys have the courage for that minus? or that only know how to press the buttons? - Naumov
    • one
      @ZhukovRoman but if you figure it out so why is it needed at all ... and even there, the answer is simply foreach in the template and the variable is somewhere in logic. - Naumov

    In short, you can zaminovatov, for what I publish a refutation of the answer @Mike in support of @ Ipatiev ...

    But still I will do it ...

    and so consider the array_chunk function

     /* {{{ proto array array_chunk(array input, int size [, bool preserve_keys]) Split array into chunks */ PHP_FUNCTION(array_chunk) { int argc = ZEND_NUM_ARGS(), num_in; zend_long size, current = 0; zend_string *str_key; zend_ulong num_key; zend_bool preserve_keys = 0; zval *input = NULL; zval chunk; zval *entry; if (zend_parse_parameters(argc, "al|b", &input, &size, &preserve_keys) == FAILURE) { return; } /* Do bounds checking for size parameter. */ if (size < 1) { php_error_docref(NULL, E_WARNING, "Size parameter expected to be greater than 0"); return; } num_in = zend_hash_num_elements(Z_ARRVAL_P(input)); if (size > num_in) { size = num_in > 0 ? num_in : 1; } array_init_size(return_value, (uint32_t)(((num_in - 1) / size) + 1)); ZVAL_UNDEF(&chunk); ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) { /* If new chunk, create and initialize it. */ if (Z_TYPE(chunk) == IS_UNDEF) { array_init_size(&chunk, (uint32_t)size); } /* Add entry to the chunk, preserving keys if necessary. */ if (preserve_keys) { if (str_key) { entry = zend_hash_update(Z_ARRVAL(chunk), str_key, entry); } else { entry = zend_hash_index_update(Z_ARRVAL(chunk), num_key, entry); } } else { entry = zend_hash_next_index_insert(Z_ARRVAL(chunk), entry); } zval_add_ref(entry); /* If reached the chunk size, add it to the result array, and reset the * pointer. */ if (!(++current % size)) { add_next_index_zval(return_value, &chunk); ZVAL_UNDEF(&chunk); } } ZEND_HASH_FOREACH_END(); /* Add the final chunk if there is one. */ if (Z_TYPE(chunk) != IS_UNDEF) { add_next_index_zval(return_value, &chunk); } } 

    And so pay attention to the line

     /* If reached the chunk size, add it to the result array, and reset the * pointer. */ if (!(++current % size)) { add_next_index_zval(return_value, &chunk); ZVAL_UNDEF(&chunk); } 

    What does she tell us? the same is correct as in the answer we calculate the remainder of the division by this same size and add the resulting chunk return_value; note the chunk is the link ie physically, this is one variable. While this code is more optimized as it is:

    1. Compiled

    2. It is typed (there is no type conversion, etc., etc.)

    3. A hash of the size from the most needed length is created without a stock (for older versions of php there may be another implementation)

    those. in fact, we see that the answer from the T-shirt is a little less than the full functionality of array_chunk and even in speed and in memory consumption, they will be comparable, in certain relative planes.

    ps @Mike so I see no reason to write 'not nice' for the sake of dubious optimization.

    source code: https://github.com/php/php-src/blob/bd9858ead26f2b1537ca61f3f5a136f8ec160a27/ext/standard/array.c

    pps Well, a little argument for coding stait

    simple example

      if($num % 3 == 2) echo '</div>'; $num++; 

    no mistakes, all is well.

      if($num % 3 == 2) // echo '</div>'; $num++; 

    There are no errors, but the algorithm does not work.

    more common example

     // тут сотня строк подобного кода if($b == 2) $a = 2; $a=1; // ну и тут так же 

    good example seen in coding style for si writing conditions

     if(2 == $a) {} 

    cool yes sealed like this if(2=$a) and you got a mistake. and if we examine how we write

     if($a == 2) {} 

    and if if($a=2) sealed, then $a is equal to 2, there is no error, the algorithm is not working.

    pps I still think that it is necessary to write beautifully and what would work, while in the community where they help, so that the junior would not ask the Temlid, а где ты вот этот кусочек откапал кода? did а где ты вот этот кусочек откапал кода?

    • one
      I agree with everything except "in terms of speed and memory consumption, they will be comparable." On small arrays (in his answer, Ipatiev limited the sample to only 15 elements, in the case of articles this is quite logical) this is true (double memory consumption will most likely not be noticeable, against the background of everything else). But on large arrays, the Ipatiev code can drop in memory or execution time (the materialized data weighs much more than the query result (at least in mysql and mysqli), and allocations that occur in array_chunk can take quite a lot of time). - Arnial
     $i = 1; echo( '<div id="r_block">' ); while ($lnews = mysql_fetch_assoc($last_news)) { //разметка if ( $i == 3 ) { echo( '</div><div id="r_block">' ); $i = 1; } else { $i++; } } echo( '</div>' ); 
    • Find a bug in your code? and understand why the minus ... - Naumov
    • I would be grateful if you tell me where the bug is. - Zim
    • @Zim is so difficult that you cannot even read your solution and find a mistake in it, it’s easier to write so that at a glance you can see what’s wrong ... - Naumov
    • Well, I do not understand in php. But I want to know where the bug is, it's not difficult for you. - Zim
    • @UrmuzTagizade do not be so categorical, and do not be rude to a person, it is his right to answer or not to answer - Naumov