Issues (50)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/helpers/ArrayHelper.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
4
namespace carono\janitor\helpers;
5
6
7
use InvalidArgumentException;
8
9
class ArrayHelper
10
{
11
12
    /**
13
     * Merges two or more arrays into one recursively.
14
     * If each array has an element with the same string key value, the latter
15
     * will overwrite the former (different from array_merge_recursive).
16
     * Recursive merging will be conducted if both arrays have an element of array
17
     * type and are having the same key.
18
     * For integer-keyed elements, the elements from the latter array will
19
     * be appended to the former array.
20
     * You can use [[UnsetArrayValue]] object to unset value from previous array or
21
     * [[ReplaceArrayValue]] to force replace former value instead of recursive merging.
22
     * @param array $a array to be merged to
23
     * @param array $b array to be merged from. You can specify additional
24
     * arrays via third argument, fourth argument etc.
25
     * @return array the merged array (the original arrays are not changed.)
26
     */
27
    public static function merge($a, $b)
0 ignored issues
show
The parameter $a is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $b is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
28
    {
29
        $args = func_get_args();
30
        $res = array_shift($args);
31
        while (!empty($args)) {
32
            foreach (array_shift($args) as $k => $v) {
33
                if (is_int($k)) {
34
                    if (array_key_exists($k, $res)) {
35
                        $res[] = $v;
36
                    } else {
37
                        $res[$k] = $v;
38
                    }
39
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
40
                    $res[$k] = static::merge($res[$k], $v);
41
                } else {
42
                    $res[$k] = $v;
43
                }
44
            }
45
        }
46
47
        return $res;
48
    }
49
50
     /**
51
     * Retrieves the value of an array element or object property with the given key or property name.
52
     * If the key does not exist in the array, the default value will be returned instead.
53
     * Not used when getting value from an object.
54
     *
55
     * The key may be specified in a dot format to retrieve the value of a sub-array or the property
56
     * of an embedded object. In particular, if the key is `x.y.z`, then the returned value would
57
     * be `$array['x']['y']['z']` or `$array->x->y->z` (if `$array` is an object). If `$array['x']`
58
     * or `$array->x` is neither an array nor an object, the default value will be returned.
59
     * Note that if the array already has an element `x.y.z`, then its value will be returned
60
     * instead of going through the sub-arrays. So it is better to be done specifying an array of key names
61
     * like `['x', 'y', 'z']`.
62
     *
63
     * Below are some usage examples,
64
     *
65
     * ```php
66
     * // working with array
67
     * $username = \yii\helpers\ArrayHelper::getValue($_POST, 'username');
68
     * // working with object
69
     * $username = \yii\helpers\ArrayHelper::getValue($user, 'username');
70
     * // working with anonymous function
71
     * $fullName = \yii\helpers\ArrayHelper::getValue($user, function ($user, $defaultValue) {
72
     *     return $user->firstName . ' ' . $user->lastName;
73
     * });
74
     * // using dot format to retrieve the property of embedded object
75
     * $street = \yii\helpers\ArrayHelper::getValue($users, 'address.street');
76
     * // using an array of keys to retrieve the value
77
     * $value = \yii\helpers\ArrayHelper::getValue($versions, ['1.0', 'date']);
78
     * ```
79
     *
80
     * @param array|object $array array or object to extract value from
81
     * @param string|\Closure|array $key key name of the array element, an array of keys or property name of the object,
82
     * or an anonymous function returning the value. The anonymous function signature should be:
83
     * `function($array, $defaultValue)`.
84
     * The possibility to pass an array of keys is available since version 2.0.4.
85
     * @param mixed $default the default value to be returned if the specified array key does not exist. Not used when
86
     * getting value from an object.
87
     * @return mixed the value of the element if found, default value otherwise
88
     */
89
    public static function getValue($array, $key, $default = null)
90
    {
91
        if ($key instanceof \Closure) {
92
            return $key($array, $default);
93
        }
94
95
        if (is_array($key)) {
96
            $lastKey = array_pop($key);
97
            foreach ($key as $keyPart) {
98
                $array = static::getValue($array, $keyPart);
99
            }
100
            $key = $lastKey;
101
        }
102
103 View Code Duplication
        if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
            return $array[$key];
105
        }
106
107
        if (($pos = strrpos($key, '.')) !== false) {
108
            $array = static::getValue($array, substr($key, 0, $pos), $default);
109
            $key = substr($key, $pos + 1);
110
        }
111
112
        if (is_object($array)) {
113
            // this is expected to fail if the property does not exist, or __get() is not implemented
114
            // it is not reliably possible to check whether a property is accessible beforehand
115
            return $array->$key;
116 View Code Duplication
        } elseif (is_array($array)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
            return (isset($array[$key]) || array_key_exists($key, $array)) ? $array[$key] : $default;
118
        }
119
120
        return $default;
121
    }
