• system\classes\Kohana\Core.php 核心文件


    View Code
       1 <?php defined('SYSPATH') OR die('No direct script access.');
       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    Kohana
      11  * @category   Base
      12  * @author     Kohana Team
      13  * @copyright  (c) 2008-2012 Kohana Team
      14  * @license    http://kohanaframework.org/license
      15  */
      16 class Kohana_Core {
      17 
      18     // Release version and codename
      19     const VERSION  = '3.3.0';
      20     const CODENAME = 'badius';
      21 
      22     // Common environment type constants for consistency and convenience
      23     const PRODUCTION  = 10;
      24     const STAGING     = 20;
      25     const TESTING     = 30;
      26     const DEVELOPMENT = 40;
      27 
      28     // Security check that is added to all generated PHP files
      29     const FILE_SECURITY = '<?php defined(\'SYSPATH\') OR die(\'No direct script access.\');';
      30 
      31     // Format of cache files: header, cache name, and data
      32     const FILE_CACHE = ":header \n\n// :name\n\n:data\n";
      33 
      34     /**
      35      * @var  string  Current environment name
      36      */
      37     public static $environment = Kohana::DEVELOPMENT;
      38 
      39     /**
      40      * @var  boolean  True if Kohana is running on windows
      41      */
      42     public static $is_windows = FALSE;
      43 
      44     /**
      45      * @var  boolean  True if [magic quotes](http://php.net/manual/en/security.magicquotes.php) is enabled.
      46      */
      47     public static $magic_quotes = FALSE;
      48 
      49     /**
      50      * @var  boolean  TRUE if PHP safe mode is on
      51      */
      52     public static $safe_mode = FALSE;
      53 
      54     /**
      55      * @var  string
      56      */
      57     public static $content_type = 'text/html';
      58 
      59     /**
      60      * @var  string  character set of input and output
      61      */
      62     public static $charset = 'utf-8';
      63 
      64     /**
      65      * @var  string  the name of the server Kohana is hosted upon
      66      */
      67     public static $server_name = '';
      68 
      69     /**
      70      * @var  array   list of valid host names for this instance
      71      */
      72     public static $hostnames = array();
      73 
      74     /**
      75      * @var  string  base URL to the application
      76      */
      77     public static $base_url = '/';
      78 
      79     /**
      80      * @var  string  Application index file, added to links generated by Kohana. Set by [Kohana::init]
      81      */
      82     public static $index_file = 'index.php';
      83 
      84     /**
      85      * @var  string  Cache directory, used by [Kohana::cache]. Set by [Kohana::init]
      86      */
      87     public static $cache_dir;
      88 
      89     /**
      90      * @var  integer  Default lifetime for caching, in seconds, used by [Kohana::cache]. Set by [Kohana::init]
      91      */
      92     public static $cache_life = 60;
      93 
      94     /**
      95      * @var  boolean  Whether to use internal caching for [Kohana::find_file], does not apply to [Kohana::cache]. Set by [Kohana::init]
      96      */
      97     public static $caching = FALSE;
      98 
      99     /**
     100      * @var  boolean  Whether to enable [profiling](kohana/profiling). Set by [Kohana::init]
     101      */
     102     public static $profiling = TRUE;
     103 
     104     /**
     105      * @var  boolean  Enable Kohana catching and displaying PHP errors and exceptions. Set by [Kohana::init]
     106      */
     107     public static $errors = TRUE;
     108 
     109     /**
     110      * @var  array  Types of errors to display at shutdown
     111      */
     112     public static $shutdown_errors = array(E_PARSE, E_ERROR, E_USER_ERROR);
     113 
     114     /**
     115      * @var  boolean  set the X-Powered-By header
     116      */
     117     public static $expose = FALSE;
     118 
     119     /**
     120      * @var  Log  logging object
     121      */
     122     public static $log;
     123 
     124     /**
     125      * @var  Config  config object
     126      */
     127     public static $config;
     128 
     129     /**
     130      * @var  boolean  Has [Kohana::init] been called?
     131      */
     132     protected static $_init = FALSE;
     133 
     134     /**
     135      * @var  array   Currently active modules
     136      */
     137     protected static $_modules = array();
     138 
     139     /**
     140      * @var  array   Include paths that are used to find files
     141      */
     142     protected static $_paths = array(APPPATH, SYSPATH);
     143 
     144     /**
     145      * @var  array   File path cache, used when caching is true in [Kohana::init]
     146      */
     147     protected static $_files = array();
     148 
     149     /**
     150      * @var  boolean  Has the file path cache changed during this execution?  Used internally when when caching is true in [Kohana::init]
     151      */
     152     protected static $_files_changed = FALSE;
     153 
     154     /**
     155      * Initializes the environment:
     156      *
     157      * - Disables register_globals and magic_quotes_gpc
     158      * - Determines the current environment
     159      * - Set global settings
     160      * - Sanitizes GET, POST, and COOKIE variables
     161      * - Converts GET, POST, and COOKIE variables to the global character set
     162      *
     163      * The following settings can be set:
     164      *
     165      * Type      | Setting    | Description                                    | Default Value
     166      * ----------|------------|------------------------------------------------|---------------
     167      * `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.   | `"/"`
     168      * `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"`
     169      * `string`  | charset    | Character set used for all input and output    | `"utf-8"`
     170      * `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"`
     171      * `integer` | cache_life | Lifetime, in seconds, of items cached by [Kohana::cache]         | `60`
     172      * `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`
     173      * `boolean` | profile    | Whether to enable the [Profiler](kohana/profiling). <br /> <br />Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE`
     174      * `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`
     175      * `boolean` | expose     | Set the X-Powered-By header
     176      *
     177      * @throws  Kohana_Exception
     178      * @param   array   $settings   Array of settings.  See above.
     179      * @return  void
     180      * @uses    Kohana::globals
     181      * @uses    Kohana::sanitize
     182      * @uses    Kohana::cache
     183      * @uses    Profiler
     184      */
     185     public static function init(array $settings = NULL)
     186     {
     187         if (Kohana::$_init)
     188         {
     189             // Do not allow execution twice
     190             return;
     191         }
     192 
     193         // Kohana is now initialized
     194         Kohana::$_init = TRUE;
     195 
     196         if (isset($settings['profile']))
     197         {
     198             // Enable profiling
     199             Kohana::$profiling = (bool) $settings['profile'];
     200         }
     201 
     202         // Start an output buffer
     203         ob_start();
     204 
     205         if (isset($settings['errors']))
     206         {
     207             // Enable error handling
     208             Kohana::$errors = (bool) $settings['errors'];
     209         }
     210 
     211         if (Kohana::$errors === TRUE)
     212         {
     213             // Enable Kohana exception handling, adds stack traces and error source.
     214             set_exception_handler(array('Kohana_Exception', 'handler'));
     215 
     216             // Enable Kohana error handling, converts all PHP errors to exceptions.
     217             set_error_handler(array('Kohana', 'error_handler'));
     218         }
     219 
     220         /**
     221          * Enable xdebug parameter collection in development mode to improve fatal stack traces.
     222          */
     223         if (Kohana::$environment == Kohana::DEVELOPMENT AND extension_loaded('xdebug'))
     224         {
     225             ini_set('xdebug.collect_params', 3);
     226         }
     227 
     228         // Enable the Kohana shutdown handler, which catches E_FATAL errors.
     229         register_shutdown_function(array('Kohana', 'shutdown_handler'));
     230 
     231         if (ini_get('register_globals'))
     232         {
     233             // Reverse the effects of register_globals
     234             Kohana::globals();
     235         }
     236 
     237         if (isset($settings['expose']))
     238         {
     239             Kohana::$expose = (bool) $settings['expose'];
     240         }
     241 
     242         // Determine if we are running in a Windows environment
     243         Kohana::$is_windows = (DIRECTORY_SEPARATOR === '\\');
     244 
     245         // Determine if we are running in safe mode
     246         Kohana::$safe_mode = (bool) ini_get('safe_mode');
     247 
     248         if (isset($settings['cache_dir']))
     249         {
     250             if ( ! is_dir($settings['cache_dir']))
     251             {
     252                 try
     253                 {
     254                     // Create the cache directory
     255                     mkdir($settings['cache_dir'], 0755, TRUE);
     256 
     257                     // Set permissions (must be manually set to fix umask issues)
     258                     chmod($settings['cache_dir'], 0755);
     259                 }
     260                 catch (Exception $e)
     261                 {
     262                     throw new Kohana_Exception('Could not create cache directory :dir',
     263                         array(':dir' => Debug::path($settings['cache_dir'])));
     264                 }
     265             }
     266 
     267             // Set the cache directory path
     268             Kohana::$cache_dir = realpath($settings['cache_dir']);
     269         }
     270         else
     271         {
     272             // Use the default cache directory
     273             Kohana::$cache_dir = APPPATH.'cache';
     274         }
     275 
     276         if ( ! is_writable(Kohana::$cache_dir))
     277         {
     278             throw new Kohana_Exception('Directory :dir must be writable',
     279                 array(':dir' => Debug::path(Kohana::$cache_dir)));
     280         }
     281 
     282         if (isset($settings['cache_life']))
     283         {
     284             // Set the default cache lifetime
     285             Kohana::$cache_life = (int) $settings['cache_life'];
     286         }
     287 
     288         if (isset($settings['caching']))
     289         {
     290             // Enable or disable internal caching
     291             Kohana::$caching = (bool) $settings['caching'];
     292         }
     293 
     294         if (Kohana::$caching === TRUE)
     295         {
     296             // Load the file path cache
     297             Kohana::$_files = Kohana::cache('Kohana::find_file()');
     298         }
     299 
     300         if (isset($settings['charset']))
     301         {
     302             // Set the system character set
     303             Kohana::$charset = strtolower($settings['charset']);
     304         }
     305 
     306         if (function_exists('mb_internal_encoding'))
     307         {
     308             // Set the MB extension encoding to the same character set
     309             mb_internal_encoding(Kohana::$charset);
     310         }
     311 
     312         if (isset($settings['base_url']))
     313         {
     314             // Set the base URL
     315             Kohana::$base_url = rtrim($settings['base_url'], '/').'/';
     316         }
     317 
     318         if (isset($settings['index_file']))
     319         {
     320             // Set the index file
     321             Kohana::$index_file = trim($settings['index_file'], '/');
     322         }
     323 
     324         // Determine if the extremely evil magic quotes are enabled
     325         Kohana::$magic_quotes = (version_compare(PHP_VERSION, '5.4') < 0 AND get_magic_quotes_gpc());
     326 
     327         // Sanitize all request variables
     328         $_GET    = Kohana::sanitize($_GET);
     329         $_POST   = Kohana::sanitize($_POST);
     330         $_COOKIE = Kohana::sanitize($_COOKIE);
     331 
     332         // Load the logger if one doesn't already exist
     333         if ( ! Kohana::$log instanceof Log)
     334         {
     335             Kohana::$log = Log::instance();
     336         }
     337 
     338         // Load the config if one doesn't already exist
     339         if ( ! Kohana::$config instanceof Config)
     340         {
     341             Kohana::$config = new Config;
     342         }
     343     }
     344 
     345     /**
     346      * Cleans up the environment:
     347      *
     348      * - Restore the previous error and exception handlers
     349      * - Destroy the Kohana::$log and Kohana::$config objects
     350      *
     351      * @return  void
     352      */
     353     public static function deinit()
     354     {
     355         if (Kohana::$_init)
     356         {
     357             // Removed the autoloader
     358             spl_autoload_unregister(array('Kohana', 'auto_load'));
     359 
     360             if (Kohana::$errors)
     361             {
     362                 // Go back to the previous error handler
     363                 restore_error_handler();
     364 
     365                 // Go back to the previous exception handler
     366                 restore_exception_handler();
     367             }
     368 
     369             // Destroy objects created by init
     370             Kohana::$log = Kohana::$config = NULL;
     371 
     372             // Reset internal storage
     373             Kohana::$_modules = Kohana::$_files = array();
     374             Kohana::$_paths   = array(APPPATH, SYSPATH);
     375 
     376             // Reset file cache status
     377             Kohana::$_files_changed = FALSE;
     378 
     379             // Kohana is no longer initialized
     380             Kohana::$_init = FALSE;
     381         }
     382     }
     383 
     384     /**
     385      * Reverts the effects of the `register_globals` PHP setting by unsetting
     386      * all global varibles except for the default super globals (GPCS, etc),
     387      * which is a [potential security hole.][ref-wikibooks]
     388      *
     389      * This is called automatically by [Kohana::init] if `register_globals` is
     390      * on.
     391      *
     392      *
     393      * [ref-wikibooks]: http://en.wikibooks.org/wiki/PHP_Programming/Register_Globals
     394      *
     395      * @return  void
     396      */
     397     public static function globals()
     398     {
     399         if (isset($_REQUEST['GLOBALS']) OR isset($_FILES['GLOBALS']))
     400         {
     401             // Prevent malicious GLOBALS overload attack
     402             echo "Global variable overload attack detected! Request aborted.\n";
     403 
     404             // Exit with an error status
     405             exit(1);
     406         }
     407 
     408         // Get the variable names of all globals
     409         $global_variables = array_keys($GLOBALS);
     410 
     411         // Remove the standard global variables from the list
     412         $global_variables = array_diff($global_variables, array(
     413             '_COOKIE',
     414             '_ENV',
     415             '_GET',
     416             '_FILES',
     417             '_POST',
     418             '_REQUEST',
     419             '_SERVER',
     420             '_SESSION',
     421             'GLOBALS',
     422         ));
     423 
     424         foreach ($global_variables as $name)
     425         {
     426             // Unset the global variable, effectively disabling register_globals
     427             unset($GLOBALS[$name]);
     428         }
     429     }
     430 
     431     /**
     432      * Recursively sanitizes an input variable:
     433      *
     434      * - Strips slashes if magic quotes are enabled
     435      * - Normalizes all newlines to LF
     436      *
     437      * @param   mixed   $value  any variable
     438      * @return  mixed   sanitized variable
     439      */
     440     public static function sanitize($value)
     441     {
     442         if (is_array($value) OR is_object($value))
     443         {
     444             foreach ($value as $key => $val)
     445             {
     446                 // Recursively clean each value
     447                 $value[$key] = Kohana::sanitize($val);
     448             }
     449         }
     450         elseif (is_string($value))
     451         {
     452             if (Kohana::$magic_quotes === TRUE)
     453             {
     454                 // Remove slashes added by magic quotes
     455                 $value = stripslashes($value);
     456             }
     457 
     458             if (strpos($value, "\r") !== FALSE)
     459             {
     460                 // Standardize newlines
     461                 $value = str_replace(array("\r\n", "\r"), "\n", $value);
     462             }
     463         }
     464 
     465         return $value;
     466     }
     467 
     468     /**
     469      * Provides auto-loading support of classes that follow Kohana's [class
     470      * naming conventions](kohana/conventions#class-names-and-file-location).
     471      * See [Loading Classes](kohana/autoloading) for more information.
     472      *
     473      *     // Loads classes/My/Class/Name.php
     474      *     Kohana::auto_load('My_Class_Name');
     475      *
     476      * or with a custom directory:
     477      *
     478      *     // Loads vendor/My/Class/Name.php
     479      *     Kohana::auto_load('My_Class_Name', 'vendor');
     480      *
     481      * You should never have to call this function, as simply calling a class
     482      * will cause it to be called.
     483      *
     484      * This function must be enabled as an autoloader in the bootstrap:
     485      *
     486      *     spl_autoload_register(array('Kohana', 'auto_load'));
     487      *
     488      * @param   string  $class      Class name
     489      * @param   string  $directory  Directory to load from
     490      * @return  boolean
     491      */
     492     public static function auto_load($class, $directory = 'classes')
     493     {
     494         // Transform the class name according to PSR-0
     495         $class     = ltrim($class, '\\');
     496         $file      = '';
     497         $namespace = '';
     498 
     499         if ($last_namespace_position = strripos($class, '\\'))
     500         {
     501             $namespace = substr($class, 0, $last_namespace_position);
     502             $class     = substr($class, $last_namespace_position + 1);
     503             $file      = str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR;
     504         }
     505 
     506         $file .= str_replace('_', DIRECTORY_SEPARATOR, $class);
     507 
     508         if ($path = Kohana::find_file($directory, $file))
     509         {
     510             // Load the class file
     511             require $path;
     512 
     513             // Class has been found
     514             return TRUE;
     515         }
     516 
     517         // Class is not in the filesystem
     518         return FALSE;
     519     }
     520 
     521     /**
     522      * Provides auto-loading support of classes that follow Kohana's old class
     523      * naming conventions.
     524      * 
     525      * This is included for compatibility purposes with older modules.
     526      *
     527      * @param   string  $class      Class name
     528      * @param   string  $directory  Directory to load from
     529      * @return  boolean
     530      */
     531     public static function auto_load_lowercase($class, $directory = 'classes')
     532     {
     533         // Transform the class name into a path
     534         $file = str_replace('_', DIRECTORY_SEPARATOR, strtolower($class));
     535 
     536         if ($path = Kohana::find_file($directory, $file))
     537         {
     538             // Load the class file
     539             require $path;
     540 
     541             // Class has been found
     542             return TRUE;
     543         }
     544 
     545         // Class is not in the filesystem
     546         return FALSE;
     547     }
     548 
     549     /**
     550      * Changes the currently enabled modules. Module paths may be relative
     551      * or absolute, but must point to a directory:
     552      *
     553      *     Kohana::modules(array('modules/foo', MODPATH.'bar'));
     554      *
     555      * @param   array   $modules    list of module paths
     556      * @return  array   enabled modules
     557      */
     558     public static function modules(array $modules = NULL)
     559     {
     560         if ($modules === NULL)
     561         {
     562             // Not changing modules, just return the current set
     563             return Kohana::$_modules;
     564         }
     565 
     566         // Start a new list of include paths, APPPATH first
     567         $paths = array(APPPATH);
     568 
     569         foreach ($modules as $name => $path)
     570         {
     571             if (is_dir($path))
     572             {
     573                 // Add the module to include paths
     574                 $paths[] = $modules[$name] = realpath($path).DIRECTORY_SEPARATOR;
     575             }
     576             else
     577             {
     578                 // This module is invalid, remove it
     579                 throw new Kohana_Exception('Attempted to load an invalid or missing module \':module\' at \':path\'', array(
     580                     ':module' => $name,
     581                     ':path'   => Debug::path($path),
     582                 ));
     583             }
     584         }
     585 
     586         // Finish the include paths by adding SYSPATH
     587         $paths[] = SYSPATH;
     588 
     589         // Set the new include paths
     590         Kohana::$_paths = $paths;
     591 
     592         // Set the current module list
     593         Kohana::$_modules = $modules;
     594 
     595         foreach (Kohana::$_modules as $path)
     596         {
     597             $init = $path.'init'.EXT;
     598 
     599             if (is_file($init))
     600             {
     601                 // Include the module initialization file once
     602                 require_once $init;
     603             }
     604         }
     605 
     606         return Kohana::$_modules;
     607     }
     608 
     609     /**
     610      * Returns the the currently active include paths, including the
     611      * application, system, and each module's path.
     612      *
     613      * @return  array
     614      */
     615     public static function include_paths()
     616     {
     617         return Kohana::$_paths;
     618     }
     619 
     620     /**
     621      * Searches for a file in the [Cascading Filesystem](kohana/files), and
     622      * returns the path to the file that has the highest precedence, so that it
     623      * can be included.
     624      *
     625      * When searching the "config", "messages", or "i18n" directories, or when
     626      * the `$array` flag is set to true, an array of all the files that match
     627      * that path in the [Cascading Filesystem](kohana/files) will be returned.
     628      * These files will return arrays which must be merged together.
     629      *
     630      * If no extension is given, the default extension (`EXT` set in
     631      * `index.php`) will be used.
     632      *
     633      *     // Returns an absolute path to views/template.php
     634      *     Kohana::find_file('views', 'template');
     635      *
     636      *     // Returns an absolute path to media/css/style.css
     637      *     Kohana::find_file('media', 'css/style', 'css');
     638      *
     639      *     // Returns an array of all the "mimes" configuration files
     640      *     Kohana::find_file('config', 'mimes');
     641      *
     642      * @param   string  $dir    directory name (views, i18n, classes, extensions, etc.)
     643      * @param   string  $file   filename with subdirectory
     644      * @param   string  $ext    extension to search for
     645      * @param   boolean $array  return an array of files?
     646      * @return  array   a list of files when $array is TRUE
     647      * @return  string  single file path
     648      */
     649     public static function find_file($dir, $file, $ext = NULL, $array = FALSE)
     650     {
     651         if ($ext === NULL)
     652         {
     653             // Use the default extension
     654             $ext = EXT;
     655         }
     656         elseif ($ext)
     657         {
     658             // Prefix the extension with a period
     659             $ext = ".{$ext}";
     660         }
     661         else
     662         {
     663             // Use no extension
     664             $ext = '';
     665         }
     666 
     667         // Create a partial path of the filename
     668         $path = $dir.DIRECTORY_SEPARATOR.$file.$ext;
     669 
     670         if (Kohana::$caching === TRUE AND isset(Kohana::$_files[$path.($array ? '_array' : '_path')]))
     671         {
     672             // This path has been cached
     673             return Kohana::$_files[$path.($array ? '_array' : '_path')];
     674         }
     675 
     676         if (Kohana::$profiling === TRUE AND class_exists('Profiler', FALSE))
     677         {
     678             // Start a new benchmark
     679             $benchmark = Profiler::start('Kohana', __FUNCTION__);
     680         }
     681 
     682         if ($array OR $dir === 'config' OR $dir === 'i18n' OR $dir === 'messages')
     683         {
     684             // Include paths must be searched in reverse
     685             $paths = array_reverse(Kohana::$_paths);
     686 
     687             // Array of files that have been found
     688             $found = array();
     689 
     690             foreach ($paths as $dir)
     691             {
     692                 if (is_file($dir.$path))
     693                 {
     694                     // This path has a file, add it to the list
     695                     $found[] = $dir.$path;
     696                 }
     697             }
     698         }
     699         else
     700         {
     701             // The file has not been found yet
     702             $found = FALSE;
     703 
     704             foreach (Kohana::$_paths as $dir)
     705             {
     706                 if (is_file($dir.$path))
     707                 {
     708                     // A path has been found
     709                     $found = $dir.$path;
     710 
     711                     // Stop searching
     712                     break;
     713                 }
     714             }
     715         }
     716 
     717         if (Kohana::$caching === TRUE)
     718         {
     719             // Add the path to the cache
     720             Kohana::$_files[$path.($array ? '_array' : '_path')] = $found;
     721 
     722             // Files have been changed
     723             Kohana::$_files_changed = TRUE;
     724         }
     725 
     726         if (isset($benchmark))
     727         {
     728             // Stop the benchmark
     729             Profiler::stop($benchmark);
     730         }
     731 
     732         return $found;
     733     }
     734 
     735     /**
     736      * Recursively finds all of the files in the specified directory at any
     737      * location in the [Cascading Filesystem](kohana/files), and returns an
     738      * array of all the files found, sorted alphabetically.
     739      *
     740      *     // Find all view files.
     741      *     $views = Kohana::list_files('views');
     742      *
     743      * @param   string  $directory  directory name
     744      * @param   array   $paths      list of paths to search
     745      * @return  array
     746      */
     747     public static function list_files($directory = NULL, array $paths = NULL)
     748     {
     749         if ($directory !== NULL)
     750         {
     751             // Add the directory separator
     752             $directory .= DIRECTORY_SEPARATOR;
     753         }
     754 
     755         if ($paths === NULL)
     756         {
     757             // Use the default paths
     758             $paths = Kohana::$_paths;
     759         }
     760 
     761         // Create an array for the files
     762         $found = array();
     763 
     764         foreach ($paths as $path)
     765         {
     766             if (is_dir($path.$directory))
     767             {
     768                 // Create a new directory iterator
     769                 $dir = new DirectoryIterator($path.$directory);
     770 
     771                 foreach ($dir as $file)
     772                 {
     773                     // Get the file name
     774                     $filename = $file->getFilename();
     775 
     776                     if ($filename[0] === '.' OR $filename[strlen($filename)-1] === '~')
     777                     {
     778                         // Skip all hidden files and UNIX backup files
     779                         continue;
     780                     }
     781 
     782                     // Relative filename is the array key
     783                     $key = $directory.$filename;
     784 
     785                     if ($file->isDir())
     786                     {
     787                         if ($sub_dir = Kohana::list_files($key, $paths))
     788                         {
     789                             if (isset($found[$key]))
     790                             {
     791                                 // Append the sub-directory list
     792                                 $found[$key] += $sub_dir;
     793                             }
     794                             else
     795                             {
     796                                 // Create a new sub-directory list
     797                                 $found[$key] = $sub_dir;
     798                             }
     799                         }
     800                     }
     801                     else
     802                     {
     803                         if ( ! isset($found[$key]))
     804                         {
     805                             // Add new files to the list
     806                             $found[$key] = realpath($file->getPathName());
     807                         }
     808                     }
     809                 }
     810             }
     811         }
     812 
     813         // Sort the results alphabetically
     814         ksort($found);
     815 
     816         return $found;
     817     }
     818 
     819     /**
     820      * Loads a file within a totally empty scope and returns the output:
     821      *
     822      *     $foo = Kohana::load('foo.php');
     823      *
     824      * @param   string  $file
     825      * @return  mixed
     826      */
     827     public static function load($file)
     828     {
     829         return include $file;
     830     }
     831 
     832     /**
     833      * Provides simple file-based caching for strings and arrays:
     834      *
     835      *     // Set the "foo" cache
     836      *     Kohana::cache('foo', 'hello, world');
     837      *
     838      *     // Get the "foo" cache
     839      *     $foo = Kohana::cache('foo');
     840      *
     841      * All caches are stored as PHP code, generated with [var_export][ref-var].
     842      * Caching objects may not work as expected. Storing references or an
     843      * object or array that has recursion will cause an E_FATAL.
     844      *
     845      * The cache directory and default cache lifetime is set by [Kohana::init]
     846      *
     847      * [ref-var]: http://php.net/var_export
     848      *
     849      * @throws  Kohana_Exception
     850      * @param   string  $name       name of the cache
     851      * @param   mixed   $data       data to cache
     852      * @param   integer $lifetime   number of seconds the cache is valid for
     853      * @return  mixed    for getting
     854      * @return  boolean  for setting
     855      */
     856     public static function cache($name, $data = NULL, $lifetime = NULL)
     857     {
     858         // Cache file is a hash of the name
     859         $file = sha1($name).'.txt';
     860 
     861         // Cache directories are split by keys to prevent filesystem overload
     862         $dir = Kohana::$cache_dir.DIRECTORY_SEPARATOR.$file[0].$file[1].DIRECTORY_SEPARATOR;
     863 
     864         if ($lifetime === NULL)
     865         {
     866             // Use the default lifetime
     867             $lifetime = Kohana::$cache_life;
     868         }
     869 
     870         if ($data === NULL)
     871         {
     872             if (is_file($dir.$file))
     873             {
     874                 if ((time() - filemtime($dir.$file)) < $lifetime)
     875                 {
     876                     // Return the cache
     877                     try
     878                     {
     879                         return unserialize(file_get_contents($dir.$file));
     880                     }
     881                     catch (Exception $e)
     882                     {
     883                         // Cache is corrupt, let return happen normally.
     884                     }
     885                 }
     886                 else
     887                 {
     888                     try
     889                     {
     890                         // Cache has expired
     891                         unlink($dir.$file);
     892                     }
     893                     catch (Exception $e)
     894                     {
     895                         // Cache has mostly likely already been deleted,
     896                         // let return happen normally.
     897                     }
     898                 }
     899             }
     900 
     901             // Cache not found
     902             return NULL;
     903         }
     904 
     905         if ( ! is_dir($dir))
     906         {
     907             // Create the cache directory
     908             mkdir($dir, 0777, TRUE);
     909 
     910             // Set permissions (must be manually set to fix umask issues)
     911             chmod($dir, 0777);
     912         }
     913 
     914         // Force the data to be a string
     915         $data = serialize($data);
     916 
     917         try
     918         {
     919             // Write the cache
     920             return (bool) file_put_contents($dir.$file, $data, LOCK_EX);
     921         }
     922         catch (Exception $e)
     923         {
     924             // Failed to write cache
     925             return FALSE;
     926         }
     927     }
     928 
     929     /**
     930      * Get a message from a file. Messages are arbitary strings that are stored
     931      * in the `messages/` directory and reference by a key. Translation is not
     932      * performed on the returned values.  See [message files](kohana/files/messages)
     933      * for more information.
     934      *
     935      *     // Get "username" from messages/text.php
     936      *     $username = Kohana::message('text', 'username');
     937      *
     938      * @param   string  $file       file name
     939      * @param   string  $path       key path to get
     940      * @param   mixed   $default    default value if the path does not exist
     941      * @return  string  message string for the given path
     942      * @return  array   complete message list, when no path is specified
     943      * @uses    Arr::merge
     944      * @uses    Arr::path
     945      */
     946     public static function message($file, $path = NULL, $default = NULL)
     947     {
     948         static $messages;
     949 
     950         if ( ! isset($messages[$file]))
     951         {
     952             // Create a new message list
     953             $messages[$file] = array();
     954 
     955             if ($files = Kohana::find_file('messages', $file))
     956             {
     957                 foreach ($files as $f)
     958                 {
     959                     // Combine all the messages recursively
     960                     $messages[$file] = Arr::merge($messages[$file], Kohana::load($f));
     961                 }
     962             }
     963         }
     964 
     965         if ($path === NULL)
     966         {
     967             // Return all of the messages
     968             return $messages[$file];
     969         }
     970         else
     971         {
     972             // Get a message using the path
     973             return Arr::path($messages[$file], $path, $default);
     974         }
     975     }
     976 
     977     /**
     978      * PHP error handler, converts all errors into ErrorExceptions. This handler
     979      * respects error_reporting settings.
     980      *
     981      * @throws  ErrorException
     982      * @return  TRUE
     983      */
     984     public static function error_handler($code, $error, $file = NULL, $line = NULL)
     985     {
     986         if (error_reporting() & $code)
     987         {
     988             // This error is not suppressed by current error reporting settings
     989             // Convert the error into an ErrorException
     990             throw new ErrorException($error, $code, 0, $file, $line);
     991         }
     992 
     993         // Do not execute the PHP error handler
     994         return TRUE;
     995     }
     996 
     997     /**
     998      * Catches errors that are not caught by the error handler, such as E_PARSE.
     999      *
    1000      * @uses    Kohana_Exception::handler
    1001      * @return  void
    1002      */
    1003     public static function shutdown_handler()
    1004     {
    1005         if ( ! Kohana::$_init)
    1006         {
    1007             // Do not execute when not active
    1008             return;
    1009         }
    1010 
    1011         try
    1012         {
    1013             if (Kohana::$caching === TRUE AND Kohana::$_files_changed === TRUE)
    1014             {
    1015                 // Write the file path cache
    1016                 Kohana::cache('Kohana::find_file()', Kohana::$_files);
    1017             }
    1018         }
    1019         catch (Exception $e)
    1020         {
    1021             // Pass the exception to the handler
    1022             Kohana_Exception::handler($e);
    1023         }
    1024 
    1025         if (Kohana::$errors AND $error = error_get_last() AND in_array($error['type'], Kohana::$shutdown_errors))
    1026         {
    1027             // Clean the output buffer
    1028             ob_get_level() AND ob_clean();
    1029 
    1030             // Fake an exception for nice debugging
    1031             Kohana_Exception::handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
    1032 
    1033             // Shutdown now to avoid a "death loop"
    1034             exit(1);
    1035         }
    1036     }
    1037 
    1038     /**
    1039      * Generates a version string based on the variables defined above.
    1040      * 
    1041      * @return string
    1042      */
    1043     public static function version()
    1044     {
    1045         return 'Kohana Framework '.Kohana::VERSION.' ('.Kohana::CODENAME.')';
    1046     }
    1047 
    1048 } // End Kohana
  • 相关阅读:
    自动称重系统-3
    自动称重系统-2
    自动称重系统-1
    Qt-序列号生成器
    征战 OSG-序及目录
    Qt-QML-安卓编译问题
    OSG-OSG中的observer_ptr指针
    HZNU Training 22 for Zhejiang Provincial Competition 2020
    树上乱搞
    HZNU Training 21 for Zhejiang Provincial Competition 2020
  • 原文地址:https://www.cnblogs.com/daizhuacai/p/2952451.html
Copyright © 2020-2023  润新知