Matching Needle & Haystack values using alternate Ontology values
The whole thing needs restructuring if you are worried about performance.  First, you probably shouldn't be using an array for your haystack.  Considering that you will know with certainty what you are looking for in the haystack, it should not be an array which must be iterated in \$O(n)\$ to determine presence of an item.  An associative array with haystack values as keys or even a stdClass item with haystack values as properties would allow for \$O(1)\$ lookup to determine if a value is present.  That might look something like this (perhaps you have more meaningful full data that true to put at each key):

[
    'John' =&gt; true,
    'Alexander' =&gt; true,
    'Kim' =&gt; true,
    'Michael' =&gt; true,
    ...
]


The same can be said for the data structure around the alternative needles.  There is no reason to perform an \$O(n)$\ iteration on the alt needle array to see if an item has a lookup value.  Imagine an associative array like:

[
    'Alex' =&gt; [
        'Alexander',
        'Alexi'
    ],
    'Alexi' =&gt; [
        'Alex',
        'Alexander'
    ],
    'Alexander' =&gt; [
        'Alex',
        'Alexi,
    ],
    ...
]


This could give you \$O(1)\$ access to an array of alternate names.

So you code might be changes to look like:

$results = [];
foreach($needles as $needle) {
   $names = [$needle];
   if(array_key_exists($needle, $altNeedles)) {
       $names = array_merge($searches, $altNeedles[$needle]);
   }
   foreach($names as $name) {
       if(array_key_exists($name, $haystack)) {
           $results[$name] = true;
       }
   }
}


Given:
    m = needles array size
    n = number of alt needles per given name
    p = haystack size

This reduces overall worst case complexity from \$O(m*n^2*p)\$  to \$O(m * n)\$

In best cases (single needles, no alternate names) this solution degenerates to \$O(1)\$ complexity, whereas, yours still always requires at least \$O(p)\$.

Now, if you have the opportunity to really rethink you data structures, this can be improved even further.  For example, are what you really calling "alternate needles" really simply alternates on the haystack?  In other words, can the alternate names simply become a part of the haystack such that you can get \$O(1)\$ look up for each needle?