[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Part of the Joomla Framework Utilities Package 4 * 5 * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. 6 * @license GNU General Public License version 2 or later; see LICENSE 7 */ 8 9 namespace Joomla\Utilities; 10 11 use Joomla\String\StringHelper; 12 13 /** 14 * ArrayHelper is an array utility class for doing all sorts of odds and ends with arrays. 15 * 16 * @since 1.0 17 */ 18 final class ArrayHelper 19 { 20 /** 21 * Private constructor to prevent instantiation of this class 22 * 23 * @since 1.0 24 */ 25 private function __construct() 26 { 27 } 28 29 /** 30 * Function to convert array to integer values 31 * 32 * @param array $array The source array to convert 33 * @param int|array $default A default value to assign if $array is not an array 34 * 35 * @return array 36 * 37 * @since 1.0 38 */ 39 public static function toInteger($array, $default = null) 40 { 41 if (\is_array($array)) 42 { 43 return array_map('intval', $array); 44 } 45 46 if ($default === null) 47 { 48 return []; 49 } 50 51 if (\is_array($default)) 52 { 53 return static::toInteger($default, null); 54 } 55 56 return [(int) $default]; 57 } 58 59 /** 60 * Utility function to map an array to a stdClass object. 61 * 62 * @param array $array The array to map. 63 * @param string $class Name of the class to create 64 * @param boolean $recursive Convert also any array inside the main array 65 * 66 * @return object 67 * 68 * @since 1.0 69 */ 70 public static function toObject(array $array, $class = 'stdClass', $recursive = true) 71 { 72 $obj = new $class; 73 74 foreach ($array as $k => $v) 75 { 76 if ($recursive && \is_array($v)) 77 { 78 $obj->$k = static::toObject($v, $class); 79 } 80 else 81 { 82 $obj->$k = $v; 83 } 84 } 85 86 return $obj; 87 } 88 89 /** 90 * Utility function to map an array to a string. 91 * 92 * @param array $array The array to map. 93 * @param string $innerGlue The glue (optional, defaults to '=') between the key and the value. 94 * @param string $outerGlue The glue (optional, defaults to ' ') between array elements. 95 * @param boolean $keepOuterKey True if final key should be kept. 96 * 97 * @return string 98 * 99 * @since 1.0 100 */ 101 public static function toString(array $array, $innerGlue = '=', $outerGlue = ' ', $keepOuterKey = false) 102 { 103 $output = []; 104 105 foreach ($array as $key => $item) 106 { 107 if (\is_array($item)) 108 { 109 if ($keepOuterKey) 110 { 111 $output[] = $key; 112 } 113 114 // This is value is an array, go and do it again! 115 $output[] = static::toString($item, $innerGlue, $outerGlue, $keepOuterKey); 116 } 117 else 118 { 119 $output[] = $key . $innerGlue . '"' . $item . '"'; 120 } 121 } 122 123 return implode($outerGlue, $output); 124 } 125 126 /** 127 * Utility function to map an object to an array 128 * 129 * @param object $source The source object 130 * @param boolean $recurse True to recurse through multi-level objects 131 * @param string $regex An optional regular expression to match on field names 132 * 133 * @return array 134 * 135 * @since 1.0 136 */ 137 public static function fromObject($source, $recurse = true, $regex = null) 138 { 139 if (\is_object($source) || \is_array($source)) 140 { 141 return self::arrayFromObject($source, $recurse, $regex); 142 } 143 144 return []; 145 } 146 147 /** 148 * Utility function to map an object or array to an array 149 * 150 * @param mixed $item The source object or array 151 * @param boolean $recurse True to recurse through multi-level objects 152 * @param string $regex An optional regular expression to match on field names 153 * 154 * @return array 155 * 156 * @since 1.0 157 */ 158 private static function arrayFromObject($item, $recurse, $regex) 159 { 160 if (\is_object($item)) 161 { 162 $result = []; 163 164 foreach (get_object_vars($item) as $k => $v) 165 { 166 if (!$regex || preg_match($regex, $k)) 167 { 168 if ($recurse) 169 { 170 $result[$k] = self::arrayFromObject($v, $recurse, $regex); 171 } 172 else 173 { 174 $result[$k] = $v; 175 } 176 } 177 } 178 179 return $result; 180 } 181 182 if (\is_array($item)) 183 { 184 $result = []; 185 186 foreach ($item as $k => $v) 187 { 188 $result[$k] = self::arrayFromObject($v, $recurse, $regex); 189 } 190 191 return $result; 192 } 193 194 return $item; 195 } 196 197 /** 198 * Adds a column to an array of arrays or objects 199 * 200 * @param array $array The source array 201 * @param array $column The array to be used as new column 202 * @param string $colName The index of the new column or name of the new object property 203 * @param string $keyCol The index of the column or name of object property to be used for mapping with the new column 204 * 205 * @return array An array with the new column added to the source array 206 * 207 * @since 1.5.0 208 * @see https://www.php.net/manual/en/language.types.array.php 209 */ 210 public static function addColumn(array $array, array $column, $colName, $keyCol = null) 211 { 212 $result = []; 213 214 foreach ($array as $i => $item) 215 { 216 $value = null; 217 218 if (!isset($keyCol)) 219 { 220 $value = static::getValue($column, $i); 221 } 222 else 223 { 224 // Convert object to array 225 $subject = \is_object($item) ? static::fromObject($item) : $item; 226 227 if (isset($subject[$keyCol]) && is_scalar($subject[$keyCol])) 228 { 229 $value = static::getValue($column, $subject[$keyCol]); 230 } 231 } 232 233 // Add the column 234 if (\is_object($item)) 235 { 236 if (isset($colName)) 237 { 238 $item->$colName = $value; 239 } 240 } 241 else 242 { 243 if (isset($colName)) 244 { 245 $item[$colName] = $value; 246 } 247 else 248 { 249 $item[] = $value; 250 } 251 } 252 253 $result[$i] = $item; 254 } 255 256 return $result; 257 } 258 259 /** 260 * Remove a column from an array of arrays or objects 261 * 262 * @param array $array The source array 263 * @param string $colName The index of the column or name of object property to be removed 264 * 265 * @return array Column of values from the source array 266 * 267 * @since 1.5.0 268 * @see https://www.php.net/manual/en/language.types.array.php 269 */ 270 public static function dropColumn(array $array, $colName) 271 { 272 $result = []; 273 274 foreach ($array as $i => $item) 275 { 276 if (\is_object($item) && isset($item->$colName)) 277 { 278 unset($item->$colName); 279 } 280 elseif (\is_array($item) && isset($item[$colName])) 281 { 282 unset($item[$colName]); 283 } 284 285 $result[$i] = $item; 286 } 287 288 return $result; 289 } 290 291 /** 292 * Extracts a column from an array of arrays or objects 293 * 294 * @param array $array The source array 295 * @param string $valueCol The index of the column or name of object property to be used as value 296 * It may also be NULL to return complete arrays or objects (this is 297 * useful together with <var>$keyCol</var> to reindex the array). 298 * @param string $keyCol The index of the column or name of object property to be used as key 299 * 300 * @return array Column of values from the source array 301 * 302 * @since 1.0 303 * @see https://www.php.net/manual/en/language.types.array.php 304 * @see https://www.php.net/manual/en/function.array-column.php 305 */ 306 public static function getColumn(array $array, $valueCol, $keyCol = null) 307 { 308 return array_column($array, $valueCol, $keyCol); 309 } 310 311 /** 312 * Utility function to return a value from a named array or a specified default 313 * 314 * @param array|\ArrayAccess $array A named array or object that implements ArrayAccess 315 * @param string $name The key to search for (this can be an array index or a dot separated key sequence as in Registry) 316 * @param mixed $default The default value to give if no key found 317 * @param string $type Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY) 318 * 319 * @return mixed 320 * 321 * @since 1.0 322 * @throws \InvalidArgumentException 323 */ 324 public static function getValue($array, $name, $default = null, $type = '') 325 { 326 if (!\is_array($array) && !($array instanceof \ArrayAccess)) 327 { 328 throw new \InvalidArgumentException('The object must be an array or an object that implements ArrayAccess'); 329 } 330 331 $result = null; 332 333 if (isset($array[$name])) 334 { 335 $result = $array[$name]; 336 } 337 elseif (strpos($name, '.')) 338 { 339 list($name, $subset) = explode('.', $name, 2); 340 341 if (isset($array[$name]) && \is_array($array[$name])) 342 { 343 return static::getValue($array[$name], $subset, $default, $type); 344 } 345 } 346 347 // Handle the default case 348 if ($result === null) 349 { 350 $result = $default; 351 } 352 353 // Handle the type constraint 354 switch (strtoupper($type)) 355 { 356 case 'INT': 357 case 'INTEGER': 358 // Only use the first integer value 359 @preg_match('/-?[0-9]+/', $result, $matches); 360 $result = @(int) $matches[0]; 361 362 break; 363 364 case 'FLOAT': 365 case 'DOUBLE': 366 // Only use the first floating point value 367 @preg_match('/-?[0-9]+(\.[0-9]+)?/', $result, $matches); 368 $result = @(float) $matches[0]; 369 370 break; 371 372 case 'BOOL': 373 case 'BOOLEAN': 374 $result = (bool) $result; 375 376 break; 377 378 case 'ARRAY': 379 if (!\is_array($result)) 380 { 381 $result = [$result]; 382 } 383 384 break; 385 386 case 'STRING': 387 $result = (string) $result; 388 389 break; 390 391 case 'WORD': 392 $result = (string) preg_replace('#\W#', '', $result); 393 394 break; 395 396 case 'NONE': 397 default: 398 // No casting necessary 399 break; 400 } 401 402 return $result; 403 } 404 405 /** 406 * Takes an associative array of arrays and inverts the array keys to values using the array values as keys. 407 * 408 * Example: 409 * $input = array( 410 * 'New' => array('1000', '1500', '1750'), 411 * 'Used' => array('3000', '4000', '5000', '6000') 412 * ); 413 * $output = ArrayHelper::invert($input); 414 * 415 * Output would be equal to: 416 * $output = array( 417 * '1000' => 'New', 418 * '1500' => 'New', 419 * '1750' => 'New', 420 * '3000' => 'Used', 421 * '4000' => 'Used', 422 * '5000' => 'Used', 423 * '6000' => 'Used' 424 * ); 425 * 426 * @param array $array The source array. 427 * 428 * @return array 429 * 430 * @since 1.0 431 */ 432 public static function invert(array $array) 433 { 434 $return = []; 435 436 foreach ($array as $base => $values) 437 { 438 if (!\is_array($values)) 439 { 440 continue; 441 } 442 443 foreach ($values as $key) 444 { 445 // If the key isn't scalar then ignore it. 446 if (is_scalar($key)) 447 { 448 $return[$key] = $base; 449 } 450 } 451 } 452 453 return $return; 454 } 455 456 /** 457 * Method to determine if an array is an associative array. 458 * 459 * @param array $array An array to test. 460 * 461 * @return boolean 462 * 463 * @since 1.0 464 */ 465 public static function isAssociative($array) 466 { 467 if (\is_array($array)) 468 { 469 foreach (array_keys($array) as $k => $v) 470 { 471 if ($k !== $v) 472 { 473 return true; 474 } 475 } 476 } 477 478 return false; 479 } 480 481 /** 482 * Pivots an array to create a reverse lookup of an array of scalars, arrays or objects. 483 * 484 * @param array $source The source array. 485 * @param string $key Where the elements of the source array are objects or arrays, the key to pivot on. 486 * 487 * @return array An array of arrays pivoted either on the value of the keys, or an individual key of an object or array. 488 * 489 * @since 1.0 490 */ 491 public static function pivot(array $source, $key = null) 492 { 493 $result = []; 494 $counter = []; 495 496 foreach ($source as $index => $value) 497 { 498 // Determine the name of the pivot key, and its value. 499 if (\is_array($value)) 500 { 501 // If the key does not exist, ignore it. 502 if (!isset($value[$key])) 503 { 504 continue; 505 } 506 507 $resultKey = $value[$key]; 508 $resultValue = $source[$index]; 509 } 510 elseif (\is_object($value)) 511 { 512 // If the key does not exist, ignore it. 513 if (!isset($value->$key)) 514 { 515 continue; 516 } 517 518 $resultKey = $value->$key; 519 $resultValue = $source[$index]; 520 } 521 else 522 { 523 // Just a scalar value. 524 $resultKey = $value; 525 $resultValue = $index; 526 } 527 528 // The counter tracks how many times a key has been used. 529 if (empty($counter[$resultKey])) 530 { 531 // The first time around we just assign the value to the key. 532 $result[$resultKey] = $resultValue; 533 $counter[$resultKey] = 1; 534 } 535 elseif ($counter[$resultKey] == 1) 536 { 537 // If there is a second time, we convert the value into an array. 538 $result[$resultKey] = [ 539 $result[$resultKey], 540 $resultValue, 541 ]; 542 $counter[$resultKey]++; 543 } 544 else 545 { 546 // After the second time, no need to track any more. Just append to the existing array. 547 $result[$resultKey][] = $resultValue; 548 } 549 } 550 551 unset($counter); 552 553 return $result; 554 } 555 556 /** 557 * Utility function to sort an array of objects on a given field 558 * 559 * @param array $a An array of objects 560 * @param mixed $k The key (string) or an array of keys to sort on 561 * @param mixed $direction Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending] 562 * @param mixed $caseSensitive Boolean or array of booleans to let sort occur case sensitive or insensitive 563 * @param mixed $locale Boolean or array of booleans to let sort occur using the locale language or not 564 * 565 * @return array 566 * 567 * @since 1.0 568 */ 569 public static function sortObjects(array $a, $k, $direction = 1, $caseSensitive = true, $locale = false) 570 { 571 if (!\is_array($locale) || !\is_array($locale[0])) 572 { 573 $locale = [$locale]; 574 } 575 576 $sortCase = (array) $caseSensitive; 577 $sortDirection = (array) $direction; 578 $key = (array) $k; 579 $sortLocale = $locale; 580 581 usort( 582 $a, function ($a, $b) use ($sortCase, $sortDirection, $key, $sortLocale) 583 { 584 for ($i = 0, $count = \count($key); $i < $count; $i++) 585 { 586 if (isset($sortDirection[$i])) 587 { 588 $direction = $sortDirection[$i]; 589 } 590 591 if (isset($sortCase[$i])) 592 { 593 $caseSensitive = $sortCase[$i]; 594 } 595 596 if (isset($sortLocale[$i])) 597 { 598 $locale = $sortLocale[$i]; 599 } 600 601 $va = $a->{$key[$i]}; 602 $vb = $b->{$key[$i]}; 603 604 if ((\is_bool($va) || is_numeric($va)) && (\is_bool($vb) || is_numeric($vb))) 605 { 606 $cmp = $va - $vb; 607 } 608 elseif ($caseSensitive) 609 { 610 $cmp = StringHelper::strcmp($va, $vb, $locale); 611 } 612 else 613 { 614 $cmp = StringHelper::strcasecmp($va, $vb, $locale); 615 } 616 617 if ($cmp > 0) 618 { 619 return $direction; 620 } 621 622 if ($cmp < 0) 623 { 624 return -$direction; 625 } 626 } 627 628 return 0; 629 } 630 ); 631 632 return $a; 633 } 634 635 /** 636 * Multidimensional array safe unique test 637 * 638 * @param array $array The array to make unique. 639 * 640 * @return array 641 * 642 * @see https://www.php.net/manual/en/function.array-unique.php 643 * @since 1.0 644 */ 645 public static function arrayUnique(array $array) 646 { 647 $array = array_map('serialize', $array); 648 $array = array_unique($array); 649 $array = array_map('unserialize', $array); 650 651 return $array; 652 } 653 654 /** 655 * An improved array_search that allows for partial matching of strings values in associative arrays. 656 * 657 * @param string $needle The text to search for within the array. 658 * @param array $haystack Associative array to search in to find $needle. 659 * @param boolean $caseSensitive True to search case sensitive, false otherwise. 660 * 661 * @return mixed Returns the matching array $key if found, otherwise false. 662 * 663 * @since 1.0 664 */ 665 public static function arraySearch($needle, array $haystack, $caseSensitive = true) 666 { 667 foreach ($haystack as $key => $value) 668 { 669 $searchFunc = ($caseSensitive) ? 'strpos' : 'stripos'; 670 671 if ($searchFunc($value, $needle) === 0) 672 { 673 return $key; 674 } 675 } 676 677 return false; 678 } 679 680 /** 681 * Method to recursively convert data to a one dimension array. 682 * 683 * @param array|object $array The array or object to convert. 684 * @param string $separator The key separator. 685 * @param string $prefix Last level key prefix. 686 * 687 * @return array 688 * 689 * @since 1.3.0 690 */ 691 public static function flatten($array, $separator = '.', $prefix = '') 692 { 693 if ($array instanceof \Traversable) 694 { 695 $array = iterator_to_array($array); 696 } 697 elseif (\is_object($array)) 698 { 699 $array = get_object_vars($array); 700 } 701 702 $result = []; 703 704 foreach ($array as $k => $v) 705 { 706 $key = $prefix ? $prefix . $separator . $k : $k; 707 708 if (\is_object($v) || \is_array($v)) 709 { 710 $result[] = static::flatten($v, $separator, $key); 711 } 712 else 713 { 714 $result[] = [$key => $v]; 715 } 716 } 717 718 return array_merge(...$result); 719 } 720 721 /** 722 * Merge array recursively. 723 * 724 * @param array ...$args Array list to be merged. 725 * 726 * @return array Merged array. 727 * 728 * @since 2.0.0 729 * @throws \InvalidArgumentException 730 */ 731 public static function mergeRecursive(...$args): array 732 { 733 $result = []; 734 735 foreach ($args as $i => $array) 736 { 737 if (!\is_array($array)) 738 { 739 throw new \InvalidArgumentException(sprintf('Argument #%d is not an array.', $i + 2)); 740 } 741 742 foreach ($array as $key => &$value) 743 { 744 if (\is_array($value) && isset($result[$key]) && \is_array($result[$key])) 745 { 746 $result[$key] = static::mergeRecursive($result [$key], $value); 747 } 748 else 749 { 750 $result[$key] = $value; 751 } 752 } 753 } 754 755 return $result; 756 } 757 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |