简体   繁体   中英

PHP Bidimensional array and foreach loops

I follow struggling with bidimensional arrays and foreach loops. The following code shows a magazines array, each of them points to an unidimensional Articles array. Right now is storing three Articles for each magazine (just the Article's Title). I would like to know how to associate a Bidimensional array so that can I store the Author and PagesNumber besides the Title, for each article belonging a magazine. Could you point me in the right direction? Thanks in advance.

<?php

// Create a magazines array
$magazines = array();

// Put 5 magazines on it
for($x=0;$x<5;$x++)
    $magazines[] = "Magazine " . $x ;

// Associate articles array to each magazine
foreach($magazines as $magazine){
    $articles[$magazine] = array();
    for($x=0;$x<3;$x++)
        $articles[$magazine][] = $magazine . " - Article Title " . $x ;
}

// List them all
foreach($magazines as $magazine){
    echo $magazine . " has these articles: <br>";
    foreach($articles[$magazine] as $article)
        echo $article . "</br>";
}
?>

You need to store the extra information in an associative array within the magazine entry:

for ( $m = 0; $m < 5; $m++ ) {
    for ( $a = 0; $a < 3; $a++ ) {
        $magazines["Magazine $m"]["Article $a"] = array(
            'title'  => "Title $a",
            'author' => "Author $a"
        );
    }
}

You can then access each element in the array in a variety of ways:

// foreach loops through each element of the array,
// returning the key and value:
foreach ( $magazines as $magazine => $articles ) {
    print "$magazine\n";
    foreach ( $articles as $article => $info ) {
        print "  $article\n";
        // You can also access elements directly by their key:
        print "    Title: {$info['title']}\n";
        print "    Author: {$info['author']}\n";
    }
}

Result:

Magazine 0
  Article 0
    Title: Title 0
    Author: Author 0
  Article 1
    Title: Title 1
    Author: Author 1
  Article 2
    Title: Title 2
    Author: Author 2
Magazine 1
  Article 0
    Title: Title 0
    Author: Author 0
  ...

There are many ways of creating a nested array, and the choice depends on your requirements. The above method used only associative arrays, whereas the following used both associative arrays and numeric arrays:

$magazines = array();

for ( $m = 0; $m < 5; $m++ ) {
    $magazines[$m] = array( 'title' => "Magazine $m" );
    for ( $a = 0; $a < 3; $a++ ) {
        $magazines[$m]['articles'][] = array(
            'title'  => "Article $a",
            'author' => "Author $a"
        );
    }
}
// 5 articles per magazine:
$articles = array_combine($magazines, array_fill(0, 5, array(1,2,3,4,5));

You now have 5 articles per magazine all with a number as their title. Just for the demo. Hope it helps. You can access all articles via the $articles array then by providing the magazine title as key.

Naturally you can set the articles for each magazine manually as well:

$articles[$magazine] = array('My first article', 'Editorial', 'Cooking with wood fire');

Or even individually:

$articles[$magazine][] = 'Learning by doing.';

Edit: If an article has more to offer then a title:

$articles[$magazine][] = array
(
  'title' => 'Learning by doing.',
  'author' => 'Frank Stein',
  'pages' => 2,
);

I'm not sure I follow the issue here. Why not use the following?

$magazines = array(

    array( // a single magazine
        'title' => 'Issue 1',
        'articles' => array( // a list of articles
            array( // a single article
                title => 'Article 1',
                content => 'xyz'
            )
        )
    ),

);

Edit: Fixed small mistake :)

If you want to make it in a more readable manner, you can do:

function Magazines(){
    return func_get_args();
}

function Magazine($title,$articles){
    return array(
        'title' => $title,
        'articles' => $articles
    );
}

function Articles(){
    return func_get_args();
}

function Article($title,$content){
    return array(
        'title' => $title,
        'content' => $content
    );
}

// and using it...
$magazines = Magazines(Magazine('Issue 1',Articles(Article('Article 1','xyz'))));

It just replaces array() with some good naming. You can easily convert this (or something similar) to OOP. At the end, OOP is just for managing the items. The actual storage is always an array.


Traversal

Reading through the array is actually quite simple once you have the right structure:

foreach($magazines as $magazine){
    // user things like $magazine['title'] in here...
    foreach($magazine['articles'] as $article){
        // user $article['title'] here
    }
}

That's 6 lines of clean code.

Maybe you should structure it a little different:

$magazines = array();

//create magazines
for($x=0;$x<5;$x++) {
  $magazines[] = array('name' => 'Magazine ' . $x, 
                       'year' => '2011', 
                       'articles' => array());
}

//fill in some articles
foreach ($magazines as &$magazine) {
  for($x=0;$x<3;$x++) {
    $magazine['articles'][] = array('article_titel' => $magazine['name'] . " - Article Title " . $x, 
                                    'article_author' => 'author ' . $x,
                                    'article_page' => $x);
  }
}

//output
foreach($magazines as $magazine) {
  echo 'The Magazine ' . $magazine['name'] . ' from ' . $magazine['year'] . ' contains the articles : ';
  foreach($magazine['articles'] as $article) {
    echo $article['article_titel'] . ' by ' . $article['article_author'] . ' on page ' . $article['article_page'];
  }
}

A little explaination: Magazines is a normal array. Then you add associative arrays to it (magazines). Each magzines-array has an articles-field, which is a normal array, which you add associative arrays to again (articles).

So now, you iterate throug magazines, and each magazine has an array of articles which you can iterate.

That means: Magazines is an array of single magazines, one magazine is an associative array, which also contains an array of articles. An article is an associative array again.

I hope that sounds not too confusing... ;)

how about:

$magazines[$magazine] = array();
$magazines[$magazine]['article']['title'] = 'title';
$magazines[$magazine]['article']['other'] = 'other';

foreach ($magazines as $name => $magazine) {
    echo "name: " . $name;
    foreach ($magazine as $articleName => $article) {
        echo "title: " . $article['title'] . "\n";
        echo "other: " . $article['other'] . "\n";
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM