这里主要分析./include/utils/autoload.php中init方法里的加载composer相关方法,其主要作用是在自动加载时引入相关的composer类。
// 加载的composer文件 protected static $composerPaths = array( 'include_paths' => 'vendor/composer/include_paths.php', 'autoload_namespaces' => 'vendor/composer/autoload_namespaces.php', 'autoload_psr4' => 'vendor/composer/autoload_psr4.php', 'autoload_classmap' => 'vendor/composer/autoload_classmap.php', ); // psr4命名空间存放,按多到少加载 public static $namespaceMapPsr4 = array(); // psr0命名空间存放 public static $namespaceMap = array();
public static function init() { ``` self::loadComposerIncludePaths(); self::loadComposerPsr4(); self::loadComposerPsr0(); ``` } public static function loadComposerIncludePaths() { // 加载include_paths并加入get_include_path中,但是目前为空 $includePaths = self::getIncludeReturn(self::$composerPaths['include_paths']); array_push($includePaths, get_include_path()); set_include_path(join(PATH_SEPARATOR, $includePaths)); } public static function loadComposerPsr4() { $map = self::getIncludeReturn(self::$composerPaths['autoload_psr4']); foreach ($map as $namespace => $paths) { if (is_array($paths)) { foreach ($paths as $path) { $path = self::normalizeFilePath($path); self::addNamespace($namespace, $path, 'psr4'); } } else { $path = self::normalizeFilePath($paths); self::addNamespace($namespace, $path, 'psr4'); } } } public static function loadComposerPsr0() { $map = self::getIncludeReturn(self::$composerPaths['autoload_namespaces']); foreach ($map as $namespace => $paths) { if (is_array($paths)) { foreach ($paths as $path) { $path = self::normalizeFilePath($path); self::addNamespace($namespace, $path, 'psr0'); } } else { $path = self::normalizeFilePath($paths); self::addNamespace($namespace, $path, 'psr0'); } } } public static function addNamespace($prefix, $dir, $type = 'psr0') { // select which map to use $map = ($type === 'psr4') ? 'namespaceMapPsr4' : 'namespaceMap'; // enforce trailing \ $prefix = rtrim($prefix, '\\') . '\\'; // remove trailing / and normalize path $dir = rtrim(self::normalizeFilePath($dir), '/'); // use a list of paths per prefix self::${$map}[$prefix][] = $dir; // The order of self::$namespace is important because the first match // will win. When registering new namespace dynamically we need to make // sure this array is ordered from more to less specific. // 从多到少排序 // 这一步主要是在自动加载时循环数组从头开始,匹配到了便退出循环 uksort(self::${$map}, function ($val1, $val2) { $level1 = substr_count($val1, '\\'); $level2 = substr_count($val2, '\\'); if ($level1 > $level2) { return -1; } elseif ($level1 < $level2) { return 1; } else { // if levels are the same, sort alphabetically for predictable result return strcasecmp($val1, $val2); } }); }
// autoload_psr4.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'Sugarcrm\\Sugarcrm\\inc\\' => array($baseDir . '/include'), 'Sugarcrm\\Sugarcrm\\custom\\inc\\' => array($baseDir . '/custom/include'), 'Sugarcrm\\Sugarcrm\\custom\\' => array($baseDir . '/custom/src', $baseDir . '/custom'), 'Sugarcrm\\Sugarcrm\\' => array($baseDir . '/src', $baseDir . '/'), ); // autoload_namespaces.php @generated by Composer $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( 'Elastica\\Test' => array($vendorDir . '/ruflin/elastica/test/lib'), 'Elastica' => array($vendorDir . '/ruflin/elastica/lib'), );