构建一个PHP函数来显示多维数组中的图像库

时间:2021-11-21 21:33:16

I've spent most of the day trying to wrap my head around multidimensional arrays, in order to build a PHP function that I can call to populate an image gallery that could potentially hold 100s of elements. At this point it would have been easier to just copy and paste the HTML portion over and over again, but I'd like to figure out how to make this work, for future projects.

我花了一整天的时间试图把我的脑袋绕在多维数组上,以便构建一个PHP函数,我可以调用它来填充一个可能包含100多个元素的图像库。在这一点上,复制和粘贴HTML部分会更容易一些,但是我想弄清楚如何在未来的项目中使它工作。

I have found solutions to other questions about foreach loops with multidimensinoal arrays, but I haven't been able to adapt them to my case. In one instance, the closest to my own situation, the solution no longer works--but I don't have the rep to make a comment about it. I used the code from that example as the basis for my own attempt. I welcome any assistance! My comments may help explain what I'm trying to achieve, if it isn't already clear.

我已经找到了关于使用多维窦阵列的foreach循环的其他问题的解决方案,但是我还不能将它们应用到我的例子中。在一个例子中,最接近我自己的情况,解决方案不再有效——但我没有代表对此发表评论。我使用这个例子中的代码作为我自己尝试的基础。我欢迎任何帮助!如果还不清楚的话,我的评论可能有助于解释我想要实现的目标。

Here is my PHP code so far:

下面是我到目前为止的PHP代码:

<?php 
// Use PHP array to populate the image path, title (for alt tag), and longer description (for image caption)
function build_html ($imgsrc, $title, $desc) {
    echo
        '<div class="responsive">
        <div class="gallery">
            <img src="$imgsrc" alt="$title" width="300" height="200">
            <div class="desc">$desc</div>
        </div>
        </div>';
}
// List of images; filenames will be numerical, so later I may switch to using $i++ shortcut in place of imgsrc
$gallery = array (
    array (
    "imgsrc"    =>  "i/Alice0.jpg", 
    "title"     =>  "Front of House", 
    "desc"      =>  "View of the house from the front sidewalk"
    ),
    array ( 
    "imgsrc"    =>  "i/Alice1.jpg", 
    "title"     =>  "Front door", 
    "desc"      =>  "Close-up of front door"
    )
);
// This is just for debugging, to confirm that I really have a multidimensional array
print_r($gallery); 

// BROKEN: this should use foreach loop(s) to gather the elements and pass them to the build_html function defined above.  
function display_gallery () { 
    foreach ($gallery as $img) { 
        $imgsrc = $img['imgsrc'];
        $title = $img['title'];
        $desc = $img['desc'];
        build_html($imgsrc, $title, $desc);

    }
}
// Calling the function in body of page
display_gallery();
?>

Edit: The error message I'm currently getting is:

编辑:我目前收到的错误消息是:

Warning: Invalid argument supplied for foreach() in /home/varlokkur/house.anthropo.org/index.php on line 121

警告:为/home/varlokkur/house.anthropo.org/index.php提供的无效参数,位于第121行

Edit: In case anyone stumbles across this question in the future, here is my modified code that works as expected. Note that the solution offered by aendeerei is a better example to follow, but this solution is closest to the original code. 2 changes to make it work:

编辑:如果将来有人遇到这个问题,这里是我修改过的代码,它可以正常工作。注意,aendeerei提供的解决方案是一个更好的示例,但是这个解决方案最接近原始代码。2个改变使它工作:

  1. Fixed built_html function to properly use the variables that are passed
  2. 修正了built_html函数,以正确使用传递的变量
  3. Fixed display_gallery function to use the $gallery variable
  4. 固定display_gallery函数来使用$gallery变量

Fixed code:

固定的代码:

<?php 
// Use PHP array to populate the image path, title (for alt tag), and longer description (for image caption)
function build_html ($imgsrc, $title, $desc) {
    echo
        '
        <div class="responsive">
        <div class="gallery">
            <img src="' . $imgsrc . '" alt="' . $title . '" width="300" height="200">
            <div class="desc">'. $desc . '</div>
        </div>
        </div>
        ';
}

// List of images; filenames will be numerical, so later I may switch to using $i++ shortcut in place of imgsrc

$gallery = array (
    array (
    "imgsrc"    =>  "i/Alice0.JPG", 
    "title"     =>  "Front of House", 
    "desc"      =>  "View of the house from the front sidewalk"
    ),
    array ( 
    "imgsrc"    =>  "i/Alice1.JPG", 
    "title"     =>  "Front door", 
    "desc"      =>  "Close-up of front door"
    )
);
// This is just for debugging, to confirm that I really have a multidimensional array
//print_r($gallery); 

// BROKEN: this should use foreach loop(s) to gather the elements and pass them to the build_html function defined above.  
function display_gallery ($gallery) { 
//  global $gallery;
    foreach ($gallery as $img) { 
        $imgsrc = $img['imgsrc'];
        $title = $img['title'];
        $desc = $img['desc'];
        build_html($imgsrc, $title, $desc);
    //  var_dump($gallery);
    }
}
//var_dump($gallery);
// Calling the function in body of page
display_gallery($gallery);
?>

3 个解决方案

#1


1  

Notes:

注:

  • I've separated the file name in images list, so it can also be used properly if it's maybe going to become an integer in the future.
  • 我已经在images列表中分离了文件名,所以如果将来它可能成为一个整数,也可以正确地使用它。
  • I added additional infos, like "alt", "width", "height". "Alt" means alternative text, showed when image can not be displayed. But "title" is the attribute used for the tooltips on hover.
  • 我添加了额外的信息,比如“alt”,“width”,“height”。“Alt”是替代文本,当图像不能显示时显示。但是“title”是用于鼠标悬停的工具提示的属性。
  • I changed the function names to intention-revealing names. And I wanted to show you that the function/method names in PHP should be defined in "camelCase" format (see PHP recommendation PSR-1: Basic Coding Standard).
  • 我将函数名更改为意图显示的名称。我想向您展示PHP中的函数/方法名称应该以“camelCase”格式定义(请参阅PHP推荐的PSR-1:基本编码标准)。
  • I used the function sprintf() in displayImageCard(), to show you how to achieve a better readability and separation of PHP variables from the output string.
  • 我使用了displayImageCard()中的函数sprintf(),向您展示如何从输出字符串中获得更好的可读性和分离PHP变量。
  • You should "inject" the $gallery array as argument to the displayImageGallery() function. The lack of this function argument was the source of the error you received.
  • 您应该“注入”$gallery数组作为displayImageGallery()函数的参数。缺少这个函数参数是您收到错误的根源。

Good luck!

好运!

<?php

/*
 * -----------------
 * Gallery functions
 * -----------------
 */

/**
 * Display image card.
 * 
 * @param string $file File name.
 * @param string $extension File extension (jpg|png, etc).
 * @param string $path File path.
 * @param string $alt Alternative text.
 * @param string $title Title used in tooltips.
 * @param string $description Description.
 * @param integer $width Width.
 * @param integer $height Height.
 * @return string Output string.
 */
function displayImageCard($file, $extension, $path, $alt, $title, $description, $width = 300, $height = 200) {
    echo sprintf('<div class="responsive">
                            <div class="gallery">
                                <img src="%s" alt="%s" title="%s" width="%s" height="%s">
                                <div class="desc">%s</div>
                            </div>
                        </div>'
            , $path . $file . '.' . $extension
            , $alt
            , $title
            , $width
            , $height
            , $description
    );
}

/**
 * Display image gallery.
 * 
 * @param array $gallery [optional] Images list.
 * @return void
 */
function displayImageGallery(array $gallery = array()) {
    echo '<pre>' . print_r($gallery, true) . '</pre>';

    foreach ($gallery as $key => $image) {
        $file = $image['file'];
        $extension = $image['extension'];
        $path = $image['path'];
        $alt = $image['alt'];
        $title = $image['title'];
        $description = $image['description'];

        displayImageCard($file, $extension, $path, $alt, $title, $description);
    }
}

/*
 * ---------------
 * Display gallery
 * ---------------
 */

