Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Auth often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Auth, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | class Auth |
||
| 16 | { |
||
| 17 | /** |
||
| 18 | * Constructor |
||
| 19 | */ |
||
| 20 | public function __construct() |
||
| 23 | |||
| 24 | /** |
||
| 25 | * retrieves all the courses that the user has already subscribed to |
||
| 26 | * @param int $user_id |
||
| 27 | * @return array an array containing all the information of the courses of the given user |
||
| 28 | */ |
||
| 29 | public function get_courses_of_user($user_id) |
||
| 30 | { |
||
| 31 | $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); |
||
| 32 | $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||
| 33 | $TABLE_COURSE_FIELD = Database::get_main_table(TABLE_EXTRA_FIELD); |
||
| 34 | $TABLE_COURSE_FIELD_VALUE = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||
| 35 | |||
| 36 | $extraFieldType = ExtraField::COURSE_FIELD_TYPE; |
||
| 37 | // get course list auto-register |
||
| 38 | $sql = "SELECT item_id FROM $TABLE_COURSE_FIELD_VALUE tcfv |
||
| 39 | INNER JOIN $TABLE_COURSE_FIELD tcf |
||
| 40 | ON tcfv.field_id = tcf.id |
||
| 41 | WHERE |
||
| 42 | tcf.extra_field_type = $extraFieldType AND |
||
| 43 | tcf.variable = 'special_course' AND |
||
| 44 | tcfv.value = 1 |
||
| 45 | "; |
||
| 46 | |||
| 47 | $result = Database::query($sql); |
||
| 48 | $special_course_list = array(); |
||
| 49 | View Code Duplication | if (Database::num_rows($result) > 0) { |
|
| 50 | while ($result_row = Database::fetch_array($result)) { |
||
| 51 | $special_course_list[] = '"' . $result_row['item_id'] . '"'; |
||
| 52 | } |
||
| 53 | } |
||
| 54 | $without_special_courses = ''; |
||
| 55 | if (!empty($special_course_list)) { |
||
| 56 | $without_special_courses = ' AND course.id NOT IN (' . implode(',', $special_course_list) . ')'; |
||
| 57 | } |
||
| 58 | |||
| 59 | // Secondly we select the courses that are in a category (user_course_cat<>0) and sort these according to the sort of the category |
||
| 60 | $user_id = intval($user_id); |
||
| 61 | $sql = "SELECT |
||
| 62 | course.code k, |
||
| 63 | course.visual_code vc, |
||
| 64 | course.subscribe subscr, |
||
| 65 | course.unsubscribe unsubscr, |
||
| 66 | course.title i, |
||
| 67 | course.tutor_name t, |
||
| 68 | course.category_code cat, |
||
| 69 | course.directory dir, |
||
| 70 | course_rel_user.status status, |
||
| 71 | course_rel_user.sort sort, |
||
| 72 | course_rel_user.user_course_cat user_course_cat |
||
| 73 | FROM $TABLECOURS course, $TABLECOURSUSER course_rel_user |
||
| 74 | WHERE |
||
| 75 | course.id = course_rel_user.c_id AND |
||
| 76 | course_rel_user.relation_type<>" . COURSE_RELATION_TYPE_RRHH . " AND |
||
| 77 | course_rel_user.user_id = '" . $user_id . "' $without_special_courses |
||
| 78 | ORDER BY course_rel_user.sort ASC"; |
||
| 79 | $result = Database::query($sql); |
||
| 80 | $courses = array(); |
||
| 81 | View Code Duplication | while ($row = Database::fetch_array($result)) { |
|
| 82 | //we only need the database name of the course |
||
| 83 | $courses[] = array( |
||
| 84 | 'code' => $row['k'], |
||
| 85 | 'visual_code' => $row['vc'], |
||
| 86 | 'title' => $row['i'], |
||
| 87 | 'directory' => $row['dir'], |
||
| 88 | 'status' => $row['status'], |
||
| 89 | 'tutor' => $row['t'], |
||
| 90 | 'subscribe' => $row['subscr'], |
||
| 91 | 'category' => $row['cat'], |
||
| 92 | 'unsubscribe' => $row['unsubscr'], |
||
| 93 | 'sort' => $row['sort'], |
||
| 94 | 'user_course_category' => $row['user_course_cat'] |
||
| 95 | ); |
||
| 96 | } |
||
| 97 | |||
| 98 | return $courses; |
||
| 99 | } |
||
| 100 | |||
| 101 | /** |
||
| 102 | * retrieves the user defined course categories |
||
| 103 | * @return array containing all the IDs of the user defined courses categories, sorted by the "sort" field |
||
| 104 | */ |
||
| 105 | public function get_user_course_categories() |
||
| 120 | |||
| 121 | /** |
||
| 122 | * This function get all the courses in the particular user category; |
||
| 123 | * @return string The name of the user defined course category |
||
| 124 | */ |
||
| 125 | public function get_courses_in_category() |
||
| 126 | { |
||
| 127 | $user_id = api_get_user_id(); |
||
| 128 | |||
| 129 | // table definitions |
||
| 130 | $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); |
||
| 131 | $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
||
| 132 | $TABLE_COURSE_FIELD = Database::get_main_table(TABLE_EXTRA_FIELD); |
||
| 133 | $TABLE_COURSE_FIELD_VALUE = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||
| 134 | |||
| 135 | $extraFieldType = ExtraField::COURSE_FIELD_TYPE; |
||
| 136 | |||
| 137 | // get course list auto-register |
||
| 138 | $sql = "SELECT item_id |
||
| 139 | FROM $TABLE_COURSE_FIELD_VALUE tcfv |
||
| 140 | INNER JOIN $TABLE_COURSE_FIELD tcf |
||
| 141 | ON tcfv.field_id = tcf.id |
||
| 142 | WHERE |
||
| 143 | tcf.extra_field_type = $extraFieldType AND |
||
| 144 | tcf.variable = 'special_course' AND |
||
| 145 | tcfv.value = 1 "; |
||
| 146 | |||
| 147 | $result = Database::query($sql); |
||
| 148 | $special_course_list = array(); |
||
| 149 | View Code Duplication | if (Database::num_rows($result) > 0) { |
|
| 150 | while ($result_row = Database::fetch_array($result)) { |
||
| 151 | $special_course_list[] = '"' . $result_row['item_id'] . '"'; |
||
| 152 | } |
||
| 153 | } |
||
| 154 | |||
| 155 | $without_special_courses = ''; |
||
| 156 | if (!empty($special_course_list)) { |
||
| 157 | $without_special_courses = ' AND course.id NOT IN (' . implode(',', $special_course_list) . ')'; |
||
| 158 | } |
||
| 159 | |||
| 160 | $sql = "SELECT |
||
| 161 | course.code, course.visual_code, course.subscribe subscr, course.unsubscribe unsubscr, |
||
| 162 | course.title title, course.tutor_name tutor, course.directory, course_rel_user.status status, |
||
| 163 | course_rel_user.sort sort, course_rel_user.user_course_cat user_course_cat |
||
| 164 | FROM $TABLECOURS course, |
||
| 165 | $TABLECOURSUSER course_rel_user |
||
| 166 | WHERE |
||
| 167 | course.id = course_rel_user.c_id AND |
||
| 168 | course_rel_user.user_id = '" . $user_id . "' AND |
||
| 169 | course_rel_user.relation_type <> " . COURSE_RELATION_TYPE_RRHH . " |
||
| 170 | $without_special_courses |
||
| 171 | ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC"; |
||
| 172 | $result = Database::query($sql); |
||
| 173 | $data = array(); |
||
| 174 | while ($course = Database::fetch_array($result)) { |
||
| 175 | $data[$course['user_course_cat']][] = $course; |
||
| 176 | } |
||
| 177 | |||
| 178 | return $data; |
||
| 179 | } |
||
| 180 | |||
| 181 | /** |
||
| 182 | * stores the changes in a course category |
||
| 183 | * (moving a course to a different course category) |
||
| 184 | * @param int $courseId |
||
| 185 | * @param int Category id |
||
| 186 | * @return bool True if it success |
||
| 187 | */ |
||
| 188 | public function updateCourseCategory($courseId, $newcategory) |
||
| 212 | |||
| 213 | /** |
||
| 214 | * moves the course one place up or down |
||
| 215 | * @param string Direction (up/down) |
||
| 216 | * @param string Course code |
||
| 217 | * @param int Category id |
||
| 218 | * @return bool True if it success |
||
| 219 | */ |
||
| 220 | public function move_course($direction, $course2move, $category) |
||
| 283 | |||
| 284 | /** |
||
| 285 | * Moves the course one place up or down |
||
| 286 | * @param string Direction up/down |
||
| 287 | * @param string Category id |
||
| 288 | * @return bool True If it success |
||
| 289 | */ |
||
| 290 | public function move_category($direction, $category2move) |
||
| 328 | |||
| 329 | /** |
||
| 330 | * Retrieves the user defined course categories and all the info that goes with it |
||
| 331 | * @return array containing all the info of the user defined courses categories with the id as key of the array |
||
| 332 | */ |
||
| 333 | View Code Duplication | public function get_user_course_categories_info() |
|
| 334 | { |
||
| 335 | $current_user_id = api_get_user_id(); |
||
| 336 | $table_category = Database::get_main_table(TABLE_USER_COURSE_CATEGORY); |
||
| 337 | $sql = "SELECT * FROM " . $table_category . " |
||
| 338 | WHERE user_id='" . $current_user_id . "' |
||
| 339 | ORDER BY sort ASC"; |
||
| 340 | $result = Database::query($sql); |
||
| 341 | while ($row = Database::fetch_array($result)) { |
||
| 342 | $output[$row['id']] = $row; |
||
| 343 | } |
||
| 344 | return $output; |
||
| 345 | } |
||
| 346 | |||
| 347 | /** |
||
| 348 | * Updates the user course category in the chamilo_user database |
||
| 349 | * @param string Category title |
||
| 350 | * @param int Category id |
||
| 351 | * @return bool True if it success |
||
| 352 | */ |
||
| 353 | View Code Duplication | public function store_edit_course_category($title, $category_id) |
|
| 369 | |||
| 370 | /** |
||
| 371 | * deletes a course category and moves all the courses that were in this category to main category |
||
| 372 | * @param int Category id |
||
| 373 | * @return bool True if it success |
||
| 374 | */ |
||
| 375 | public function delete_course_category($category_id) |
||
| 400 | |||
| 401 | /** |
||
| 402 | * Search the courses database for a course that matches the search term. |
||
| 403 | * The search is done on the code, title and tutor field of the course table. |
||
| 404 | * @param string $search_term The string that the user submitted, what we are looking for |
||
| 405 | * @param array $limit |
||
| 406 | * @param boolean $justVisible search only on visible courses in the catalogue |
||
| 407 | * @return array An array containing a list of all the courses matching the the search term. |
||
| 408 | */ |
||
| 409 | public function search_courses($search_term, $limit, $justVisible = false) |
||
| 410 | { |
||
| 411 | $courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
||
| 412 | $extraFieldTable = Database :: get_main_table(TABLE_EXTRA_FIELD); |
||
| 413 | $extraFieldValuesTable = Database :: get_main_table(TABLE_EXTRA_FIELD_VALUES); |
||
| 414 | |||
| 415 | $limitFilter = CourseCategory::getLimitFilterFromArray($limit); |
||
| 416 | |||
| 417 | // get course list auto-register |
||
| 418 | $sql = "SELECT item_id |
||
| 419 | FROM $extraFieldValuesTable tcfv |
||
| 420 | INNER JOIN $extraFieldTable tcf ON tcfv.field_id = tcf.id |
||
| 421 | WHERE |
||
| 422 | tcf.variable = 'special_course' AND |
||
| 423 | tcfv.value = 1 "; |
||
| 424 | |||
| 425 | $special_course_result = Database::query($sql); |
||
| 426 | View Code Duplication | if (Database::num_rows($special_course_result) > 0) { |
|
| 427 | $special_course_list = array(); |
||
| 428 | while ($result_row = Database::fetch_array($special_course_result)) { |
||
| 429 | $special_course_list[] = '"' . $result_row['item_id'] . '"'; |
||
| 430 | } |
||
| 431 | } |
||
| 432 | $without_special_courses = ''; |
||
| 433 | if (!empty($special_course_list)) { |
||
| 434 | $without_special_courses = ' AND course.code NOT IN (' . implode(',', $special_course_list) . ')'; |
||
| 435 | } |
||
| 436 | |||
| 437 | $visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('course') : ''; |
||
| 438 | |||
| 439 | $search_term_safe = Database::escape_string($search_term); |
||
| 440 | $sql_find = "SELECT * FROM $courseTable |
||
| 441 | WHERE ( |
||
| 442 | code LIKE '%" . $search_term_safe . "%' OR |
||
| 443 | title LIKE '%" . $search_term_safe . "%' OR |
||
| 444 | tutor_name LIKE '%" . $search_term_safe . "%' |
||
| 445 | ) |
||
| 446 | $without_special_courses |
||
| 447 | $visibilityCondition |
||
| 448 | ORDER BY title, visual_code ASC |
||
| 449 | $limitFilter |
||
| 450 | "; |
||
| 451 | |||
| 452 | if (api_is_multiple_url_enabled()) { |
||
| 453 | $url_access_id = api_get_current_access_url_id(); |
||
| 454 | if ($url_access_id != -1) { |
||
| 455 | $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
||
| 456 | $sql_find = "SELECT * |
||
| 457 | FROM $courseTable as course |
||
| 458 | INNER JOIN $tbl_url_rel_course as url_rel_course |
||
| 459 | ON (url_rel_course.c_id = course.id) |
||
| 460 | WHERE |
||
| 461 | access_url_id = $url_access_id AND ( |
||
| 462 | code LIKE '%" . $search_term_safe . "%' OR |
||
| 463 | title LIKE '%" . $search_term_safe . "%' OR |
||
| 464 | tutor_name LIKE '%" . $search_term_safe . "%' |
||
| 465 | ) |
||
| 466 | $without_special_courses |
||
| 467 | $visibilityCondition |
||
| 468 | ORDER BY title, visual_code ASC |
||
| 469 | $limitFilter |
||
| 470 | "; |
||
| 471 | } |
||
| 472 | } |
||
| 473 | $result_find = Database::query($sql_find); |
||
| 474 | $courses = array(); |
||
| 475 | while ($row = Database::fetch_array($result_find)) { |
||
| 476 | $row['registration_code'] = !empty($row['registration_code']); |
||
| 477 | $count_users = count(CourseManager::get_user_list_from_course_code($row['code'])); |
||
| 478 | $count_connections_last_month = Tracking::get_course_connections_count( |
||
| 479 | $row['id'], 0, api_get_utc_datetime(time() - (30 * 86400)) |
||
| 480 | ); |
||
| 481 | |||
| 482 | $point_info = CourseManager::get_course_ranking($row['id'], 0); |
||
| 483 | |||
| 484 | $courses[] = array( |
||
| 485 | 'real_id' => $row['id'], |
||
| 486 | 'point_info' => $point_info, |
||
| 487 | 'code' => $row['code'], |
||
| 488 | 'directory' => $row['directory'], |
||
| 489 | 'visual_code' => $row['visual_code'], |
||
| 490 | 'title' => $row['title'], |
||
| 491 | 'tutor' => $row['tutor_name'], |
||
| 492 | 'subscribe' => $row['subscribe'], |
||
| 493 | 'unsubscribe' => $row['unsubscribe'], |
||
| 494 | 'registration_code' => $row['registration_code'], |
||
| 495 | 'creation_date' => $row['creation_date'], |
||
| 496 | 'visibility' => $row['visibility'], |
||
| 497 | 'count_users' => $count_users, |
||
| 498 | 'count_connections' => $count_connections_last_month |
||
| 499 | ); |
||
| 500 | } |
||
| 501 | return $courses; |
||
| 502 | } |
||
| 503 | |||
| 504 | /** |
||
| 505 | * unsubscribe the user from a given course |
||
| 506 | * @param string $course_code |
||
| 507 | * @return bool True if it success |
||
| 508 | */ |
||
| 509 | public function remove_user_from_course($course_code) |
||
| 539 | |||
| 540 | /** |
||
| 541 | * stores the user course category in the chamilo_user database |
||
| 542 | * @param string Category title |
||
| 543 | * @return bool True if it success |
||
| 544 | */ |
||
| 545 | public function store_course_category($category_title) |
||
| 582 | |||
| 583 | /** |
||
| 584 | * Counts the number of courses in a given course category |
||
| 585 | * @param string $categoryCode Category code |
||
| 586 | * @param $searchTerm |
||
| 587 | * @return int Count of courses |
||
| 588 | */ |
||
| 589 | public function count_courses_in_category($categoryCode, $searchTerm = '') |
||
| 593 | |||
| 594 | /** |
||
| 595 | * get the browsing of the course categories (faculties) |
||
| 596 | * @return array array containing a list with all the categories and subcategories(if needed) |
||
| 597 | */ |
||
| 598 | public function browse_course_categories() |
||
| 602 | |||
| 603 | /** |
||
| 604 | * Display all the courses in the given course category. I could have used a parameter here |
||
| 605 | * @param string $categoryCode Category code |
||
| 606 | * @param int $randomValue |
||
| 607 | * @param array $limit will be used if $random_value is not set. |
||
| 608 | * This array should contains 'start' and 'length' keys |
||
| 609 | * @return array Courses data |
||
| 610 | */ |
||
| 611 | public function browse_courses_in_category($categoryCode, $randomValue = null, $limit = array()) |
||
| 615 | |||
| 616 | /** |
||
| 617 | * Subscribe the user to a given course |
||
| 618 | * @param string $course_code Course code |
||
| 619 | * @return string Message about results |
||
| 620 | */ |
||
| 621 | public function subscribe_user($course_code) |
||
| 669 | |||
| 670 | /** |
||
| 671 | * List the sessions |
||
| 672 | * @param string $date (optional) The date of sessions |
||
| 673 | * @param array $limit |
||
| 674 | * @return array The session list |
||
| 675 | */ |
||
| 676 | public function browseSessions($date = null, $limit = array()) |
||
| 677 | { |
||
| 678 | $em = Database::getManager(); |
||
| 679 | $qb = $em->createQueryBuilder(); |
||
| 680 | |||
| 681 | $_sessions = $qb->select('s')->from('ChamiloCoreBundle:Session', 's'); |
||
| 682 | |||
| 683 | if (!empty($limit)) { |
||
| 684 | $_sessions->setFirstResult($limit['start']) |
||
| 685 | ->setMaxResults($limit['length']); |
||
| 686 | } |
||
| 687 | |||
| 688 | $_sessions->where( |
||
| 689 | $qb->expr()->gt('s.nbrCourses', 0) |
||
| 690 | ); |
||
| 691 | |||
| 692 | if (!is_null($date)) { |
||
| 693 | $_sessions |
||
| 694 | ->andWhere( |
||
| 695 | $qb->expr()->orX( |
||
| 696 | $qb->expr()->between(':date', 's.accessStartDate', 's.accessEndDate'), |
||
| 697 | $qb->expr()->isNull('s.accessEndDate'), |
||
| 698 | $qb->expr()->andX( |
||
| 699 | $qb->expr()->isNull('s.accessStartDate'), |
||
| 700 | $qb->expr()->isNotNull('s.accessEndDate'), |
||
| 701 | $qb->expr()->gt('s.accessEndDate', ':date') |
||
| 702 | ) |
||
| 703 | ) |
||
| 704 | ) |
||
| 705 | ->setParameter('date', $date); |
||
| 706 | } |
||
| 707 | |||
| 708 | return $_sessions->getQuery()->getResult(); |
||
| 709 | } |
||
| 710 | |||
| 711 | /** |
||
| 712 | * Return a COUNT from Session table |
||
| 713 | * @param string $date in Y-m-d format |
||
| 714 | * @return int |
||
| 715 | */ |
||
| 716 | public function countSessions($date = null) |
||
| 738 | |||
| 739 | /** |
||
| 740 | * Search sessions by the tags in their courses |
||
| 741 | * @param string $termTag Term for search in tags |
||
| 742 | * @param array $limit Limit info |
||
| 743 | * @return array The sessions |
||
| 744 | */ |
||
| 745 | public function browseSessionsByTags($termTag, array $limit) |
||
| 746 | { |
||
| 747 | $em = Database::getManager(); |
||
| 748 | $qb = $em->createQueryBuilder(); |
||
| 749 | |||
| 750 | $sessions = $qb->select('s') |
||
| 751 | ->distinct(true) |
||
| 752 | ->from('ChamiloCoreBundle:Session', 's') |
||
| 753 | ->innerJoin( |
||
| 754 | 'ChamiloCoreBundle:SessionRelCourse', |
||
| 755 | 'src', |
||
| 756 | \Doctrine\ORM\Query\Expr\Join::WITH, |
||
| 757 | 's.id = src.session' |
||
| 758 | ) |
||
| 759 | ->innerJoin( |
||
| 760 | 'ChamiloCoreBundle:ExtraFieldRelTag', |
||
| 761 | 'frt', |
||
| 762 | \Doctrine\ORM\Query\Expr\Join::WITH, |
||
| 763 | 'src.course = frt.itemId' |
||
| 764 | ) |
||
| 765 | ->innerJoin( |
||
| 766 | 'ChamiloCoreBundle:Tag', |
||
| 767 | 't', |
||
| 768 | \Doctrine\ORM\Query\Expr\Join::WITH, |
||
| 769 | 'frt.tagId = t.id' |
||
| 770 | ) |
||
| 771 | ->innerJoin( |
||
| 772 | 'ChamiloCoreBundle:ExtraField', |
||
| 773 | 'f', |
||
| 774 | \Doctrine\ORM\Query\Expr\Join::WITH, |
||
| 775 | 'frt.fieldId = f.id' |
||
| 776 | ) |
||
| 777 | ->where( |
||
| 778 | $qb->expr()->like('t.tag', ":tag") |
||
| 779 | ) |
||
| 780 | ->andWhere( |
||
| 781 | $qb->expr()->eq('f.extraFieldType', ExtraField::COURSE_FIELD_TYPE) |
||
| 782 | ) |
||
| 783 | ->setFirstResult($limit['start']) |
||
| 784 | ->setMaxResults($limit['length']) |
||
| 785 | ->setParameter('tag', "$termTag%") |
||
| 786 | ->getQuery() |
||
| 787 | ->getResult(); |
||
| 788 | |||
| 789 | $sessionsToBrowse = []; |
||
| 790 | foreach ($sessions as $session) { |
||
| 791 | if ($session->getNbrCourses() === 0) { |
||
| 792 | continue; |
||
| 793 | } |
||
| 794 | $sessionsToBrowse[] = $session; |
||
| 795 | } |
||
| 796 | |||
| 797 | return $sessionsToBrowse; |
||
| 798 | } |
||
| 799 | |||
| 800 | /** |
||
| 801 | * Search sessions by searched term by session name |
||
| 802 | * @param string $queryTerm Term for search |
||
| 803 | * @param array $limit Limit info |
||
| 804 | * @return array The sessions |
||
| 805 | */ |
||
| 806 | public function browseSessionsBySearch($queryTerm, array $limit) |
||
| 831 | } |
||
| 832 |
Let’s assume that you have a directory layout like this:
. |-- OtherDir | |-- Bar.php | `-- Foo.php `-- SomeDir `-- Foo.phpand let’s assume the following content of
Bar.php:If both files
OtherDir/Foo.phpandSomeDir/Foo.phpare loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.phpHowever, as
OtherDir/Foo.phpdoes not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: