-1

On the page there will be about several hundred elements to which individual keywords are assigned, as in a kind of index.

These keywords are used to dynamically show or hide these elements with JavaScript, depending on whether the searched keywords are found. The keywords are inserted by PHP into the data-tags of the individual elements.

For example, the keyword directory could look like this:

$keywords =
[
    'MainCategory1' =>
    [
        'Category1' =>
        [
            'Value1' => 0,
            'SubCategory1' => [
                'Value2' => 0,
                'Value3' => 0
            ]
        ],
        'Category2' =>
        [
            'Value4' => 0,
            'Value5' => 0
        ]
    ],
    'MainCategory2' =>
    [
        'Category2' =>
        [
            'Value2' => 0,
            'Value4' => 0
        ],
        'Category3' =>
        [
            'Value5' => 0,
            'Value6' => 0
        ]
    ]
];

Some categories and values may occur more than once, depending on which subtopic they are in.

For example, an element has been assigned these keywords:

MainCategory1 > Category1
MainCategory1 > Category2 > Value5
MainCategory2 > Category2 > Value2

The keywords are stored in the backend as a json string and written to the data attributes. For this element:

{"MainCategory1":{"Category1":0,"Category2":{"Value5":0}},"MainCategory2":{"Category2":{"Value2":0}}}

My idea now is to loop through all elements as soon as a keyword is selected and see if the stored JSON string matches "MainCategory1 > Category2 > Value5".

This would correspond in PHP to

isset($keywords['MainCategory1']['Category2']['Value5'])

My questions about this:

  1. How could I make the isset query dynamic in php if I don't know beforehand how many levels the keyword has? This is important for when a keyword is set, to check in the backend whether the keyword is valid at all. I could loop through each level though; is there an alternative for this?

What I'm doing so far:

$arrayString = explode(' > ', $array);
$foundCount = 0;
$currentArray = $keywords;
for($i = 1; $i <= count($arrayString); $i++) {
    $key = $arrayString[$i - 1];
    $keyExists = array_key_exists($key, $currentArray);

    if(!$keyExists)
        break;

    $currentArray = $currentArray[$key];
    $foundCount++;
}

$isKeywordValid = $foundCount == count($arrayString);
  1. I am familiar with regex, but I am having trouble finding a pattern that solves this problem. What does the pattern have to look like if I want to know if "MainCategory1 > Category2 > Value5" matches the JSON string in this particular example? (This convention is only a paraphrase for the different levels. The string can also be parsed differently)
Moldevort
  • 193
  • 1
  • 9

1 Answers1

1

Taken from How to access and manipulate multi-dimensional array by key names / path?, you can walk down the structure using a reference:

function array_isset($path, $array) {
    $path = explode(' > ', $path);
    $temp =& $array;

    foreach($path as $key) {
        if(!isset($temp[$key])) { return false; }
        $temp =& $temp[$key];
    }
    return true;
}

Or turn MainCategory1 > Category2 > Value5 into ["MainCategory1"]["Category2"]["Value5"] and evaluate it as an isset:

function array_isset($path, $array) {
    $path = '["' . str_replace(' > ', '"]["', $path) . '"]';
    eval("return isset(\$array{$path});");
}

Then just do:

if(array_isset('MainCategory1 > Category2  > Value5', $keywords)) {
    // code
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Thank you, I haven't thought of eval()! Do you have happen to have any ideas for question #2? – Moldevort Oct 06 '21 at 20:15
  • No. regex isn't really suitable for this and it looks like the regex guru removed the regex tag. – AbraCadaver Oct 06 '21 at 20:16
  • @Moldevort There shouldn't be a "question #2" -- asking multiple questions in one constitutes the "Needs More Focus" close reason. Please moving forward only ask one question at at time. – Dexygen Oct 07 '21 at 14:32