简体   繁体   中英

access specific array within array php

First things first Im a beginner :)

Im working an a web site for an art gallery (46 artists, each 3 works list + alot of other data)

So i decide to create one main array with all the artists and their works listed in array within array fashion. I got my head around how to access parts of the array with foreach loop. However, I have a hard time figuring out how to access each artist individually.

here is a portion of the array and foreach loops to access it

What im trying to achieve is to be able to use one really big array and be able to access each artist's array individually.

       $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>";

The syntax of your array is imperfect. You should always use the => operator to create a key/value pair within an array. The key should be an integer, a string (eg "sitnikov" ), or an existing variable which has an integer or string value (eg $sitnikov ). You shouldn't end your key with [] :

$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"
        )
    )
);

Your nested foreach loops will work fine if you change the line immediately after the first foreach loop to echo $artists_id . "</br>"; echo $artists_id . "</br>"; .

The structure if your array is a little broken.

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

You don't need the [] on the second 'sitnikov'. This is the structure you are looking for:

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

Then after that, you can do this:

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

This is just an example so make it fit your needs.

My oh my...

Don't get me wrong: I am quite impressed by what you achieved with so modest a knowledge of the PHP language. However, there are other ways of doing things that could spare you a huge lot of efforts.

I might be wrong, but your code makes me think you could become a pretty good programmer if you keep trying. That's why I decided to try and get you started on a few things.


The problem with your current approach is that you define all the data directly inside the code. It forces you to cope with the not so friendly PHP syntax each time you want to modify a bit of information.

As the other answers clearly show, you will end up with a code that is pretty unreadable and very difficult (if not impossible) to maintain.
With 40 artists or so, the array will be huge, and finding or modifying a given information will become a nightmare.

The main point is to decorrelate your data from your code .

As I see it, the trick is to find a solution that does not require huge PHP expertise but still allows you to maintain your data relatively easily.
Super pros would use a database, but that would require a colossal investment to learn how to handle these cumbersome beasts in PHP.
I think we could settle for a simple text file here. For instance:

[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 [...]

Notice that a few fields of this "homebrewed database" are different from your array contents:

  • the thumb and url items are gone, since you can calculate them automatically
  • the dimensions are simplified to hold only the variable part of the definition (ie raw width and height instead of the whole "W: xx H xx in." string).
    We will generate a "pretty_dimensions" field that will hold the complete displayable string.
  • tags inside brackets designate the start of a block of data (basically you will need an array of artists, each containing an array of pictures)
  • individual bits or information are denoted by a name followed by : (year, dimentions, etc).

Now we need a bit of code to read this file and turn it into an equivalent of your original array. We need also something to write back the current state of your database to disk.

Here is a working example :

<?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);

?>

You can get the code and sample database from here

I did my best to keep the code simple and (hopefully) readable.
Feel free to ask if something is not clear (kuroi dot neko at wanadoo dot fr)

Although it is a working bit of code, it's still just an example .

The proper and robust way to do it would be to use a local database (typically SQLite) instead of writing all this DB handling code yourself.

However, tackling database access directly could be a daunting task. Hopefully, this bit of code might serve as an intermediate step to help you feel how things can be done.

The next step would be to learn about classes and objects, so that you could turn this bit of code into something more pleasant to use. I designed it so that turning the database access code into a class should be relatively straightforward.

From there you could try to implement a real database. But that will not be done in a day :).

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

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