// Images list.
$gallery = array(
    array(
        'file' => 'i/Alice0',
        'extension' => 'jpg',
        'path' => 'abc/',
        'alt' => 'Front of House',
        'title' => 'Front of House',
        'description' => 'View of the house from the front sidewalk',
    ),
    array(
        'file' => 'i/Alice1',
        'extension' => 'jpg',
        'path' => 'def/',
        'alt' => 'Front door',
        'title' => 'Front door',
        'description' => 'Close-up of front door',
    )
);

// Display image gallery.
displayImageGallery($gallery);

#2


2  

Unlike in JavaScript, there is no scope bubbling in PHP. A function scope in PHP is isolated from the outside scope. Your $gallery is defined outside the function scope. Inside the function, it is undefined. That is why you get the Invalid argument supplied for foreach() message, because foreach expects an array, but it's not there. When you var_dump($gallery) in the function, you will see it is undefined.

与JavaScript不同,PHP中没有冒泡的范围。PHP中的函数作用域与外部作用域隔离。您的$gallery是在函数范围之外定义的。在函数内部,它是未定义的。这就是为什么为foreach()消息提供无效参数的原因,因为foreach期望一个数组,但它不在那里。当您在函数中使用var_dump($gallery)时,您将看到它是未定义的。

The solution is to pass $gallery to display_gallery(), e.g.

解决方案是将$gallery传递给display_gallery(),例如。

function display_gallery(array $gallery) {
   // the code as is
}
display_gallery($gallery);

An alternative would be to utilize the global keyword:

另一种选择是利用全球关键字:

function display_gallery() {
    global $gallery;       
    // the code as is
}
display_gallery();

However, while the latter looks like a convenient and simple fix, reaching from an inner scope to an outer scope is usually harder to maintain and more error prone in the long run. I am including it for the sake of completeness, but would advice to use the first approach, e.g. passing in the variable.

然而,虽然后者看起来是一种方便而简单的修复,但是从内部作用域到外部作用域通常很难维护,而且从长远来看更容易出错。出于完整性的考虑,我将它包含在内,但是建议使用第一种方法,例如传递变量。

#3


1  

This will solve it:

这将解决方法:

function display_gallery ($gallery) {     
foreach ($gallery as $img) { 
    $imgsrc = $img['imgsrc'];
    $title = $img['title'];
    $desc = $img['desc'];
    build_html($imgsrc, $title, $desc);
}
}
// Calling the function in body of page
display_gallery($gallery);

As well you could put the part where you define your array in function:

也可以将定义数组的部分放在函数中:

function returnArray() {
    // $gallery = ...
    return ($gallery);
}

And then in foreach loop:

然后在foreach循环中

foreach (returnArray() as $img) { ... }

#1


1  

Notes:

注:

  • I've separated the file name in images list, so it can also be used properly if it's maybe going to become an integer in the future.
  • 我已经在images列表中分离了文件名,所以如果将来它可能成为一个整数,也可以正确地使用它。
  • I added additional infos, like "alt", "width", "height". "Alt" means alternative text, showed when image can not be displayed. But "title" is the attribute used for the tooltips on hover.
  • 我添加了额外的信息,比如“alt”,“width”,“height”。“Alt”是替代文本,当图像不能显示时显示。但是“title”是用于鼠标悬停的工具提示的属性。
  • I changed the function names to intention-revealing names. And I wanted to show you that the function/method names in PHP should be defined in "camelCase" format (see PHP recommendation PSR-1: Basic Coding Standard).
  • 我将函数名更改为意图显示的名称。我想向您展示PHP中的函数/方法名称应该以“camelCase”格式定义(请参阅PHP推荐的PSR-1:基本编码标准)。
  • I used the function sprintf() in displayImageCard(), to show you how to achieve a better readability and separation of PHP variables from the output string.
  • 我使用了displayImageCard()中的函数sprintf(),向您展示如何从输出字符串中获得更好的可读性和分离PHP变量。
  • You should "inject" the $gallery array as argument to the displayImageGallery() function. The lack of this function argument was the source of the error you received.
  • 您应该“注入”$gallery数组作为displayImageGallery()函数的参数。缺少这个函数参数是您收到错误的根源。

Good luck!

好运!

<?php

/*
 * -----------------
 * Gallery functions
 * -----------------
 */

/**
 * Display image card.
 * 
 * @param string $file File name.
 * @param string $extension File extension (jpg|png, etc).
 * @param string $path File path.
 * @param string $alt Alternative text.
 * @param string $title Title used in tooltips.
 * @param string $description Description.
 * @param integer $width Width.
 * @param integer $height Height.
 * @return string Output string.
 */
function displayImageCard($file, $extension, $path, $alt, $title, $description, $width = 300, $height = 200) {
    echo sprintf('<div class="responsive">
                            <div class="gallery">
                                <img src="%s" alt="%s" title="%s" width="%s" height="%s">
                                <div class="desc">%s</div>
                            </div>
                        </div>'
            , $path . $file . '.' . $extension
            , $alt
            , $title
            , $width
            , $height
            , $description
    );
}

/**
 * Display image gallery.
 * 
 * @param array $gallery [optional] Images list.
 * @return void
 */
function displayImageGallery(array $gallery = array()) {
    echo '<pre>' . print_r($gallery, true) . '</pre>';

    foreach ($gallery as $key => $image) {
        $file = $image['file'];
        $extension = $image['extension'];
        $path = $image['path'];
        $alt = $image['alt'];
        $title = $image['title'];
        $description = $image['description'];

        displayImageCard($file, $extension, $path, $alt, $title, $description);
    }
}

/*
 * ---------------
 * Display gallery
 * ---------------
 */

// Images list.
$gallery = array(
    array(
        'file' => 'i/Alice0',
        'extension' => 'jpg',
        'path' => 'abc/',
        'alt' => 'Front of House',
        'title' => 'Front of House',
        'description' => 'View of the house from the front sidewalk',
    ),
    array(
        'file' => 'i/Alice1',
        'extension' => 'jpg',
        'path' => 'def/',
        'alt' => 'Front door',
        'title' => 'Front door',
        'description' => 'Close-up of front door',
    )
);

// Display image gallery.
displayImageGallery($gallery);

#2


2  

Unlike in JavaScript, there is no scope bubbling in PHP. A function scope in PHP is isolated from the outside scope. Your $gallery is defined outside the function scope. Inside the function, it is undefined. That is why you get the Invalid argument supplied for foreach() message, because foreach expects an array, but it's not there. When you var_dump($gallery) in the function, you will see it is undefined.

与JavaScript不同,PHP中没有冒泡的范围。PHP中的函数作用域与外部作用域隔离。您的$gallery是在函数范围之外定义的。在函数内部,它是未定义的。这就是为什么为foreach()消息提供无效参数的原因,因为foreach期望一个数组,但它不在那里。当您在函数中使用var_dump($gallery)时,您将看到它是未定义的。

The solution is to pass $gallery to display_gallery(), e.g.

解决方案是将$gallery传递给display_gallery(),例如。

function display_gallery(array $gallery) {
   // the code as is
}
display_gallery($gallery);

An alternative would be to utilize the global keyword:

另一种选择是利用全球关键字:

function display_gallery() {
    global $gallery;       
    // the code as is
}
display_gallery();

However, while the latter looks like a convenient and simple fix, reaching from an inner scope to an outer scope is usually harder to maintain and more error prone in the long run. I am including it for the sake of completeness, but would advice to use the first approach, e.g. passing in the variable.

然而,虽然后者看起来是一种方便而简单的修复,但是从内部作用域到外部作用域通常很难维护,而且从长远来看更容易出错。出于完整性的考虑,我将它包含在内,但是建议使用第一种方法,例如传递变量。

#3


1  

This will solve it:

这将解决方法:

function display_gallery ($gallery) {     
foreach ($gallery as $img) { 
    $imgsrc = $img['imgsrc'];
    $title = $img['title'];
    $desc = $img['desc'];
    build_html($imgsrc, $title, $desc);
}
}
// Calling the function in body of page
display_gallery($gallery);

As well you could put the part where you define your array in function:

也可以将定义数组的部分放在函数中:

function returnArray() {
    // $gallery = ...
    return ($gallery);
}

And then in foreach loop:

然后在foreach循环中

foreach (returnArray() as $img) { ... }