122
123
    /**
124
     * Writes a value into an associative array at the key path specified.
125
     * If there is no such key path yet, it will be created recursively.
126
     * If the key exists, it will be overwritten.
127
     *
128
     * ```php
129
     *  $array = [
130
     *      'key' => [
131
     *          'in' => [
132
     *              'val1',
133
     *              'key' => 'val'
134
     *          ]
135
     *      ]
136
     *  ];
137
     * ```
138
     *
139
     * The result of `ArrayHelper::setValue($array, 'key.in.0', ['arr' => 'val']);` will be the following:
140
     *
141
     * ```php
142
     *  [
143
     *      'key' => [
144
     *          'in' => [
145
     *              ['arr' => 'val'],
146
     *              'key' => 'val'
147
     *          ]
148
     *      ]
149
     *  ]
150
     *
151
     * ```
152
     *
153
     * The result of
154
     * `ArrayHelper::setValue($array, 'key.in', ['arr' => 'val']);` or
155
     * `ArrayHelper::setValue($array, ['key', 'in'], ['arr' => 'val']);`
156
     * will be the following:
157
     *
158
     * ```php
159
     *  [
160
     *      'key' => [
161
     *          'in' => [
162
     *              'arr' => 'val'
163
     *          ]
164
     *      ]
165
     *  ]
166
     * ```
167
     *
168
     * @param array $array the array to write the value to
169
     * @param string|array|null $path the path of where do you want to write a value to `$array`
170
     * the path can be described by a string when each key should be separated by a dot
171
     * you can also describe the path as an array of keys
172
     * if the path is null then `$array` will be assigned the `$value`
173
     * @param mixed $value the value to be written
174
     * @since 2.0.13
175
     */
176
    public static function setValue(&$array, $path, $value)
177
    {
178
        if ($path === null) {
179
            $array = $value;
180
            return;
181
        }
182
183
        $keys = is_array($path) ? $path : explode('.', $path);
184
185
        while (count($keys) > 1) {
186
            $key = array_shift($keys);
187
            if (!isset($array[$key])) {
188
                $array[$key] = [];
189
            }
190
            if (!is_array($array[$key])) {
191
                $array[$key] = [$array[$key]];
192
            }
193
            $array = &$array[$key];
194
        }
195
196
        $array[array_shift($keys)] = $value;
197
    }
198
199
    /**
200
     * Removes an item from an array and returns the value. If the key does not exist in the array, the default value
201
     * will be returned instead.
202
     *
203
     * Usage examples,
204
     *
205
     * ```php
206
     * // $array = ['type' => 'A', 'options' => [1, 2]];
207
     * // working with array
208
     * $type = \yii\helpers\ArrayHelper::remove($array, 'type');
209
     * // $array content
210
     * // $array = ['options' => [1, 2]];
211
     * ```
212
     *
213
     * @param array $array the array to extract value from
214
     * @param string $key key name of the array element
215
     * @param mixed $default the default value to be returned if the specified key does not exist
216
     * @return mixed|null the value of the element if found, default value otherwise
217
     */
218
    public static function remove(&$array, $key, $default = null)
219
    {
220
        if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) {
221
            $value = $array[$key];
222
            unset($array[$key]);
223
224
            return $value;
225
        }
226
227
        return $default;
228
    }
229
230
    /**
231
     * Removes items with matching values from the array and returns the removed items.
232
     *
233
     * Example,
234
     *
235
     * ```php
236
     * $array = ['Bob' => 'Dylan', 'Michael' => 'Jackson', 'Mick' => 'Jagger', 'Janet' => 'Jackson'];
237
     * $removed = \yii\helpers\ArrayHelper::removeValue($array, 'Jackson');
238
     * // result:
239
     * // $array = ['Bob' => 'Dylan', 'Mick' => 'Jagger'];
240
     * // $removed = ['Michael' => 'Jackson', 'Janet' => 'Jackson'];
241
     * ```
242
     *
243
     * @param array $array the array where to look the value from
244
     * @param string $value the value to remove from the array
245
     * @return array the items that were removed from the array
246
     * @since 2.0.11
247
     */
248
    public static function removeValue(&$array, $value)
249
    {
250
        $result = [];
251
        if (is_array($array)) {
252
            foreach ($array as $key => $val) {
253
                if ($val === $value) {
254
                    $result[$key] = $val;
255
                    unset($array[$key]);
256
                }
257
            }
258
        }
259
260
        return $result;
261
    }
262
263
    /**
264
     * Returns the values of a specified column in an array.
265
     * The input array should be multidimensional or an array of objects.
266
     *
267
     * For example,
268
     *
269
     * ```php
270
     * $array = [
271
     *     ['id' => '123', 'data' => 'abc'],
272
     *     ['id' => '345', 'data' => 'def'],
273
     * ];
274
     * $result = ArrayHelper::getColumn($array, 'id');
275
     * // the result is: ['123', '345']
276
     *
277
     * // using anonymous function
278
     * $result = ArrayHelper::getColumn($array, function ($element) {
279
     *     return $element['id'];
280
     * });
281
     * ```
282
     *
283
     * @param array $array
284
     * @param int|string|\Closure $name
285
     * @param bool $keepKeys whether to maintain the array keys. If false, the resulting array
286
     * will be re-indexed with integers.
287
     * @return array the list of column values
288
     */
289
    public static function getColumn($array, $name, $keepKeys = true)
290
    {
291
        $result = [];
292
        if ($keepKeys) {
293
            foreach ($array as $k => $element) {
294
                $result[$k] = static::getValue($element, $name);
295
            }
296
        } else {
297
            foreach ($array as $element) {
298
                $result[] = static::getValue($element, $name);
299
            }
300
        }
301
302
        return $result;
303
    }
304
305
    /**
306
     * Builds a map (key-value pairs) from a multidimensional array or an array of objects.
307
     * The `$from` and `$to` parameters specify the key names or property names to set up the map.
308
     * Optionally, one can further group the map according to a grouping field `$group`.
309
     *
310
     * For example,
311
     *
312
     * ```php
313
     * $array = [
314
     *     ['id' => '123', 'name' => 'aaa', 'class' => 'x'],
315
     *     ['id' => '124', 'name' => 'bbb', 'class' => 'x'],
316
     *     ['id' => '345', 'name' => 'ccc', 'class' => 'y'],
317
     * ];
318
     *
319
     * $result = ArrayHelper::map($array, 'id', 'name');
320
     * // the result is:
321
     * // [
322
     * //     '123' => 'aaa',
323
     * //     '124' => 'bbb',
324
     * //     '345' => 'ccc',
325
     * // ]
326
     *
327
     * $result = ArrayHelper::map($array, 'id', 'name', 'class');
328
     * // the result is:
329
     * // [
330
     * //     'x' => [
331
     * //         '123' => 'aaa',
332
     * //         '124' => 'bbb',
333
     * //     ],
334
     * //     'y' => [
335
     * //         '345' => 'ccc',
336
     * //     ],
337
     * // ]
338
     * ```
339
     *
340
     * @param array $array
341
     * @param string|\Closure $from
342
     * @param string|\Closure $to
343
     * @param string|\Closure $group
344
     * @return array
345
     */
346
    public static function map($array, $from, $to, $group = null)
347
    {
348
        $result = [];
349
        foreach ($array as $element) {
350
            $key = static::getValue($element, $from);
351
            $value = static::getValue($element, $to);
352
            if ($group !== null) {
353
                $result[static::getValue($element, $group)][$key] = $value;
354
            } else {
355
                $result[$key] = $value;
356
            }
357
        }
358
359
        return $result;
360
    }
361
362
    /**
363
     * Checks if the given array contains the specified key.
364
     * This method enhances the `array_key_exists()` function by supporting case-insensitive
365
     * key comparison.
366
     * @param string $key the key to check
367
     * @param array $array the array with keys to check
368
     * @param bool $caseSensitive whether the key comparison should be case-sensitive
369
     * @return bool whether the array contains the specified key
370
     */
371
    public static function keyExists($key, $array, $caseSensitive = true)
372
    {
373
        if ($caseSensitive) {
374
            // Function `isset` checks key faster but skips `null`, `array_key_exists` handles this case
375
            // https://secure.php.net/manual/en/function.array-key-exists.php#107786
376
            return isset($array[$key]) || array_key_exists($key, $array);
377
        }
378
379
        foreach (array_keys($array) as $k) {
380
            if (strcasecmp($key, $k) === 0) {
381
                return true;
382
            }
383
        }
384
385
        return false;
386
    }
387
388
    /**
389
     * Decodes HTML entities into the corresponding characters in an array of strings.
390
     * Only array values will be decoded by default.
391
     * If a value is an array, this method will also decode it recursively.
392
     * Only string values will be decoded.
393
     * @param array $data data to be decoded
394
     * @param bool $valuesOnly whether to decode array values only. If false,
395
     * both the array keys and array values will be decoded.
396
     * @return array the decoded data
397
     * @see https://secure.php.net/manual/en/function.htmlspecialchars-decode.php
398
     */
399
    public static function htmlDecode($data, $valuesOnly = true)
400
    {
401
        $d = [];
402
        foreach ($data as $key => $value) {
403
            if (!$valuesOnly && is_string($key)) {
404
                $key = htmlspecialchars_decode($key, ENT_QUOTES);
405
            }
406
            if (is_string($value)) {
407
                $d[$key] = htmlspecialchars_decode($value, ENT_QUOTES);
408
            } elseif (is_array($value)) {
409
                $d[$key] = static::htmlDecode($value);
410
            } else {
411
                $d[$key] = $value;
412
            }
413
        }
414
415
        return $d;
416
    }
417
418
    /**
419
     * Returns a value indicating whether the given array is an associative array.
420
     *
421
     * An array is associative if all its keys are strings. If `$allStrings` is false,
422
     * then an array will be treated as associative if at least one of its keys is a string.
423
     *
424
     * Note that an empty array will NOT be considered associative.
425
     *
426
     * @param array $array the array being checked
427
     * @param bool $allStrings whether the array keys must be all strings in order for
428
     * the array to be treated as associative.
429
     * @return bool whether the array is associative
430
     */
431
    public static function isAssociative($array, $allStrings = true)
432
    {
433
        if (!is_array($array) || empty($array)) {
434
            return false;
435
        }
436
437
        if ($allStrings) {
438
            foreach ($array as $key => $value) {
439
                if (!is_string($key)) {
440
                    return false;
441
                }
442
            }
443
444
            return true;
445
        }
446
447
        foreach ($array as $key => $value) {
448
            if (is_string($key)) {
449
                return true;
450
            }
451
        }
452
453
        return false;
454
    }
455
456
    /**
457
     * Returns a value indicating whether the given array is an indexed array.
458
     *
459
     * An array is indexed if all its keys are integers. If `$consecutive` is true,
460
     * then the array keys must be a consecutive sequence starting from 0.
461
     *
462
     * Note that an empty array will be considered indexed.
463
     *
464
     * @param array $array the array being checked
465
     * @param bool $consecutive whether the array keys must be a consecutive sequence
466
     * in order for the array to be treated as indexed.
467
     * @return bool whether the array is indexed
468
     */
469
    public static function isIndexed($array, $consecutive = false)
470
    {
471
        if (!is_array($array)) {
472
            return false;
473
        }
474
475
        if (empty($array)) {
476
            return true;
477
        }
478
479
        if ($consecutive) {
480
            return array_keys($array) === range(0, count($array) - 1);
481
        }
482
483
        foreach ($array as $key => $value) {
484
            if (!is_int($key)) {
485
                return false;
486
            }
487
        }
488
489
        return true;
490
    }
491
492
    /**
493
     * Check whether an array or [[\Traversable]] contains an element.
494
     *
495
     * This method does the same as the PHP function [in_array()](https://secure.php.net/manual/en/function.in-array.php)
496
     * but additionally works for objects that implement the [[\Traversable]] interface.
497
     * @param mixed $needle The value to look for.
498
     * @param array|\Traversable $haystack The set of values to search.
499
     * @param bool $strict Whether to enable strict (`===`) comparison.
500
     * @return bool `true` if `$needle` was found in `$haystack`, `false` otherwise.
501
     * @throws InvalidArgumentException if `$haystack` is neither traversable nor an array.
502
     * @see https://secure.php.net/manual/en/function.in-array.php
503
     * @since 2.0.7
504
     */
505
    public static function isIn($needle, $haystack, $strict = false)
506
    {
507
        if ($haystack instanceof \Traversable) {
508
            foreach ($haystack as $value) {
509
                if ($needle == $value && (!$strict || $needle === $value)) {
510
                    return true;
511
                }
512
            }
513
        } elseif (is_array($haystack)) {
514
            return in_array($needle, $haystack, $strict);
515
        } else {
516
            throw new InvalidArgumentException('Argument $haystack must be an array or implement Traversable');
517
        }
518
519
        return false;
520
    }
