【问题标题】:access specific array within array php访问数组php中的特定数组
【发布时间】:2014-01-11 01:44:00
【问题描述】:

首先我是初学者:)

我正在为一家美术馆工作一个网站(46 位艺术家,每人 3 个作品列表 + 大量其他数据)

所以我决定创建一个主阵列,其中所有艺术家及其作品以阵列方式列在阵列中。我很清楚如何使用 foreach 循环访问数组的某些部分。但是,我很难弄清楚如何单独访问每个艺术家。

这里是数组的一部分,foreach 循环访问它

我想要实现的是能够使用一个非常大的数组并能够单独访问每个艺术家的数组。

       $artists = array(
            $sitnikov = array(
        $sitnikov[] = array(
        "artist" => "Vasily Sitnikov",
        "title" => '"'."Long Journey".'"',
        "year" => 1982,
        "media" => "Oil and tempera on plywood",
        "dimentions" => "H:" . 10 . " x W:" . 30.5 . "in",
        "availability" => "Sold",
        "thumb" => BASE_URL . "artists/vasily_sitnikov/images/ldpi/Thumb_Sitnikov_Vasily_Freedom.jpg",
        "lg" => BASE_URL . "artists/vasily_sitnikov/images/mdpi/Lg_Sitnikov_Vasily_Freedom.jpg"
        ),
        ),
        $slepishev = array(
        $slepishev[] = array(
        "artist" => "Anatoly Slepishev",
        "title" => '"'."Rider".'"',
        "year" => 1990,
        "media" => "Mixed media on paper",
        "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
        "availability" => $available,
        "thumb" => BASE_URL .     "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepishev_Rider.jpg",
        "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepishev_Rider.jpg",
        "literature" => "2011 Man’s Best Friends in the Works of Russian Artists Sloane Gallery of Art. ArtNet Online catalogue"
        ),
    $slepishev[] = array(
        "artist" => "Anatoly Slepishev",
        "title" => '"'."Lakeside".'"',
        "year" => 1991,
        "media" => "Watercolor on paper",
        "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
        "availability" => $available,
        "thumb" => BASE_URL . "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepyshev_Lakeside.jpg",
        "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepyshev_Lakeside.jpg",
        "literature" => "2011 Man’s Best Friends in the Works of Russian Artists Sloane Gallery of Art. ArtNet Online catalogue"
        ),
    $slepishev[] = array(
        "artist" => "Anatoly Slepishev",
        "title" => '"'."Rest".'"',
        "year" => 1991,
        "media" => "Watercolor on paper",
        "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
        "availability" => $available,
        "thumb" => BASE_URL . "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepyshev_Rest.jpg",
        "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepyshev_Rest.jpg"
        ))
);

echo "<pre>";
foreach ($artists as $artists_id => $artist_each) {
            echo $artist_id . "</br>";

        foreach ($artist_each as $artist_id => $artists_work) {
            echo 
            $artists_work["artist"] ."<br>"
            . $artists_work["title"] . "<br>"
            . $artists_work["year"] . "<br>" 
            . $artists_work["media"]. "<br>"
            . $artists_work["dimentions"] ."<br>"
            . $artists_work["availability"] ."<br>"
            .'"<img src ="' . $artists_work["thumb"] .'" /><br>'.
            '"<img src ="' . $artists_work["lg"] .'" /><br>'
            ;

        }
      }


      echo "</pre>";

【问题讨论】:

    标签: php arrays loops multidimensional-array foreach


    【解决方案1】:

    天哪……

    不要误会我的意思:您对 PHP 语言的了解如此之少,所取得的成就给我留下了深刻的印象。 但是,还有其他方法可以让您省去大量的精力。

    我可能错了,但你的代码让我觉得如果你继续努力,你可以成为一个非常优秀的程序员。这就是为什么我决定尝试让您开始做一些事情。


    您当前方法的问题是您直接在代码中定义所有数据。每次你想修改一些信息时,它都会迫使你应对不那么友好的 PHP 语法。

    正如其他答案清楚地表明的那样,您最终会得到一个非常不可读且非常难以(如果不是不可能)维护的代码。
    如果有 40 位左右的艺术家,阵列将非常庞大,查找或修改给定信息将成为一场噩梦。

    重点是将数据与代码去关联

    在我看来,诀窍是找到一个不需要大量 PHP 专业知识但仍允许您相对轻松地维护数据的解决方案。
    超级专业人士会使用数据库,但这需要大量投资来学习如何在 PHP 中处理这些笨重的野兽。
    我想我们可以在这里接受一个简单的文本文件。例如:

    [artist]: Vasily Sitnikov
    
    [picture]: Long Journey
    year: 1982
    media: Oil and tempera on plywood
    dimentions: 10 30.5
    availability: Sold
    
    [artist]: Anatoly Slepishev
    
    [picture]: Rider
    year: 1990
    media: Mixed media on paper
    dimentions: 19.5 25.5
    availability: Available
    literature: 2011 Man’s Best Friends [...]
    
    [picture]: Lakeside
    year: 1991
    media: Watercolor on paper
    dimentions: 19.5 25.5
    availability: Available
    literature: 2011 Man’s Best Friends [...]
    

    请注意,这个“自制数据库”的一些字段与您的数组内容不同:

    • thumb 和 url 项已消失,因为您可以自动计算它们
    • 尺寸已简化为仅包含定义的可变部分(即原始宽度和高度,而不是整个“W: xx H xx in.”字符串)。
      我们将生成一个“pretty_dimensions”字段来保存完整的可显示字符串。
    • 括号内的标签表示数据块的开始(基本上您需要一组艺术家,每个艺术家都包含一组图片)
    • 单个位或信息由名称表示,后跟:(年份、尺寸等)。

    现在我们需要一些代码来读取此文件并将其转换为您的原始数组的等价物。 我们还需要一些东西来将数据库的当前状态写回磁盘。

    这是一个工作示例:

    <?php
    
    // -------------------
    // Database parameters
    // -------------------
    
    // database default name
    define ('DATABASE_NAME', "database.txt");
    
    // database save directory
    define ('SAVE_DIR', "save/");
    
    // site root
    define ('BASE_URL', "http://...."); // <-- *** PUT THE PROPER URL HERE
    
    
    // ------------------------------
    // main database reading function
    // ------------------------------
    function read_database ($filename = DATABASE_NAME)
    {
        // list of properties that must be defined for each picture
        $mandatory_data = array (
            'year', 'dimentions', 'media', 'availability');
        // list of valid properties
        $allowed_data = array_merge ($mandatory_data, array (
            'literature'));
    
        // read the whole file into a string
        $file = file_get_contents ($filename);
    
        // split the file into lines
        $lines = explode ("\n", $file);
    
        // analyze each line
        $a = null; // current artist
        $p = null; // current picture
        $l = 0;    // current line number
        foreach ($lines as $line)
        {
            // keep track of line number for error reporting
            $l++;
    
            // eliminate trailing spaces and skip empty lines
            $line = trim ($line);
            if ($line == '') continue;
    
            // get the line type and value
            list ($type, $value) = explode (':', $line, 2);
            if ($value == null) panic ($line, "missing ':' delimiter");
    
            // decode the type
            $type = trim($type); // eliminate white spaces
            $value = trim($value);
            switch ($type)
            {
            case '[artist]':
                // create a new artist
                if (isset ($database[$value])) panic ($l, "artist '$value' defined more than once");
                $a = $value;
                $db[$a] = array();
                break;
            case '[picture]':
                // create a new picture for the current artist
                if ($a === null)         panic ($l, "picture defined before an artist was specified");
                if (isset ($db[$value])) panic ($l, "artist '$value' defined more than once");
                $p = $value;
                $db[$a][$p] = array();
                break;
            default:
                // all other values are simply stored as data
                // associated to the current picture of the current artist
                if ($a === null) panic ($l, "data defined before an artist was specified");
                if ($p === null) panic ($l, "data defined before a picture was specified");
                if (isset($db[$a][$p][$value])) panic ($l, "data '$type' defined more than once");
                $db[$a][$p][$type] = $value;
                break;
            }
        }
    
        // compute final data
        foreach ($db as $a => $pictures)
        {
            foreach ($pictures as $p => $picture)
            {
                // check mandatory data
                foreach ($mandatory_data as $data)
                {
                    if (!isset ($picture[$data]))
                    {
                        warning ($a,$p, "data '$data' not defined");
                        // set a dummy value to avoid errors in further processing
                        $picture[$data]="";
                    }
                }
    
                // check allowed data
                foreach ($picture as $data => $value)
                {
                    if (!in_array ($data, $allowed_data))
                    {
                        warning ($a,$p, "invalid data name '$data'");
                    }
                }
    
                // add picture name
                $picture['name'] = '"'.$p.'"';
    
                // compute pretty "dimentions" value
                @list ($w, $h, $extra) = explode (" ", $picture['dimentions']);
                if ($w == null || $h == null || $extra != null) warning ($a, $p, "invalid dimentions format");
                $picture['pretty_dimensions'] = "W: $w H: $h in.";
    
                // compute thumb and lg
                $uartist  = underscore_string ($a);
                $upicture = underscore_string ($p);
                $picture['thumb'] = BASE_URL . "artists/${uartist}/images/ldpi/Thumb_${uartist}_${upicture}.jpg";
                $picture['lg']    = BASE_URL . "artists/${uartist}/images/mdpi/Lg_${uartist}_${upicture}.jpg";
    
                // update current picture
                $db[$a][$p] = $picture;
            }
        }
    
        // done
        return $db;
    }
    
    function write_database ($db, $filename=DATABASE_NAME)
    {
        // list of auto-computed properties
        $auto_data = array (
            'name', 'thumb', 'lg', 'pretty_dimensions');
    
        // make a safety copy of the current database state
        copy_to_safety ($filename);
    
        // compute new file contents
        $output = '';
        foreach ($db as $a => $pictures)
        {
            $output .= "[artist]:$a\n\n";
            foreach ($pictures as $p => $picture)
            {
                $output .= "[picture]:$p\n\n";
                foreach ($picture as $data => $value)
                {
                    // skip auto-computed fields
                    if (in_array ($data, $auto_data)) continue;
    
                    $output .= "$data: $value\n";
                }
            }
        }
    
        // overwrite DB file with new contents
        file_put_contents ($filename, $output);
    }
    
    // copy a file to safety
    function copy_to_safety ($filename)
    {
        // nothing to do if there is no previous version
        if (!file_exists ($filename)) return;
    
        // create save directory if need be
        if (!file_exists(SAVE_DIR)) mkdir (SAVE_DIR, 0777, true);
    
        // copy the file
        $save_name = SAVE_DIR.$filename.date(" Y-M-d@H.i.s");
        file_put_contents ($save_name, file_get_contents ($filename));
    }
    
    // name computations
    function underscore_string ($s)
    {
        return str_replace (" ", "_", $s);
    }
    
    // error reporting
    function panic ($line, $message)
    {
        die ("FATAL ERROR in line <b>$line</b>: $message<br />");
    }
    
    function warning ($artist, $picture, $message)
    {
        echo ("artist '$artist' picture '$picture': $message<br />");
    }
    
    // ----
    // test
    // ----
    
    // display all sold pictures
    function display_sold_pictures ($db)
    {
        echo "<h1>sold pictures</h1>";
        echo "<table><tr><th>Artist</th><th>Picture</th><th>Year</th></tr>";
        foreach ($db as $a => $pictures)
            foreach ($pictures as $p => $picture)
            {
                if ($db[$a][$p]['availability'] != 'Sold') continue;
                echo "<tr><td>$a</td><td>$p</td><td>${picture['year']}</td></tr>";
            }
        echo "</table>";
    }
    
    // display sold pictures in the current DB
    $db = read_database ();
    display_sold_pictures ($db);
    
    // mark every picture as sold
    foreach ($db as $a => $pictures)
        foreach ($pictures as $p => $picture)
            $db[$a][$p]['availability'] = 'Sold';
    
    // save the database
    write_database ($db, "dummy.txt");
    
    // display sold pictures in the modified DB
    $db = read_database ("dummy.txt");
    display_sold_pictures ($db);
    
    ?>
    

    您可以从here获取代码和示例数据库

    我尽了最大努力使代码保持简单和(希望)可读。
    如果有什么不清楚的地方可以随时询问(kuroi dot neko at wanadoo dot fr)

    虽然这是一段代码,它仍然只是一个示例

    正确且可靠的方法是使用本地数据库(通常是 SQLite),而不是自己编写所有这些数据库处理代码。

    但是,直接处理数据库访问可能是一项艰巨的任务。希望这段代码可以作为一个中间步骤,帮助您了解如何完成工作。

    下一步是学习类和对象,这样你就可以把这段代码变成更好用的东西。我设计它是为了将数据库访问代码转换为一个类应该相对简单。

    从那里您可以尝试实现一个真正的数据库。但这不会在一天内完成:)。

    Я тоже немношко русского языка знаю, если вам удобнее, но о технических предметам лучше по-англиский говорить :)

    【讨论】:

    • 圣牛人。我知道已经有一段时间了。但回想起来,我不敢相信我什至有勇气在论坛上问这样的问题。感谢您当时加倍努力。
    • 哦,好吧,如果这个答案对你有用,我想我的时间并没有浪费......
    【解决方案2】:

    如果您的数组有点损坏,则结构。

    $artists = array(
        $sitnikov = array(
            $sitnikov[] = array(
    

    您不需要第二个“sitnikov”上的 []。这是您正在寻找的结构:

    $artists = array (
        'sitnikov' => array(
            "artist" => "Vasily Sitnikov",
            "title" => '"'."Long Journey".'"'
        ),
        'slepishev' => array(
            "artist" => "Anatoly Slepishev",
            "title" => '"'."Lakeside".'"'
        )
    );
    

    然后,你可以这样做:

    foreach ( $artists as $artist => $values) {
        echo "Artist: " . $values['artist'] . "<br>";
        echo "Title: " . $values['title'] . "<br>";
        echo "<hr>";
    }
    

    这只是一个示例,因此请根据您的需要进行调整。

    【讨论】:

      【解决方案3】:

      您的数组的语法不完善。您应该始终使用 =&gt; 运算符在数组中创建键/值对。键应该是整数、字符串(例如"sitnikov")或具有整数或字符串值的现有变量(例如$sitnikov)。您不应该以 [] 结束您的密钥:

      $artists = array(
          "sitnikov" => array(
              0 => array(
                  "artist" => "Vasily Sitnikov",
                  "title" => '"'."Long Journey".'"',
                  "year" => 1982,
                  "media" => "Oil and tempera on plywood",
                  "dimentions" => "H:" . 10 . " x W:" . 30.5 . "in",
                  "availability" => "Sold",
                  "thumb" => BASE_URL . "artists/vasily_sitnikov/images/ldpi/Thumb_Sitnikov_Vasily_Freedom.jpg",
                  "lg" => BASE_URL . "artists/vasily_sitnikov/images/mdpi/Lg_Sitnikov_Vasily_Freedom.jpg"
              ),
          ),
          "slepishev" => array(
              0 => array(
                  "artist" => "Anatoly Slepishev",
                  "title" => '"'."Rider".'"',
                  "year" => 1990,
                  "media" => "Mixed media on paper",
                  "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
                  "availability" => $available,
                  "thumb" => BASE_URL .     "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepishev_Rider.jpg",
                  "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepishev_Rider.jpg",
                  "literature" => "2011 Man’s Best Friends in the Works of Russian Artists Sloane Gallery of Art. ArtNet Online catalogue"
              ),
              1 => array(
                  "artist" => "Anatoly Slepishev",
                  "title" => '"'."Lakeside".'"',
                  "year" => 1991,
                  "media" => "Watercolor on paper",
                  "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
                  "availability" => $available,
                  "thumb" => BASE_URL . "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepyshev_Lakeside.jpg",
                  "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepyshev_Lakeside.jpg",
                  "literature" => "2011 Man’s Best Friends in the Works of Russian Artists Sloane Gallery of Art. ArtNet Online catalogue"
              ),
              2 => array(
                  "artist" => "Anatoly Slepishev",
                  "title" => '"'."Rest".'"',
                  "year" => 1991,
                  "media" => "Watercolor on paper",
                  "dimentions" => "H:" . 19.5 . " x W:" . 25.5 . "in",
                  "availability" => $available,
                  "thumb" => BASE_URL . "artists/anatoly_slepyshev/images/ldpi/Thumb_Anatoly_Slepyshev_Rest.jpg",
                  "lg" => BASE_URL . "artists/anatoly_slepyshev/images/mdpi/Lg_Anatoly_Slepyshev_Rest.jpg"
              )
          )
      );
      

      如果您在第一个 foreach 循环之后立即将行更改为 echo $artists_id . "&lt;/br&gt;";,则嵌套的 foreach 循环将正常工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多