Joomla 3 二次开发 说明 1
此版本需要在PHP5.3.10以上运行
首先,进入安装文件夹installation/index.php
1 //版本检测 2 if (version_compare(PHP_VERSION, '5.3.10', '<')) 3 { 4 die('Your host needs to use PHP 5.3.10 or higher to run this version of Joomla!'); 5 } 6 7 //入口钥匙 8 define('_JEXEC', 1); 9 10 //引导程序 11 require_once dirname(__FILE__) . '/application/bootstrap.php'; 12 13 //下面代码先省略 直接进入bootstrap.php文
打开application/bootstrap.php
defined('_JEXEC') or die; //打钥匙进门 // Define the base path and require the other defines define('JPATH_BASE', dirname(__DIR__)); require_once __DIR__ . '/defines.php'; //定义路径 此文件可以忽略不看 但是要注意其中的常量 // Launch the application //进入这个文件 require_once __DIR__ . '/framework.php'; // Register the Installation application JLoader::registerPrefix('Installation', JPATH_INSTALLATION); //定义安装 // Register the application's router due to non-standard include JLoader::register('JRouterInstallation', __DIR__ . '/router.php'); //定义路由
打开application/framework.php文件
1 //.....前部代码 2 3 //定义错误 调试 程序开始时间 4 error_reporting(E_ALL); 5 const JDEBUG = false; 6 @ini_set('magic_quotes_runtime', 0); 7 8 9 //检测配置文件 10 if (file_exists(JPATH_CONFIGURATION . '/configuration.php') 11 && (filesize(JPATH_CONFIGURATION . '/configuration.php') > 10) 12 && !file_exists(JPATH_INSTALLATION . '/index.php')) 13 { 14 header('Location: ../index.php'); 15 exit(); 16 } 17 18 // Import the Joomla Platform. 19 //下面这2个文件不错 依次进入 20 require_once JPATH_LIBRARIES . '/import.php'; 21 22 // Bootstrap the CMS libraries. 23 require_once JPATH_LIBRARIES . '/cms.php'; 24 25 // Import filesystem classes since they aren't autoloaded 26 //这个函数在根目录libraries/loader.php 27 jimport('joomla.filesystem.file'); 28 jimport('joomla.filesystem.folder'); 29 jimport('joomla.filesystem.path');
打开application/import.php文件
1 /*前面很长一段 对几个常量定义 2 JPATH_PLATFORM 3 IS_WIN 4 IS_UNIX 5 6 加载J平台类 J的一些版本信息都可以得到 7 下面就是一个自动加载类Loader 它用到了spl_autoload_register __autoload() _load() 8 spl_autoload_register 主要作用如下 9 一般 需要实例对象 必须要用到 include/require(_once)等四个 10 J为了省略这些代码 就直接用了spl_autoload_register 11 $c = new $Class 这个代码可以运行的话 只需要__autoload()函数里面return include $PATH($class的路径) 12 */ 13 14 15 //加载LOADER.PHP 16 if (!class_exists('JLoader')) 17 { 18 require_once JPATH_PLATFORM . '/loader.php'; 19 } 20 21 // Make sure that the Joomla Platform has been successfully loaded. 22 if (!class_exists('JLoader')) 23 { 24 throw new RuntimeException('Joomla Platform not loaded.'); 25 } 26 27 //调用方法 28 // Setup the autoloaders. 29 JLoader::setup(); 30 31 // Import the base Joomla Platform libraries. 32 JLoader::import('joomla.factory'); 33 34 // Register classes for compatability with PHP 5.3 35 if (version_compare(PHP_VERSION, '5.4.0', '<')) 36 { 37 JLoader::register('JsonSerializable', JPATH_PLATFORM . '/compat/jsonserializable.php'); 38 } 39 40 // Register classes that don't follow one file per class naming conventions. 41 JLoader::register('JText', JPATH_PLATFORM . '/joomla/language/text.php'); 42 JLoader::register('JRoute', JPATH_PLATFORM . '/joomla/application/route.php'); 43 44 // Register the PasswordHash lib 45 JLoader::register('PasswordHash', JPATH_PLATFORM . '/phpass/PasswordHash.php');
打开根目录libraries/loader.php
1 function setup($enablePsr = true, $enablePrefixes = true, $enableClasses = true) 2 { 3 if ($enableClasses) 4 { 5 // Register the class map based autoloader. 6 spl_autoload_register(array('JLoader', 'load')); //寻找类的时候调用Loader类的Load方法,而不使用系统__autoload 这里有IF 注意 7 } 8 9 if ($enablePrefixes) 10 { 11 // Register the J prefix and base path for Joomla platform libraries. 12 self::registerPrefix('J', JPATH_PLATFORM . '/joomla'); 13 14 // Register the prefix autoloader. 15 spl_autoload_register(array('JLoader', '_autoload'));//同上 貌似是重写系统的__autoload 16 } 17 18 if ($enablePsr) 19 { 20 // Register the PSR-0 based autoloader. 21 spl_autoload_register(array('JLoader', 'loadByPsr0')); 22 spl_autoload_register(array('JLoader', 'loadByAlias')); 23 } 24 } 25 26 //上面这个方法 让在没有include等四方法的作用下 直接new or :: 的时候 依次按照类的名字寻找对应的类所在的文件 并且 inlcude 进来
其他的
/* 这个方法 很明显 首先在全局里面看 有没有 然后再LOAD这个类里面看有没有 有就返回真 没有就返回失败 */ function load($class) { // Sanitize class name. $class = strtolower($class); // If the class already exists do nothing. if (class_exists($class, false)) { return true; } // If the class is registered include the file. if (isset(self::$classes[$class])) { include_once self::$classes[$class]; return true; } return false; } /** 下面的方法就通过LOAD里面的标示符 和 类名 对应的路径存在文件如否 包含对应类 (?<=[a-z0-9])(?=[A-Z]) 这个正则匹配出来 所有大写开头的单词 很关键 其中的prefixes 系统有2个 一个在setup方法中定义 一个在cms.php文件中定义 其实 在安装程序里面 也定义了一个 prefix: Array ( [J] => Array ( [0] => /home/wwwroot/www.mycode.com/j/libraries/cms [1] => /home/wwwroot/www.mycode.com/j/libraries/joomla ) [Installation] => Array ( [0] => /home/wwwroot/www.mycode.com/j/installation ) ) 这样一来 就更快的找到对应的类的文件 例如 JApplicationWeb 这个类 通过下面的函数之后 直接到了 /home/wwwroot/www.mycode.com/j/libraries/joomla/application/web.php 很好 很方便 */ private static function _autoload($class) { foreach (self::$prefixes as $prefix => $lookup) { $chr = strlen($prefix) < strlen($class) ? $class[strlen($prefix)] : 0; if (strpos($class, $prefix) === 0 && ($chr === strtoupper($chr))) { return self::_load(substr($class, strlen($prefix)), $lookup); } } return false; } /** * Load a class based on name and lookup array. * * @param string $class The class to be loaded (wihtout prefix). * @param array $lookup The array of base paths to use for finding the class file. * * @return boolean True if the class was loaded, false otherwise. * * @since 12.1 */ private static function _load($class, $lookup) { // Split the class name into parts separated by camelCase. $parts = preg_split('/(?<=[a-z0-9])(?=[A-Z])/x', $class); // If there is only one part we want to duplicate that part for generating the path. $parts = (count($parts) === 1) ? array($parts[0], $parts[0]) : $parts; foreach ($lookup as $base) { // Generate the path based on the class name parts. $path = $base . '/' . implode('/', array_map('strtolower', $parts)) . '.php'; // Load the file if it exists. if (file_exists($path)) { return include $path; } } return false; } }
1 /** 2 function loadByPsr0 和 loadByAlias 3 4 前者遵循PSR[Proposing a Standards Recommendation(提出标准建议)]标准来找类 5 DIRECTORY_SEPARATOR => '/' 6 通过函数处理 可以吧\A\Class=> /path/A/Class.php \A_Class => /path/A/Class.php 7 只是这个时候 寻找的路径 是namaspaces 8 namespace: 9 Array 10 ( 11 [Joomla] => Array 12 ( 13 [0] => /home/wwwroot/www.mycode.com/j/libraries/framework 14 ) 15 16 [Symfony] => Array 17 ( 18 [0] => /home/wwwroot/www.mycode.com/j/libraries/framework 19 ) 20 21 ) 22 23 24 后者 通过别名来完成自动加载 具体参照 class_alias这个函数 25 classAliases: 26 Array 27 ( 28 [JRegistry] => \Joomla\Registry\Registry 29 [JRegistryFormat] => \Joomla\Registry\AbstractRegistryFormat 30 [JRegistryFormatINI] => \Joomla\Registry\Format\Ini 31 [JRegistryFormatJSON] => \Joomla\Registry\Format\Json 32 [JRegistryFormatPHP] => \Joomla\Registry\Format\Php 33 [JRegistryFormatXML] => \Joomla\Registry\Format\Xml 34 [JAdministrator] => JApplicationAdministrator 35 [JSite] => JApplicationSite 36 ) 37 38 /*** 39 function register 注册 写入数组self::$classes中 通过getClassList()方法可以直接取值 40 function registerPrefix 注册标示符 写入数组self::$prefixes中 看上去仅供内部使用 41 function registerNamespace 注册namespace 写入数组self::$namespaces 同上 42 function registerAlias 注册别名 写入数组self::$classAliases 43 function discover 给了类的标示符 /名字/路径 就可以直接用这个函数注册类 44 45 整个class 的最后 还有两个函数 46 一个是EXIT 47 一个是用Loader的导入函数 48 49 *////