521
522
    /**
523
     * Checks whether a variable is an array or [[\Traversable]].
524
     *
525
     * This method does the same as the PHP function [is_array()](https://secure.php.net/manual/en/function.is-array.php)
526
     * but additionally works on objects that implement the [[\Traversable]] interface.
527
     * @param mixed $var The variable being evaluated.
528
     * @return bool whether $var is array-like
529
     * @see https://secure.php.net/manual/en/function.is-array.php
530
     * @since 2.0.8
531
     */
532
    public static function isTraversable($var)
533
    {
534
        return is_array($var) || $var instanceof \Traversable;
535
    }
536
537
    /**
538
     * Checks whether an array or [[\Traversable]] is a subset of another array or [[\Traversable]].
539
     *
540
     * This method will return `true`, if all elements of `$needles` are contained in
541
     * `$haystack`. If at least one element is missing, `false` will be returned.
542
     * @param array|\Traversable $needles The values that must **all** be in `$haystack`.
543
     * @param array|\Traversable $haystack The set of value to search.
544
     * @param bool $strict Whether to enable strict (`===`) comparison.
545
     * @throws InvalidArgumentException if `$haystack` or `$needles` is neither traversable nor an array.
546
     * @return bool `true` if `$needles` is a subset of `$haystack`, `false` otherwise.
547
     * @since 2.0.7
548
     */
549
    public static function isSubset($needles, $haystack, $strict = false)
550
    {
551
        if (is_array($needles) || $needles instanceof \Traversable) {
552
            foreach ($needles as $needle) {
553
                if (!static::isIn($needle, $haystack, $strict)) {
554
                    return false;
555
                }
556
            }
557
558
            return true;
559
        }
560
561
        throw new InvalidArgumentException('Argument $needles must be an array or implement Traversable');
562
    }
563
564
    /**
565
     * Filters array according to rules specified.
566
     *
567
     * For example:
568
     *
569
     * ```php
570
     * $array = [
571
     *     'A' => [1, 2],
572
     *     'B' => [
573
     *         'C' => 1,
574
     *         'D' => 2,
575
     *     ],
576
     *     'E' => 1,
577
     * ];
578
     *
579
     * $result = \yii\helpers\ArrayHelper::filter($array, ['A']);
580
     * // $result will be:
581
     * // [
582
     * //     'A' => [1, 2],
583
     * // ]
584
     *
585
     * $result = \yii\helpers\ArrayHelper::filter($array, ['A', 'B.C']);
586
     * // $result will be:
587
     * // [
588
     * //     'A' => [1, 2],
589
     * //     'B' => ['C' => 1],
590
     * // ]
591
     *
592
     * $result = \yii\helpers\ArrayHelper::filter($array, ['B', '!B.C']);
593
     * // $result will be:
594
     * // [
595
     * //     'B' => ['D' => 2],
596
     * // ]
597
     * ```
598
     *
599
     * @param array $array Source array
600
     * @param array $filters Rules that define array keys which should be left or removed from results.
601
     * Each rule is:
602
     * - `var` - `$array['var']` will be left in result.
603
     * - `var.key` = only `$array['var']['key'] will be left in result.
604
     * - `!var.key` = `$array['var']['key'] will be removed from result.
605
     * @return array Filtered array
606
     * @since 2.0.9
607
     */
608
    public static function filter($array, $filters)
609
    {
610
        $result = [];
611
        $forbiddenVars = [];
612
613
        foreach ($filters as $var) {
614
            $keys = explode('.', $var);
615
            $globalKey = $keys[0];
616
            $localKey = isset($keys[1]) ? $keys[1] : null;
617
618
            if ($globalKey[0] === '!') {
619
                $forbiddenVars[] = [
620
                    substr($globalKey, 1),
621
                    $localKey,
622
                ];
623
                continue;
624
            }
625
626
            if (!array_key_exists($globalKey, $array)) {
627
                continue;
628
            }
629
            if ($localKey === null) {
630
                $result[$globalKey] = $array[$globalKey];
631
                continue;
632
            }
633
            if (!isset($array[$globalKey][$localKey])) {
634
                continue;
635
            }
636
            if (!array_key_exists($globalKey, $result)) {
637
                $result[$globalKey] = [];
638
            }
639
            $result[$globalKey][$localKey] = $array[$globalKey][$localKey];
640
        }
641
642
        foreach ($forbiddenVars as $var) {
643
            list($globalKey, $localKey) = $var;
644
            if (array_key_exists($globalKey, $result)) {
645
                unset($result[$globalKey][$localKey]);
646
            }
647
        }
648
649
        return $result;
650
    }
651
}