Need help creating and modifying an associative array

I’m using PHP to help me develop an ePub that includes a series of tables that include the names of the various U.S. states. Each state name is linked to its own page, and all the links in each table target the same anchor…

…/alaska#bird
…/colorado#bird

Rather than insert the name of a state, with the html link, over and over and over, I’d like to just type in ‘.$AZ.’, which would then echo the linked word Arizona (e.g. Arizona).

So far, it’s simple. I just include a file that features the values for each of the 50 states, $AL through $WY. The problem: How do I insert a unique anchor value for each table?

Here’s one possibility…

First, I create my 50 state values…

$AZ = '<a href="'.$StatesHomeLink.'az.'.$XHTML.'#XYZ" title="Arizona">Arizona</a>';

Next, I use str_replace to replace XYZ with an anchor value. I would paste the following line of code just before the Food table, for example:

$AZ = str_replace('XYZ', 'food', $AZ);

That, too, is simple…for a single value. However, I need to modify all 50 state values for each table, something like this…

$AZ = str_replace('XYZ', 'food', $AZ);
$CA = str_replace('XYZ', 'food', $CA);

Is there some way to expedite this, so i don’t have to paste 50 lines of code with a different anchor in front of each table?

It looks like this is something I could do with an associative array. I would create a master array, then include a line of code modifying the anchor link just before each table. Then I can type in ‘.$AZ.’ and it will automatically link to a page with a specific anchor (e.g. #food).

However, I don’t know exactly how to create such an array, or how to modify the anchor links.

Thanks for any tips.

There should not be any need for replacements that may be defined before creating the anchor string.
Not sure how you are stricturing your array but for example:-

$states = array(
  ['name' => 'Arizona', 'code' => 'AZ', 'url' => 'arizona.php'],
  ['name' => 'Calafornia', 'code' => 'CA', 'url' => 'calafornia.php'],
);

$fragment = '#food';

Then you can make the anchoe string from that in a foreach loop.

<?php foreach($states as $state) : ?>
<a href="<?= $state['url'].$fragment?>" title="<?= $state['name']?>"><?= $state['name']?></a>
<?php endforeach ?>

Not sure that’s exactly what you are doing but it’s a start.
If you have a lot of data like this you may want to consider a database or CSV file.

1 Like

Ah, that is a step in the right direction. Here’s how I adapted your code:

<?php
$states = array(
['name' => 'Arizona', 'code' => 'AZ', 'url' => 'arizona.php'],
['name' => 'Texas', 'code' => 'TX', 'url' => 'texas.php'],
);

$fragment = '#food';
$fragment2 = '#drink';
?>

<?php foreach($states as $state) : ?>
<a href="<?= $state['url'].$fragment?>" title="<?= $state['name']?>"><?= $state['name']?></a>
<?php endforeach ?>

<?php foreach($states as $state) : ?>
<a href="<?= $state['url'].$fragment2?>" title="<?= $state['name']?>"><?= $state['name']?></a>
<?php endforeach ?>

Next, I need to echo $TX in a table…

<table>
  <tr>
      <td>Some Text...</td><td>'.$TX.'</td>
  </tr>
 </table>

What happens is the code above displays links for Arizona and Texas, but the value ‘.$TX.’ inside my table displays nothing. How do I modify it so that I can paste in any state code - ‘.$AZ.’, ‘.$CA.’, etc. - in any table cell, and it will display the complete linked name?

You’re right about using a database. That’s my preference, but I have some kind of problem with my laptop. My websites kind of self-destructed a long time ago, and I never could troubleshoot the problem. So I’m just waiting until I can afford a new laptop, then start from scratch. I’m using an aging Mac, and they’re so expensive.

In the meantime, I’ve just about given up on programming. I’m converting my websites to WordPress and focusing on epubs, which are a lot easier and safer to work with than websites. :wink:

Nevertheless, PHP is a handy development tool, so I’m using it as a crutch as much as I can. Thanks for the code.

The example array I did is OK if you are going to list every state at once with the foreach.
So for example you could run the foreach in the table to create a table row for each state.
If you are wanting to pull out just one state, of a select few by name (or code) you would need to make the top level array associative:-

$states = array(
  'AZ' => ['name' => 'Arizona', 'url' => 'arizona.php'],
  'CA' => ['name' => 'Calafornia', 'url' => 'calafornia.php'],
);

Then you can call and state by $states['AZ'] or for a specific “propery” $states['AZ']['name']
TBH it would help to see a sample of the end product content to give any firm advice.

Where you have “Some Text…” Would that be text related to that state? If you would that belong in the array too?

No, the text isn’t associated with the array.

Imagine an empty table cell…

<td></td>

I simply want to insert a linked state…

<td>'.$AZ.'</td>

or multiple linked states in each cell…

<td>.'.$AZ.', '.$CA.', '.$WY.'</td>

The table would then display…

<td>Arizona, California, Wyoming</td>

…except each state name would be hyperlinked.

Thanks.

So you are not listing every state, so the foreach is out of the game.

But the associative array may work, though it does not contain the whole link html, because the fragment you end with may change from time to time.

Personally I would maybe go down the OOP route with this with a state entity class, it could contain a method to create the link html from properties already assigned on construct and a fragment string passed in on demand.

public function makeLink(string $fragment = NULL){
    if(($fragment) || (!$this->link)){
        $this->link = '<a href="' . $this->url . '#' . $fragment . '" title="' . $this->name . '">' . $this->name . '</a>' ;
    }
    return $this->link ;
}

Then you may do something like:-

<td><?= $AZ->makeLink('food') ?></td>

Allowing you to change the fragment anytime you call it. Really depends on exaclty what you want the end result to be.

I’ll give that a try. Thanks for all your help.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.