1

I have a folder containing images that I want to put inside a Bootstrap carousel. Instead of hardcode everything in my HTML, I thought to use PHP to scan the image files and create my carousel list dynamically.

After various attempts, my best achievement was having a carousel listing the names of my images (rather than the image themselves).

My code is below. I have two question about it:

  1. (obviously) Why is it not working?
  2. Is there a better way to separate such a long PHP function from the HTML code (like a call with include but that would work with functions)?

    <div class="container-fluid">
      <?php
        $img_folder = './img/img_animazione/';
        function carousel_loop($folder)
        {
          echo '<div id="myCarousel" class="carousel slide" data-ride="carousel">';
          echo '<ol class="carousel-indicators">';
          $i = -1;
          $images = scandir($folder);
          foreach($images as $image) {
            $i++; //$i is the index of the current loop.
            if ($i == 0) {
              echo '<li data-target="#myCarousel" data-slide-to="' . $i . '" class="active"></li>';
            } else {
              echo '<li data-target="#myCarousel" data-slide-to="' . $i . '"</li>';
            }
          }
          echo '</ol>';
          echo '<div class="carousel-inner">';
          foreach($images as $image) {
            if ($image === reset($images)) {
              echo '<div class="item active">';
              echo '<img src="' . $image . '" alt="'. $image . '">';
              echo '</div>';
            } else {
              echo '<div class="item">';
              echo '<img src="' . $image . '" alt="'. $image . '">';
              echo '</div>';
            }
          }
          echo '</div>'; 
          echo '<a class="left carousel-control" href="#myCarousel" data-slide="prev">';
          echo '<span class="glyphicon glyphicon-chevron-left"></span>';
          echo '<span class="sr-only">Previous</span>';
          echo '</a>';
          echo '<a class="right carousel-control" href="#myCarousel" data-slide="next">';
          echo '<span class="glyphicon glyphicon-chevron-right"></span>';
          echo '<span class="sr-only">Next</span>';
          echo '</a>';
          echo '</div>';
        }
        carousel_loop($img_folder);
      ?>
    </div>
    
umbe1987
  • 2,894
  • 6
  • 35
  • 63

2 Answers2

1

That's not the way to use functions. You can't echo like that from inside the function. You have to build up the HTML inside the function and return it. Then either just echo the function or assign what it returns to a variable.

So like this:

<?php
   function carousel_loop($folder)
   {
   html = "";
   html .= '<div id="myCarousel" class="carousel slide" data-ride="carousel">';
   html .= '<ol class="carousel-indicators">';
   $i = -1;
   $images = scandir($folder);
   foreach($images as $image) {
      $i++; //$i is the index of the current loop.
      if ($i == 0) {
        html .= '<li data-target="#myCarousel" data-slide-to="' . $i . '" class="active"></li>';
      } else {
         html .= '<li data-target="#myCarousel" data-slide-to="' . $i . '"</li>';
      }
    }
    html .= '</ol>';
    html .= '<div class="carousel-inner">';
    foreach($images as $image) {
      if ($image === reset($images)) {
        html .= '<div class="item active">';
        html .= '<img src="' . $image . '" alt="'. $image . '">';
        html .= '</div>';
      } else {
        html .= '<div class="item">';
        html .= '<img src="' . $image . '" alt="'. $image . '">';
        html .= '</div>';
      }
    }
    html .= '</div>'; 
    html .= '<a class="left carousel-control" href="#myCarousel" data-slide="prev">';
    html .= '<span class="glyphicon glyphicon-chevron-left"></span>';
    html .= '<span class="sr-only">Previous</span>';
    html .= '</a>';
    html .= '<a class="right carousel-control" href="#myCarousel" data-slide="next">';
    html .= '<span class="glyphicon glyphicon-chevron-right"></span>';
    html .= '<span class="sr-only">Next</span>';
    html .= '</a>';
    html .= '</div>';

    return html;
}
?>
<div class="container-fluid">
<?php
$img_folder = './img/img_animazione/';
echo carousel_loop($img_folder);
?>
</div>
abetwothree
  • 575
  • 2
  • 8
  • 28
  • Thanks: I got the point: I have to transform everything into a "mega HTML string" and print the return of my function with echo. However, I am trying your code and it is not working. – umbe1987 Jun 04 '17 at 10:41
  • ok so I finally found two big problems to the code, and eventually came up with a working (although still "dirt") solution. 1) `$image` is only the name of a file, but `src` wants path/to/image, so I did `$folder . DIRECTORY_SEPARATOR . $image`; 2) `scandir()` gives me also `.` and `..` (working and parent directory) in the array `$image`, so I solved by doing `$allFiles = scandir($folder); $images = array_diff($allFiles, array('.', '..'));` as in proposed https://stackoverflow.com/a/7132422/1979665. I'll insert everything as an answer asap. – umbe1987 Jun 05 '17 at 21:02
0

Thanks to @Abraham A. answer, I finally was able to come up with a working (still "dirt") solution. I'll post the code below. The problems in my initial code were:

  1. Using echo within a function instead of returning a (very long) HTML string in the function and "echoing" it from outside.
  2. <img src= obviously wants a source and not just a filename. My first attempt was <img src= . $image, the correct form is <img src= . $folder . DIRECTORY_SEPARATOR . $image
  3. It seems like [scandir()][1] creates an array with all the filenames within a folder AND ".", ".." (current and parent folder) in it. I got rid of the latters via $allFiles = scandir($folder); $images = array_diff($allFiles, array('.', '..')); as suggested here.

My working code is this one now.

<?php
   function carousel_loop($folder)
   {
     $html = "";
     $html .= '<div id="myCarousel" class="carousel slide" data-ride="carousel">';
     $html .= '<ol class="carousel-indicators">';
     $i = -1;
     $allFiles = scandir($folder); // list all files in folders
     $images = array_diff($allFiles, array('.', '..')); // drop current and parent folder from array list (".", "..")
     foreach($images as $image) {
       $i++; //$i is the index of the current loop.
       if ($i == 0) {
         $html .= '<li data-target="#myCarousel" data-slide-to="' . $i . '" class="active"></li>';
       } else {
         $html .= '<li data-target="#myCarousel" data-slide-to="' . $i . '"></li>';
       }
     }
     $html .= '</ol>';
     $html .= '<div class="carousel-inner">';
     foreach($images as $image) {
       if ($image === reset($images)) {
         $html .= '<div class="item active">';
         $html .= '<img src="' . $folder . DIRECTORY_SEPARATOR . $image . '" alt="' . $image . '" style="width:100%;">';
         $html .= '</div>';
       } else {
         $html .= '<div class="item">';
         $html .= '<img src="' . $folder . DIRECTORY_SEPARATOR . $image . '" alt="' . $image . '" style="width:100%;">';
         $html .= '</div>';
       }
     }
     $html .= '</div>';
     $html .= '<a class="left carousel-control" href="#myCarousel" data-slide="prev">';
     $html .= '<span class="glyphicon glyphicon-chevron-left"></span>';
     $html .= '<span class="sr-only">Previous</span>';
     $html .= '</a>';
     $html .= '<a class="right carousel-control" href="#myCarousel" data-slide="next">';
     $html .= '<span class="glyphicon glyphicon-chevron-right"></span>';
     $html .= '<span class="sr-only">Next</span>';
     $html .= '</a>';
     $html .= '</div>';

     return $html;
   }
?>

<div class="container">
  <?php
    $img_folder = './img/img_animazione';
    echo carousel_loop($img_folder);
  ?>
</div>
umbe1987
  • 2,894
  • 6
  • 35
  • 63
  • Glad you got it working. Didn't have a chance to help out again and even then I didn't have the images or folder structure to error check the images not showing up. – abetwothree Jun 06 '17 at 02:28