Most simply, call array_udiff()
to leverage a callback with a 3-way comparison (no iterated function calls, no serializing) on the rows.
This will still work if the rows have associative keys in different orders -- no sorting is necessary.
Code: (Demo)
$pageids = [
['id' => 1, 'linklabel' => 'Home', 'url' => 'home'],
['id' => 2, 'linklabel' => 'Graphic Design', 'url' => 'graphicdesign'],
['id' => 3, 'linklabel' => 'Other Design', 'url' => 'otherdesign'],
['id' => 6, 'linklabel' => 'Logo Design', 'url' => 'logodesign'],
['id' => 15, 'linklabel' => 'Content Writing', 'url' => 'contentwriting'],
];
$parentpage = [
['id' => 2, 'linklabel' => 'Graphic Design', 'url' => 'graphicdesign'],
['url' => 'otherdesign', 'id' => 3, 'linklabel' => 'Other Design'],
];
var_export(
array_udiff($pageids, $parentpage, fn($a, $b) => $a <=> $b)
);
Output:
array (
0 =>
array (
'id' => 1,
'linklabel' => 'Home',
'url' => 'home',
),
3 =>
array (
'id' => 6,
'linklabel' => 'Logo Design',
'url' => 'logodesign',
),
4 =>
array (
'id' => 15,
'linklabel' => 'Content Writing',
'url' => 'contentwriting',
),
)
Granted the asker's sample data does not indicate shuffled subarray keys, my sample input will disrupt @AbraCadaver's and @Lebnik's algorithms and cause them to give a different result than expected. My snippet gives the same result as @qdev's and @Gruber's answers, but my snippet does FAR less work.