核心kohana

   1 <?php defined('SYSPATH') OR die('No direct access allowed.');
   2 /**
   3  * Contains the most low-level helpers methods in Kohana:
   4  *
   5  * - Environment initialization
   6  * - Locating files within the cascading filesystem
   7  * - Auto-loading and transparent extension of classes
   8  * - Variable and path debugging
   9  *
  10  * @package    Gleez\Core
  11  * @author     Sandeep Sangamreddi - Gleez
  12  * @author     Kohana Team
  13  * @copyright  (c) 2011-2013 Gleez Technologies
  14  * @copyright  (c) 2008-2012 Kohana Team
  15  * @license    http://gleezcms.org/license Gleez CMS License
  16  * @license    http://kohanaframework.org/license
  17  */
  18 class Kohana {
  19 
  20     // Release version and codename
  21     const VERSION  = '3.2.2';
  22     const CODENAME = 'hypoleucos';
  23 
  24     // Common environment type constants for consistency and convenience
  25     const PRODUCTION  = 10;
  26     const STAGING     = 20;
  27     const TESTING     = 30;
  28     const DEVELOPMENT = 40;
  29 
  30     // Security check that is added to all generated PHP files
  31     const FILE_SECURITY = '<?php defined(\'SYSPATH\') OR die(\'No direct script access.\');';
  32 
  33     // Format of cache files: header, cache name, and data
  34     const FILE_CACHE = ":header \n\n// :name\n\n:data\n";
  35 
  36     /**
  37      * @var  string  Current environment name
  38      */
  39     public static $environment = Kohana::DEVELOPMENT;
  40 
  41     /**
  42      * @var  boolean  True if Kohana is running from the command line
  43      */
  44     public static $is_cli = FALSE;
  45 
  46     /**
  47      * @var  boolean  True if Kohana is running on windows
  48      */
  49     public static $is_windows = FALSE;
  50 
  51     /**
  52      * @var  boolean  True if [magic quotes](http://php.net/manual/en/security.magicquotes.php) is enabled.
  53      */
  54     public static $magic_quotes = FALSE;
  55 
  56     /**
  57      * @var  boolean  Should errors and exceptions be logged
  58      */
  59     public static $log_errors = FALSE;
  60 
  61     /**
  62      * @var  boolean  TRUE if PHP safe mode is on
  63      */
  64     public static $safe_mode = FALSE;
  65 
  66     /**
  67      * @var  string
  68      */
  69     public static $content_type = 'text/html';
  70 
  71     /**
  72      * @var  string  character set of input and output
  73      */
  74     public static $charset = 'utf-8';
  75 
  76     /**
  77      * @var  string  the name of the server Kohana is hosted upon
  78      */
  79     public static $server_name = '';
  80 
  81     /**
  82      * @var  array   list of valid host names for this instance
  83      */
  84     public static $hostnames = array();
  85 
  86     /**
  87      * @var  string  base URL to the application
  88      */
  89     public static $base_url = '/';
  90 
  91     /**
  92      * @var  string  Application index file, added to links generated by Kohana. Set by [Kohana::init]
  93      */
  94     public static $index_file = 'index.php';
  95 
  96     /**
  97      * @var  string  Cache directory, used by [Kohana::cache]. Set by [Kohana::init]
  98      */
  99     public static $cache_dir;
 100 
 101     /**
 102      * @var  integer  Default lifetime for caching, in seconds, used by [Kohana::cache]. Set by [Kohana::init]
 103      */
 104     public static $cache_life = 60;
 105 
 106     /**
 107      * @var  boolean  Whether to use internal caching for [Kohana::find_file], does not apply to [Kohana::cache]. Set by [Kohana::init]
 108      */
 109     public static $caching = FALSE;
 110 
 111     /**
 112      * @var  boolean  Whether to enable [profiling](kohana/profiling). Set by [Kohana::init]
 113      */
 114     public static $profiling = TRUE;
 115 
 116     /**
 117      * @var  boolean  Enable Kohana catching and displaying PHP errors and exceptions. Set by [Kohana::init]
 118      */
 119     public static $errors = TRUE;
 120 
 121     /**
 122      * @var  array  Types of errors to display at shutdown
 123      */
 124     public static $shutdown_errors = array(E_PARSE, E_ERROR, E_USER_ERROR);
 125 
 126     /**
 127      * @var  boolean  set the X-Powered-By header
 128      */
 129     public static $expose = FALSE;
 130 
 131     /**
 132      * @var  Log  logging object
 133      */
 134     public static $log;
 135 
 136     /**
 137      * @var  Config  config object
 138      */
 139     public static $config;
 140 
 141     /**
 142      * @var  boolean  Has [Kohana::init] been called?
 143      */
 144     protected static $_init = FALSE;
 145 
 146     /**
 147      * @var  array   Currently active modules
 148      */
 149     protected static $_modules = array();
 150 
 151     /**
 152      * @var  array   Include paths that are used to find files
 153      */
 154     protected static $_paths = array(APPPATH, GLZPATH, SYSPATH);
 155 
 156     /**
 157      * @var  array   File path cache, used when caching is true in [Kohana::init]
 158      */
 159     protected static $_files = array();
 160 
 161     /**
 162      * @var  boolean  Has the file path cache changed during this execution?  Used internally when when caching is true in [Kohana::init]
 163      */
 164     protected static $_files_changed = FALSE;
 165 
 166     /**
 167      * Initializes the environment:
 168      *
 169      * - Disables register_globals and magic_quotes_gpc
 170      * - Determines the current environment
 171      * - Set global settings
 172      * - Sanitizes GET, POST, and COOKIE variables
 173      * - Converts GET, POST, and COOKIE variables to the global character set
 174      *
 175      * The following settings can be set:
 176      *
 177      * Type      | Setting    | Description                                    | Default Value
 178      * ----------|------------|------------------------------------------------|---------------
 179      * `string`  | base_url   | The base URL for your application.  This should be the *relative* path from your DOCROOT to your `index.php` file, in other words, if Kohana is in a subfolder, set this to the subfolder name, otherwise leave it as the default.  **The leading slash is required**, trailing slash is optional.   | `"/"`
 180      * `string`  | index_file | The name of the [front controller](http://en.wikipedia.org/wiki/Front_Controller_pattern).  This is used by Kohana to generate relative urls like [HTML::anchor()] and [URL::base()]. This is usually `index.php`.  To [remove index.php from your urls](tutorials/clean-urls), set this to `FALSE`. | `"index.php"`
 181      * `string`  | charset    | Character set used for all input and output    | `"utf-8"`
 182      * `string`  | cache_dir  | Kohana's cache directory.  Used by [Kohana::cache] for simple internal caching, like [Fragments](kohana/fragments) and **\[caching database queries](this should link somewhere)**.  This has nothing to do with the [Cache module](cache). | `APPPATH."cache"`
 183      * `integer` | cache_life | Lifetime, in seconds, of items cached by [Kohana::cache]         | `60`
 184      * `boolean` | errors     | Should Kohana catch PHP errors and uncaught Exceptions and show the `error_view`. See [Error Handling](kohana/errors) for more info. <br /> <br /> Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE`
 185      * `boolean` | profile    | Whether to enable the [Profiler](kohana/profiling). <br /> <br />Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE`
 186      * `boolean` | caching    | Cache file locations to speed up [Kohana::find_file].  This has nothing to do with [Kohana::cache], [Fragments](kohana/fragments) or the [Cache module](cache).  <br /> <br />  Recommended setting: `FALSE` while developing, `TRUE` on production servers. | `FALSE`
 187      * `boolean` | expose     | Set the X-Powered-By header
 188      *
 189      * @throws  Kohana_Exception
 190      * @param   array   $settings   Array of settings.  See above.
 191      * @return  void
 192      * @uses    Kohana::globals
 193      * @uses    Kohana::sanitize
 194      * @uses    Kohana::cache
 195      * @uses    Profiler
 196      */
 197     public static function init(array $settings = NULL)
 198     {
 199         if (Kohana::$_init)
 200         {
 201             // Do not allow execution twice
 202             // 不允许执行两次,默认 Kohana::$_init = FALSE;
 203             return;
 204         }
 205 
 206         // Kohana is now initialized
 207         Kohana::$_init = TRUE;
 208         
 209 
 210         if (isset($settings['profile']))
 211         {
 212             // Enable profiling
 213             Kohana::$profiling = (bool) $settings['profile'];
 214         }
 215         
 216 
 217         // Start an output buffer
 218         // 打开输出控制缓冲
 219         ob_start();
 220         
 221 
 222         if (isset($settings['errors']))
 223         {
 224             // Enable error handling
 225             Kohana::$errors = (bool) $settings['errors'];
 226         }
 227 
 228         if (Kohana::$errors === TRUE)
 229         {
 230             // Enable Kohana exception handling, adds stack traces and error source.
 231             // 设置一个用户定义的异常处理函数
 232             set_exception_handler(array('Kohana_Exception', 'handler'));
 233 
 234             // Enable Kohana error handling, converts all PHP errors to exceptions.
 235             // 设置一个用户定义的错误处理函数
 236             set_error_handler(array('Kohana', 'error_handler'));
 237         }
 238 
 239 
 240 
 241 
 242 
 243         // Enable the Kohana shutdown handler, which catches E_FATAL errors.
 244         // Register a function for execution on shutdown
 245         register_shutdown_function(array('Kohana', 'shutdown_handler'));
 246         
 247         
 248         // ini_get — 获取一个配置选项的值
 249         if (ini_get('register_globals'))
 250         {
 251             // Reverse the effects of register_globals
 252             Kohana::globals();
 253         }
 254         
 255 
 256         if (isset($settings['expose']))
 257         {
 258             Kohana::$expose = (bool) $settings['expose'];
 259         }
 260 
 261 
 262 
 263         // Determine if we are running in a command line environment
 264         Kohana::$is_cli = (PHP_SAPI === 'cli');
 265 
 266 
 267 
 268         // Determine if we are running in a Windows environment
 269         Kohana::$is_windows = (DIRECTORY_SEPARATOR === '\\');
 270 
 271 
 272 
 273         // Determine if we are running in safe mode
 274         Kohana::$safe_mode = (bool) ini_get('safe_mode');
 275 
 276 
 277 
 278         if (isset($settings['cache_dir']))
 279         {
 280             if ( ! is_dir($settings['cache_dir']))
 281             {
 282                 try
 283                 {
 284                     // Create the cache directory
 285                     mkdir($settings['cache_dir'], 0755, TRUE);
 286 
 287                     // Set permissions (must be manually set to fix umask issues)
 288                     chmod($settings['cache_dir'], 0755);
 289                 }
 290                 catch (Exception $e)
 291                 {
 292                     throw new Kohana_Exception('Could not create cache directory :dir',
 293                         array(':dir' => Debug::path($settings['cache_dir'])));
 294                 }
 295             }
 296 
 297             // Set the cache directory path
 298             Kohana::$cache_dir = realpath($settings['cache_dir']);
 299         }
 300         else
 301         {
 302             // Use the default cache directory
 303             Kohana::$cache_dir = APPPATH.'cache';
 304         }
 305         
 306         
 307 
 308         if ( ! is_writable(Kohana::$cache_dir))
 309         {
 310             throw new Kohana_Exception('Directory :dir must be writable',
 311                 array(':dir' => Debug::path(Kohana::$cache_dir)));
 312         }
 313         
 314         
 315 
 316         if (isset($settings['cache_life']))
 317         {
 318             // Set the default cache lifetime
 319             Kohana::$cache_life = (int) $settings['cache_life'];
 320         }
 321         
 322         
 323 
 324         if (isset($settings['caching']))
 325         {
 326             // Enable or disable internal caching
 327             Kohana::$caching = (bool) $settings['caching'];
 328         }
 329         
 330         
 331 
 332         if (Kohana::$caching === TRUE)
 333         {
 334             // Load the file path cache
 335             Kohana::$_files = Kohana::cache('Kohana::find_file()');
 336         }
 337         
 338         
 339 
 340         if (isset($settings['charset']))
 341         {
 342             // Set the system character set
 343             Kohana::$charset = strtolower($settings['charset']);
 344         }
 345         
 346         
 347         
 348 
 349         if (function_exists('mb_internal_encoding'))
 350         {
 351             // Set the MB extension encoding to the same character set
 352             // 设置/获取内部字符编码
 353             mb_internal_encoding(Kohana::$charset);
 354         }
 355         
 356         
 357 
 358         if (isset($settings['base_url']))
 359         {
 360             // Set the base URL
 361             Kohana::$base_url = rtrim($settings['base_url'], '/').'/';
 362         }
 363         
 364         
 365 
 366         if (isset($settings['index_file']))
 367         {
 368             // Set the index file
 369             Kohana::$index_file = trim($settings['index_file'], '/');
 370         }
 371         
 372         
 373 
 374         // Determine if the extremely evil magic quotes are enabled
 375         Kohana::$magic_quotes = version_compare(PHP_VERSION, '5.4') < 0 AND get_magic_quotes_gpc();
 376         
 377         
 378 
 379         // Sanitize all request variables
 380         $_GET    = Kohana::sanitize($_GET);
 381         $_POST   = Kohana::sanitize($_POST);
 382         $_COOKIE = Kohana::sanitize($_COOKIE);
 383         
 384         
 385         // instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例:
 386         // instanceof 也可用来确定一个变量是不是继承自某一父类的子类的实例:
 387         // 检查一个对象是否不是某个类的实例,可以使用逻辑运算符 not。---
 388         
 389         // Load the logger if one doesn't already exist
 390         if ( ! Kohana::$log instanceof Log)
 391         {
 392             Kohana::$log = Log::instance();
 393         }
 394 
 395         // Load the config if one doesn't already exist
 396         if ( ! Kohana::$config instanceof Config)
 397         {
 398             Kohana::$config = new Config;
 399         }
 400     }
 401 
 402     /**
 403      * Cleans up the environment:
 404      *
 405      * - Restore the previous error and exception handlers
 406      * - Destroy the Kohana::$log and Kohana::$config objects
 407      *
 408      * @return  void
 409      */
 410     public static function deinit()
 411     {
 412         if (Kohana::$_init) //已经加载配置选项
 413         {
 414             // Removed the autoloader
 415             spl_autoload_unregister(array('Kohana', 'auto_load'));
 416 
 417             if (Kohana::$errors)
 418             {
 419                 // Go back to the previous error handler
 420                 // 还原之前的错误处理函数
 421                 restore_error_handler();
 422 
 423                 // Go back to the previous exception handler
 424                 // 恢复之前定义过的异常处理函数
 425                 restore_exception_handler();
 426             }
 427 
 428             // Destroy objects created by init
 429             Kohana::$log = Kohana::$config = NULL;
 430 
 431             // Reset internal storage
 432             Kohana::$_modules = Kohana::$_files = array();
 433             Kohana::$_paths   = array(APPPATH, GLZPATH, SYSPATH);
 434 
 435             // Reset file cache status
 436             Kohana::$_files_changed = FALSE;
 437 
 438             // Kohana is no longer initialized
 439             Kohana::$_init = FALSE;
 440         }
 441     }
 442 
 443     /**
 444      * Reverts the effects of the `register_globals` PHP setting by unsetting
 445      * all global varibles except for the default super globals (GPCS, etc),
 446      * which is a [potential security hole.][ref-wikibooks]
 447      *
 448      * This is called automatically by [Kohana::init] if `register_globals` is
 449      * on.
 450      *
 451      *
 452      * [ref-wikibooks]: http://en.wikibooks.org/wiki/PHP_Programming/Register_Globals
 453      *
 454      * @return  void
 455      */
 456     public static function globals()
 457     {
 458         if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS']))
 459         {
 460             // Prevent malicious GLOBALS overload attack
 461             echo "Global variable overload attack detected! Request aborted.\n";
 462 
 463             // Exit with an error status
 464             exit(1);
 465         }
 466 
 467         // Get the variable names of all globals
 468         $global_variables = array_keys($GLOBALS);
 469 
 470         // Remove the standard global variables from the list
 471         $global_variables = array_diff($global_variables, array(
 472             '_COOKIE',    
 473             '_ENV',
 474             '_GET',
 475             '_FILES',
 476             '_POST',
 477             '_REQUEST',
 478             '_SERVER',
 479             '_SESSION',
 480             'GLOBALS',
 481         ));
 482 
 483         foreach ($global_variables as $name)
 484         {
 485             // Unset the global variable, effectively disabling register_globals
 486             unset($GLOBALS[$name]);
 487         }
 488     }
 489 
 490     /**
 491      * Recursively sanitizes an input variable:
 492      *
 493      * - Strips slashes if magic quotes are enabled
 494      * - Normalizes all newlines to LF
 495      *
 496      * @param   mixed   $value  any variable
 497      * @return  mixed   sanitized variable
 498      */
 499     public static function sanitize($value)
 500     {
 501         if (is_array($value) OR is_object($value))
 502         {
 503             foreach ($value as $key => $val)
 504             {
 505                 // Recursively clean each value
 506                 $value[$key] = Kohana::sanitize($val);
 507             }
 508         }
 509         elseif (is_string($value))
 510         {
 511             if (Kohana::$magic_quotes === TRUE)
 512             {
 513                 // Remove slashes added by magic quotes
 514                 $value = stripslashes($value);
 515             }
 516 
 517             if (strpos($value, "\r") !== FALSE)
 518             {
 519                 // Standardize newlines
 520                 $value = str_replace(array("\r\n", "\r"), "\n", $value);
 521             }
 522         }
 523 
 524         return $value;
 525     }
 526 
 527     /**
 528      * Provides auto-loading support of classes that follow Kohana's [class
 529      * naming conventions](kohana/conventions#class-names-and-file-location).
 530      * See [Loading Classes](kohana/autoloading) for more information.
 531      *
 532      * Class names are converted to file names by making the class name
 533      * lowercase and converting underscores to slashes:
 534      *
 535      *     // Loads classes/my/class/name.php
 536      *     Kohana::auto_load('My_Class_Name');
 537      *
 538      * You should never have to call this function, as simply calling a class
 539      * will cause it to be called.
 540      *
 541      * This function must be enabled as an autoloader in the bootstrap:
 542      *
 543      *     spl_autoload_register(array('Kohana', 'auto_load'));
 544      *
 545      * @param   string  $class  class name
 546      * @return  boolean
 547      */
 548     public static function auto_load($class)
 549     {
 550         try
 551         {
 552             // Transform the class name into a path
 553             $file = str_replace('_', '/', strtolower($class));
 554 
 555             if ($path = Kohana::find_file('classes', $file))
 556             {
 557                 // Load the class file
 558                 require $path;
 559 
 560                 // Class has been found
 561                 return TRUE;
 562             }
 563 
 564             // Class is not in the filesystem
 565             return FALSE;
 566         }
 567         catch (Exception $e)
 568         {
 569             Kohana_Exception::handler($e);
 570             die;
 571         }
 572     }
 573 
 574     /**
 575      * Changes the currently enabled modules. Module paths may be relative
 576      * or absolute, but must point to a directory:
 577      *
 578      *     Kohana::modules(array('modules/foo', MODPATH.'bar'));
 579      *
 580      * @param   array   $modules    list of module paths
 581      * @return  array   enabled modules
 582      */
 583     public static function modules(array $modules = NULL)
 584     {
 585         if ($modules === NULL)
 586         {
 587             // Not changing modules, just return the current set
 588             return Kohana::$_modules;
 589         }
 590         
 591         
 592         
 593         
 594 
 595         // Start a new list of include paths, APPPATH first
 596         $paths = array(APPPATH);
 597 
 598         foreach ($modules as $name => $path)
 599         {
 600             if (is_dir($path))
 601             {
 602                 // Add the module to include paths
 603                 $paths[] = $modules[$name] = realpath($path).DIRECTORY_SEPARATOR;
 604             }
 605             else
 606             {
 607                 // This module is invalid, remove it
 608                 throw new Kohana_Exception('Attempted to load an invalid or missing module \':module\' at \':path\'', array(
 609                     ':module' => $name,
 610                     ':path'   => Debug::path($path),
 611                 ));
 612             }
 613         }
 614 
 615         // Include GLZPATH before system for CFS
 616         $paths[] = GLZPATH;
 617 
 618         // Finish the include paths by adding SYSPATH
 619         $paths[] = SYSPATH;
 620         
 621         
 622         
 623         
 624         
 625         
 626 
 627         // Set the new include paths
 628         Kohana::$_paths = $paths;
 629 
 630         // Set the current module list
 631         Kohana::$_modules = $modules;
 632         
 633         
 634         
 635 
 636         /** Run Gleez Components */
 637         Gleez::ready();
 638         
 639         
 640         
 641         // 加载每个模块下init.php配置路由文件
 642         foreach (Kohana::$_modules as $path)
 643         {
 644             $init = $path.'init'.EXT;
 645 
 646             if (is_file($init))
 647             {
 648                 // Include the module initialization file once
 649                 require_once $init;
 650             }
 651         }
 652         
 653         
 654     
 655         //@todo better handling instead of init
 656         require_once GLZPATH.'init'.EXT;
 657         
 658         
 659         
 660     
 661         return Kohana::$_modules;
 662     }
 663 
 664     /**
 665      * Returns the the currently active include paths, including the
 666      * application, system, and each module's path.
 667      *
 668      * @return  array
 669      */
 670     public static function include_paths()
 671     {
 672         return Kohana::$_paths;
 673     }
 674 
 675     /**
 676      * Searches for a file in the [Cascading Filesystem](kohana/files), and
 677      * returns the path to the file that has the highest precedence, so that it
 678      * can be included.
 679      *
 680      * When searching the "config", "messages", or "i18n" directories, or when
 681      * the `$array` flag is set to true, an array of all the files that match
 682      * that path in the [Cascading Filesystem](kohana/files) will be returned.
 683      * These files will return arrays which must be merged together.
 684      *
 685      * If no extension is given, the default extension (`EXT` set in
 686      * `index.php`) will be used.
 687      *
 688      *     // Returns an absolute path to views/template.php
 689      *     Kohana::find_file('views', 'template');
 690      *
 691      *     // Returns an absolute path to media/css/style.css
 692      *     Kohana::find_file('media', 'css/style', 'css');
 693      *
 694      *     // Returns an array of all the "mimes" configuration files
 695      *     Kohana::find_file('config', 'mimes');
 696      *
 697      * @param   string  $dir    directory name (views, i18n, classes, extensions, etc.)
 698      * @param   string  $file   filename with subdirectory
 699      * @param   string  $ext    extension to search for
 700      * @param   boolean $array  return an array of files?
 701      * @return  array   a list of files when $array is TRUE
 702      * @return  string  single file path
 703      */
 704     public static function find_file($dir, $file, $ext = NULL, $array = FALSE)
 705     {
 706         if ($ext === NULL)
 707         {
 708             // Use the default extension
 709             $ext = EXT;
 710         }
 711         elseif ($ext)
 712         {
 713             // Prefix the extension with a period
 714             $ext = ".{$ext}";
 715         }
 716         else
 717         {
 718             // Use no extension
 719             $ext = '';
 720         }
 721         
 722         
 723 
 724         // Create a partial path of the filename
 725         $path = $dir.DIRECTORY_SEPARATOR.$file.$ext;
 726         
 727         
 728         
 729 
 730         if (Kohana::$caching === TRUE AND isset(Kohana::$_files[$path.($array ? '_array' : '_path')]))
 731         {
 732             // This path has been cached
 733             return Kohana::$_files[$path.($array ? '_array' : '_path')];
 734         }
 735         
 736         
 737         
 738         
 739         if (Kohana::$profiling === TRUE AND class_exists('Profiler', FALSE))
 740         {
 741             // Start a new benchmark
 742             $benchmark = Profiler::start('Kohana', __FUNCTION__);
 743         }
 744         
 745         
 746         
 747 
 748         if ($array OR $dir === 'config' OR $dir === 'i18n' OR $dir === 'messages')
 749         {
 750             // Include paths must be searched in reverse
 751             $paths = array_reverse(Kohana::$_paths);
 752 
 753             // Array of files that have been found
 754             $found = array();
 755 
 756             foreach ($paths as $dir)
 757             {
 758                 if (is_file($dir.$path))
 759                 {
 760                     // This path has a file, add it to the list
 761                     $found[] = $dir.$path;
 762                 }
 763             }
 764         }
 765         else
 766         {
 767             // The file has not been found yet
 768             $found = FALSE;
 769 
 770             foreach (Kohana::$_paths as $dir)
 771             {
 772                 if (is_file($dir.$path))
 773                 {
 774                     // A path has been found
 775                     $found = $dir.$path;
 776 
 777                     // Stop searching
 778                     break;
 779                 }
 780             }
 781         }
 782         
 783         
 784         
 785         
 786         
 787 
 788         if (Kohana::$caching === TRUE)
 789         {
 790             // Add the path to the cache
 791             Kohana::$_files[$path.($array ? '_array' : '_path')] = $found;
 792 
 793             // Files have been changed
 794             Kohana::$_files_changed = TRUE;
 795         }
 796         
 797         
 798         
 799 
 800         if (isset($benchmark))
 801         {
 802             // Stop the benchmark
 803             Profiler::stop($benchmark);
 804         }
 805 
 806         return $found;
 807     }
 808 
 809     /**
 810      * Recursively finds all of the files in the specified directory at any
 811      * location in the [Cascading Filesystem](kohana/files), and returns an
 812      * array of all the files found, sorted alphabetically.
 813      *
 814      *     // Find all view files.
 815      *     $views = Kohana::list_files('views');
 816      *
 817      * @param   string  $directory  directory name
 818      * @param   array   $paths      list of paths to search
 819      * @return  array
 820      */
 821     public static function list_files($directory = NULL, array $paths = NULL)
 822     {
 823         if ($directory !== NULL)
 824         {
 825             // Add the directory separator
 826             $directory .= DIRECTORY_SEPARATOR;
 827         }
 828         
 829         
 830 
 831         if ($paths === NULL)
 832         {
 833             // Use the default paths
 834             $paths = Kohana::$_paths;
 835         }
 836 
 837 
 838 
 839         // Create an array for the files
 840         $found = array();
 841 
 842         foreach ($paths as $path)
 843         {
 844             if (is_dir($path.$directory))
 845             {
 846                 // Create a new directory iterator
 847                 $dir = new DirectoryIterator($path.$directory);
 848 
 849                 foreach ($dir as $file)
 850                 {
 851                     // Get the file name
 852                     $filename = $file->getFilename();
 853 
 854                     if ($filename[0] === '.' OR $filename[strlen($filename)-1] === '~')
 855                     {
 856                         // Skip all hidden files and UNIX backup files
 857                         continue;
 858                     }
 859 
 860                     // Relative filename is the array key
 861                     $key = $directory.$filename;
 862 
 863                     if ($file->isDir())
 864                     {
 865                         if ($sub_dir = Kohana::list_files($key, $paths))
 866                         {
 867                             if (isset($found[$key]))
 868                             {
 869                                 // Append the sub-directory list
 870                                 $found[$key] += $sub_dir;
 871                             }
 872                             else
 873                             {
 874                                 // Create a new sub-directory list
 875                                 $found[$key] = $sub_dir;
 876                             }
 877                         }
 878                     }
 879                     else
 880                     {
 881                         if ( ! isset($found[$key]))
 882                         {
 883                             // Add new files to the list
 884                             $found[$key] = realpath($file->getPathName());
 885                         }
 886                     }
 887                 }
 888             }
 889         }
 890 
 891         // Sort the results alphabetically
 892         ksort($found);
 893 
 894         return $found;
 895     }
 896 
 897     /**
 898      * Loads a file within a totally empty scope and returns the output:
 899      *
 900      *     $foo = Kohana::load('foo.php');
 901      *
 902      * @param   string  $file
 903      * @return  mixed
 904      */
 905     public static function load($file)
 906     {
 907         return include $file;
 908     }
 909 
 910     /**
 911      * Provides simple file-based caching for strings and arrays:
 912      *
 913      *     // Set the "foo" cache
 914      *     Kohana::cache('foo', 'hello, world');
 915      *
 916      *     // Get the "foo" cache
 917      *     $foo = Kohana::cache('foo');
 918      *
 919      * All caches are stored as PHP code, generated with [var_export][ref-var].
 920      * Caching objects may not work as expected. Storing references or an
 921      * object or array that has recursion will cause an E_FATAL.
 922      *
 923      * The cache directory and default cache lifetime is set by [Kohana::init]
 924      *
 925      * [ref-var]: http://php.net/var_export
 926      *
 927      * @throws  Kohana_Exception
 928      * @param   string  $name       name of the cache
 929      * @param   mixed   $data       data to cache
 930      * @param   integer $lifetime   number of seconds the cache is valid for
 931      * @return  mixed    for getting
 932      * @return  boolean  for setting
 933      */
 934     public static function cache($name, $data = NULL, $lifetime = NULL)
 935     {
 936         // Cache file is a hash of the name
 937         $file = sha1($name).'.txt';
 938         
 939         
 940         // Cache directories are split by keys to prevent filesystem overload
 941         $dir = Kohana::$cache_dir.DIRECTORY_SEPARATOR.    $file[0].$file[1].DIRECTORY_SEPARATOR;
 942         
 943 
 944         if ($lifetime === NULL)
 945         {
 946             // Use the default lifetime
 947             $lifetime = Kohana::$cache_life;
 948         }
 949         
 950         
 951         // 返回
 952         if ($data === NULL)
 953         {
 954             if (is_file($dir.$file))
 955             {
 956                 if ((time() - filemtime($dir.$file)) < $lifetime)
 957                 {
 958                     // Return the cache
 959                     try
 960                     {
 961                         return unserialize(file_get_contents($dir.$file));
 962                     }
 963                     catch (Exception $e)
 964                     {
 965                         // Cache is corrupt, let return happen normally.
 966                     }
 967                 }
 968                 else
 969                 {
 970                     try
 971                     {
 972                         // Cache has expired
 973                         unlink($dir.$file);
 974                     }
 975                     catch (Exception $e)
 976                     {
 977                         // Cache has mostly likely already been deleted,
 978                         // let return happen normally.
 979                     }
 980                 }
 981             }
 982 
 983             // Cache not found
 984             return NULL;
 985         }
 986         
 987         
 988         
 989 
 990         if ( ! is_dir($dir))
 991         {
 992             // Create the cache directory
 993             mkdir($dir, 0777, TRUE);
 994 
 995             // Set permissions (must be manually set to fix umask issues)
 996             chmod($dir, 0777);
 997         }
 998 
 999         // Force the data to be a string
1000         $data = serialize($data);
1001 
1002         try
1003         {
1004             // Write the cache
1005             return (bool) file_put_contents($dir.$file, $data, LOCK_EX);
1006         }
1007         catch (Exception $e)
1008         {
1009             // Failed to write cache
1010             return FALSE;
1011         }
1012     }
1013 
1014     /**
1015      * Get a message from a file. Messages are arbitary strings that are stored
1016      * in the `messages/` directory and reference by a key. Translation is not
1017      * performed on the returned values.  See [message files](kohana/files/messages)
1018      * for more information.
1019      *
1020      *     // Get "username" from messages/text.php
1021      *     $username = Kohana::message('text', 'username');
1022      *
1023      * @param   string  $file       file name
1024      * @param   string  $path       key path to get
1025      * @param   mixed   $default    default value if the path does not exist
1026      * @return  string  message string for the given path
1027      * @return  array   complete message list, when no path is specified
1028      * @uses    Arr::merge
1029      * @uses    Arr::path
1030      */
1031     public static function message($file, $path = NULL, $default = NULL)
1032     {
1033         static $messages;
1034 
1035         if ( ! isset($messages[$file]))
1036         {
1037             // Create a new message list
1038             $messages[$file] = array();
1039 
1040             if ($files = Kohana::find_file('messages', $file))
1041             {
1042                 foreach ($files as $f)
1043                 {
1044                     // Combine all the messages recursively
1045                     $messages[$file] = Arr::merge($messages[$file], Kohana::load($f));
1046                 }
1047             }
1048         }
1049 
1050         if ($path === NULL)
1051         {
1052             // Return all of the messages
1053             return $messages[$file];
1054         }
1055         else
1056         {
1057             // Get a message using the path
1058             return Arr::path($messages[$file], $path, $default);
1059         }
1060     }
1061 
1062     /**
1063      * PHP error handler, converts all errors into ErrorExceptions. This handler
1064      * respects error_reporting settings.
1065      *
1066      * @throws  ErrorException
1067      * @return  TRUE
1068      */
1069     public static function error_handler($code, $error, $file = NULL, $line = NULL)
1070     {
1071         if (error_reporting() & $code)
1072         {
1073             // This error is not suppressed by current error reporting settings
1074             // Convert the error into an ErrorException
1075             throw new ErrorException($error, $code, 0, $file, $line);
1076         }
1077 
1078         // Do not execute the PHP error handler
1079         return TRUE;
1080     }
1081 
1082     /**
1083      * Catches errors that are not caught by the error handler, such as E_PARSE.
1084      *
1085      * @uses    Kohana_Exception::handler
1086      * @return  void
1087      */
1088     public static function shutdown_handler()
1089     {
1090         if ( ! Kohana::$_init)
1091         {
1092             // Do not execute when not active
1093             return;
1094         }
1095 
1096         try
1097         {
1098             if (Kohana::$caching === TRUE AND Kohana::$_files_changed === TRUE)
1099             {
1100                 // Write the file path cache
1101                 Kohana::cache('Kohana::find_file()', Kohana::$_files);
1102             }
1103         }
1104         catch (Exception $e)
1105         {
1106             // Pass the exception to the handler
1107             Kohana_Exception::handler($e);
1108         }
1109 
1110         if (Kohana::$errors AND $error = error_get_last() AND in_array($error['type'], Kohana::$shutdown_errors))
1111         {
1112             // Clean the output buffer
1113             ob_get_level() and ob_clean();
1114 
1115             // Fake an exception for nice debugging
1116             Kohana_Exception::handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
1117 
1118             // Shutdown now to avoid a "death loop"
1119             exit(1);
1120         }
1121     }
1122 
1123 } // End Kohana
1124 
1125 if ( ! function_exists('__'))
1126 {
1127     /**
1128      * Translate strings to the page language or a given language
1129      *
1130      * The PHP function [strtr](http://php.net/strtr) is used for replacing parameters.
1131      * <code>
1132      *  __('Welcome back, :user', array(':user' => $username));
1133      * </code>
1134      *
1135      * [!!] The target language is defined by [I18n::$lang].
1136      *
1137      * @param   string  $string Text to translate
1138      * @param   array   $values Values to replace in the translated text. [Optional]
1139      *                          An associative array of replacements to make after translation.
1140      *                          Incidences of any key in this array are replaced with the corresponding value.
1141      *                          Based on the first character of the key, the value is escaped and/or themed:
1142      *                          - !variable: inserted as is
1143      *                          - :variable: inserted as is
1144      *                          - @variable: escape plain text to HTML (HTML::chars)
1145      *                          - %variable: escape text and theme as a placeholder for user-submitted
1146      *                          - ^variable: escape text and uppercase the first character of each word in a string
1147      *                          - ~variable: escape text and make a string's first character uppercase
1148      *                          content (HTML::chars + theme_placeholder)
1149      * @param   string  $lang   Source language [Optional]
1150      * @return  string
1151      *
1152      * @uses    I18n::get
1153      * @uses    HTML::chars
1154      */
1155     function __($string, array $values = NULL, $lang = 'en-us')
1156     {
1157         if ($lang !== I18n::$lang)
1158         {
1159             // The message and target languages are different
1160             // Get the translation for this message
1161             $string = I18n::get($string);
1162         }
1163 
1164         if (empty($values))
1165         {
1166             return $string;
1167         }
1168         else
1169         {
1170             // Transform arguments before inserting them.
1171             foreach ($values as $key => $value)
1172             {
1173                 switch ($key[0])
1174                 {
1175                     case '@':
1176                         // Escaped only
1177                         $values[$key] = HTML::chars($value);
1178                     break;
1179                     case '%':
1180                         // Escaped and placeholder
1181                         $values[$key] = '<em class="placeholder">' . HTML::chars($value) . '</em>';
1182                     break;
1183                     case '^':
1184                         // Escaped and uppercase the first character of each word in a string
1185                         $values[$key] = ucwords(HTML::chars($value));
1186                     break;
1187                     case '~':
1188                         // Escaped and make a string's first character uppercase
1189                         $values[$key] = ucfirst(HTML::chars($value));
1190                     break;
1191                     case '!':
1192                     case ':':
1193                     default:
1194                         // Pass-through
1195                 }
1196             }
1197         }
1198 
1199         return strtr($string, $values);
1200     }
1201 }
1202 
1203 function __n($count, $singular, $plural, array $values = array(), $lang = 'en-us')
1204 {
1205     if ($lang !== I18n::$lang)
1206     {
1207         $string = $count === 1 ? I18n::get($singular) : Gleez_I18n::get_plural($plural, $count);
1208     }
1209     else
1210         $string = $count === 1 ? $singular : $plural;
1211 
1212     return strtr($string, array_merge($values, array('%count' => $count)));
1213 }

 

转载于:https://www.cnblogs.com/1406425891-z/archive/2013/05/30/3109166.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值