0

My while loop is decrementing by two and I cannot find the cause.

I feel that I do not understand how PHP is interacting with the HTML.
Any words of clarity? (Note the index of the dictionaries start at 1)

if (isset($title)) { 
    $i = sizeof($title);

    while ($i > 0) {
        $idnum = intostring($i); 
        $titletoadd = $title[$idnum];
        $summarytoadd = $summary[$idnum];

        $podcastblock =<<<EOD
        <div class="podcast" id="podcast$idnum">
         <p class="podcasttitle" id="podcasttitle$idnum">$titletoadd</p>
         <div class="container column horizontal-spaced ">
         <p class="podcastnumber left shrink " id="podcastnumber$idnum">$i</p>
         <p class="summary grow" id="summary$idnum">$summarytoadd</p>
         </div>
          <audio class="audioplayer tile displaymiddle wide"  id='audioplayer$idnum" controls>
          <source src="audiofiles/p$i.mp3" type="audio/mpeg">
        </audio>

        EOD;

        echo $podcastblock; 
        $i--;
    }
kyledewy
  • 3
  • 3

3 Answers3

1

You have a typo on this line:

<audio class="audioplayer tile displaymiddle wide"  id='audioplayer$idnum" controls>

You're starting the id attribute value with a single quote, bit ending it with a double quote. As a result, everything until the next <audio element is being used as part of the id, not as separate HTML elements. So you only see every other DIV.

Change to:

<audio class="audioplayer tile displaymiddle wide"  id="audioplayer$idnum" controls>
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

first of, remove this particular code $idnum = intostring($i); you dont need this. Change it to $idnum = $i;

It is not really decrementing by two, if you try to fill your $title array with 10 or more elements. In this way you can observe what's happening

Here are your mistakes:

$title = array("title1", "title2");

/* The array starts from 0 index then 1, 2 and so on
once you get the size of the array it
just counts the elements in the array
but not really knowing the last index */

$i = sizeof($title);

/* in this case our $i have now the value of 2
$title[2] does not exists because we only have two elements
namely $title[0] and $title[1]... this is your first mistake */

// second mistake:

while ($i > 0)

/* our array starts from zero, with this condition,
you're basically skipping zero index (beginning of the array) */

// to fix these you need to put the following codes

$i = (count($title) - 1); /* use count instead of sizeof but they are completely the same...
subtract 1 to the total count to get the last index of the array */

while ($i >= 0) // lastly include the 0 index

Hope this helps.

Ram
  • 508
  • 3
  • 13
  • Thanks, I didn't know that about PHP. As for the indexing, I forgot to mention the dictionary I made starts at index "1" so the index alignment is alright, but it is still decrementing by 2. – kyledewy Feb 20 '16 at 01:07
0

There is nothing in this code that would cause your $i to be decremented by 2. If there is an extra decrement happening, it would have to be in your intostring() method.

However, there are a few other issues happening here. You have a rogue single quote in your html and it's missing the closing div tag. I can make a few suggestions to clean this up a bit.

  1. For blocks of HTML wrapped in PHP, it's easier to understand how PHP interacts with the HTML if you start and end your PHP string with a single quote, use all Double quotes inside the HTML elements, and explicitly inject the PHP variables using string concatenation like: '. $variable .'

  2. You don't have to cast the $i to a string, PHP will handle that for you.

  3. I think a for loop is a little cleaner in this situation and it makes the intention of the code more clear.

Try this:

$title = array("Title1","Title2","Title3");
$summary = array("Summary1","Summary2","Summary3");

if (isset($title)) {

    for ($i= count($title); $i > 0; $i--) {
        $titletoadd = $title[$i];
        $summarytoadd = $summary[$i];

        $podcastblock = '
        <div class="podcast" id="podcast'. $i .'">
            <p class="podcasttitle" id="podcasttitle'. $i .'">'. $titletoadd .'</p>
            <div class="container column horizontal-spaced ">
                <p class="podcastnumber left shrink " id="podcastnumber'. $i .'">'. $i .'</p>
                <p class="summary grow" id="summary'. $i .'">'. $summarytoadd .'</p>
            </div>
            <audio class="audioplayer tile displaymiddle wide" id="audioplayer'. $i .'" controls>
                <source src="audiofiles/p'. $i .'mp3" type="audio/mpeg">
            </audio>
        </div>';

        echo $podcastblock;
    }

}
James Wiley
  • 489
  • 3
  • 8
  • Yes! So the double increment turned out to be something with the heredoc. Can you elaborate why you use this quote structure vs heredoc block quote? – kyledewy Feb 20 '16 at 01:32
  • Personal preference mostly. On a superficial level, it makes your code ugly. And the fact that your closing identifier has to be in the first column on its own row, can break your indention flow and look really out of place. I also have a personal rule that I don't use any feature of PHP that allows white space control execution. You never know when someone on a different operating system or with a different IDE might need to open your code and if line endings aren't handled correctly, your heredoc sections can cause problems that are very difficult to pinpoint. – James Wiley Feb 20 '16 at 04:40
  • Yaa that sounds more robust. Any faster way of doing this? – kyledewy Feb 21 '16 at 19:55
  • I would think about moving this code to javascript instead of doing it in PHP. PHP does all of its processing before the page renders so If you only have a few entries it wont make much of a difference, but if you have a lot of mp3s to load, the user wont see anything on the page until PHP gets all of your entries and builds the page. If this data is coming from a database, you could wrap that part in a PHP service, then call the service from jQuery to load each entry. This way your page will load immediately and the entries will appear as they load. This gives a bettter user experience. – James Wiley Feb 21 '16 at 22:31
  • OK great, I will do that in the future. Thanks for your advise! – kyledewy Mar 03 '16 at 17:22