PageRenderTime 92ms CodeModel.GetById 3ms app.highlight 77ms RepoModel.GetById 1ms app.codeStats 0ms

/ipserver/FLEA/FLEA.php

http://ipmanger.googlecode.com/
PHP | 2031 lines | 1090 code | 158 blank | 783 comment | 274 complexity | 46fe5430720fb8971ef86a457cce6065 MD5 | raw file
   1<?php
   2/////////////////////////////////////////////////////////////////////////////
   3// FleaPHP Framework
   4//
   5// Copyright (c) 2005 - 2008 QeeYuan China Inc. (http://www.qeeyuan.com)
   6//
   7// ??????????????? LICENSE.txt ???
   8// ???? http://www.fleaphp.org/ ???????
   9/////////////////////////////////////////////////////////////////////////////
  10
  11/**
  12 * ?? FLEA ??????????? FleaPHP ????
  13 *
  14 * ????? FleaPHP ???????????? FleaPHP ???
  15 * ??????????? require('FLEA.php') ??????
  16 * ???? FleaPHP ???????????
  17 *
  18 * @copyright Copyright (c) 2005 - 2008 QeeYuan China Inc. (http://www.qeeyuan.com)
  19 * @author ???? (www.qeeyuan.com)
  20 * @package Core
  21 * @version $Id: FLEA.php,v 1.1 2008/09/10 03:00:15 jiang Exp $
  22 */
  23
  24/**
  25 * ?????????
  26 */
  27global $___fleaphp_loaded_time;
  28$___fleaphp_loaded_time = microtime();
  29
  30/**
  31 * ?????????
  32 */
  33
  34// ?? FleaPHP ?????
  35define('FLEA_VERSION', '1.0.70.1017');
  36
  37// ???? PHP4 ? PHP5 ???
  38if (substr(PHP_VERSION, 0, 1) == '5') {
  39    define('PHP5', true);
  40    define('PHP4', false);
  41} else {
  42    define('PHP5', false);
  43    define('PHP4', true);
  44}
  45
  46// ??? DIRECTORY_SEPARATOR
  47define('DS', DIRECTORY_SEPARATOR);
  48
  49// ?? URL ??
  50define('URL_STANDARD',  'URL_STANDARD');
  51
  52// PATHINFO ??
  53define('URL_PATHINFO',  'URL_PATHINFO');
  54
  55// URL ????
  56define('URL_REWRITE',   'URL_REWRITE');
  57
  58/**#@+
  59 * ?? RBAC ??????
  60 */
  61// RBAC_EVERYONE ?????????????????????
  62define('RBAC_EVERYONE',     'RBAC_EVERYONE');
  63
  64// RBAC_HAS_ROLE ???????????
  65define('RBAC_HAS_ROLE',     'RBAC_HAS_ROLE');
  66
  67// RBAC_NO_ROLE ????????????
  68define('RBAC_NO_ROLE',      'RBAC_NO_ROLE');
  69
  70// RBAC_NULL ????????
  71define('RBAC_NULL',         'RBAC_NULL');
  72
  73// ACTION_ALL ???????????
  74define('ACTION_ALL',        'ACTION_ALL');
  75/**#@-*/
  76
  77/**
  78 * ??? FleaPHP ??
  79 */
  80define('G_FLEA_VAR', '__FLEA_CORE__');
  81$GLOBALS[G_FLEA_VAR] = array(
  82    'APP_INF'               => array(),
  83    'OBJECTS'               => array(),
  84    'DBO'                   => array(),
  85    'CLASS_PATH'            => array(),
  86    'FLEA_EXCEPTION_STACK'  => array(),
  87    'FLEA_EXCEPTION_HANDLER'=> null,
  88);
  89
  90// ?? FleaPHP ???????????? CLASS_PATH
  91$GLOBALS[G_FLEA_VAR]['CLASS_PATH'][] = dirname(__FILE__);
  92define('FLEA_DIR', $GLOBALS[G_FLEA_VAR]['CLASS_PATH'][0] . DS . 'FLEA');
  93define('FLEA_3RD_DIR', $GLOBALS[G_FLEA_VAR]['CLASS_PATH'][0] . DS . '3rd');
  94
  95// ????? FleaPHP ????????
  96if (!defined('NO_LEGACY_FLEAPHP') || NO_LEGACY_FLEAPHP == false) {
  97    require(FLEA_DIR . '/Compatibility.php');
  98}
  99
 100/**
 101 * ????????
 102 *
 103 * ?????? DEPLOY_MODE ??? true??????????? FleaPHP
 104 */
 105if (!defined('DEPLOY_MODE') || DEPLOY_MODE != true) {
 106    $GLOBALS[G_FLEA_VAR]['APP_INF'] = require(FLEA_DIR . '/Config/DEBUG_MODE_CONFIG.php');
 107    define('DEBUG_MODE', true);
 108    if (!defined('DEPLOY_MODE')) { define('DEPLOY_MODE', false); }
 109} else {
 110    $GLOBALS[G_FLEA_VAR]['APP_INF'] = require(FLEA_DIR . '/Config/DEPLOY_MODE_CONFIG.php');
 111    define('DEBUG_MODE', false);
 112    if (!defined('DEPLOY_MODE')) { define('DEPLOY_MODE', true); }
 113}
 114
 115// ??? PHP5 ???????????
 116if (!defined('E_STRICT')) {
 117    define('E_STRICT', 2048);
 118}
 119if (DEBUG_MODE) {
 120    error_reporting(error_reporting(0) & ~E_STRICT);
 121} else {
 122    error_reporting(0);
 123}
 124
 125// ????????
 126__SET_EXCEPTION_HANDLER('__FLEA_EXCEPTION_HANDLER');
 127
 128/**
 129 * FLEA ???? FleaPHP ???????
 130 *
 131 * ??????????????
 132 *
 133 * @package Core
 134 * @author ???? (www.qeeyuan.com)
 135 * @version 1.0
 136 */
 137class FLEA
 138{
 139    /**
 140     * ????????
 141     *
 142     * example:
 143     * <code>
 144     * FLEA::loadAppInf('./config/MyConfig.php');
 145     * </code>
 146     *
 147     * @param mixed $__config ??????????
 148     */
 149    function loadAppInf($__flea_internal_config = null)
 150    {
 151        if (!is_array($__flea_internal_config) && is_string($__flea_internal_config)) {
 152            if (!is_readable($__flea_internal_config)) {
 153                FLEA::loadClass('FLEA_Exception_ExpectedFile');
 154                return __THROW(new FLEA_Exception_ExpectedFile($__flea_internal_config));
 155            }
 156            $__flea_internal_config = require($__flea_internal_config);
 157        }
 158        if (is_array($__flea_internal_config)) {
 159            $GLOBALS[G_FLEA_VAR]['APP_INF'] = array_merge($GLOBALS[G_FLEA_VAR]['APP_INF'], $__flea_internal_config);
 160        }
 161        return null;
 162    }
 163
 164    /**
 165     * ??????????
 166     *
 167     * example:
 168     * <code>
 169     * FLEA::setAppInf('siteTitle');
 170     * .....
 171     * $siteTitle = FLEA::getAppInf('siteTitle');
 172     * </code>
 173     *
 174     * @param string $option
 175     * @param mixed $default
 176     *
 177     * @return mixed
 178     */
 179    function getAppInf($option, $default = null)
 180    {
 181        return isset($GLOBALS[G_FLEA_VAR]['APP_INF'][$option]) ? $GLOBALS[G_FLEA_VAR]['APP_INF'][$option] : $default;
 182    }
 183
 184    /**
 185     * ?????????????????????????
 186     *
 187     * example:
 188     * <code>
 189     * $arr = array('min' => 1, 'max' => 100, 'step' => 2);
 190     * FLEA::setAppInf('rule', $arr);
 191     * .....
 192     * $min = FLEA::getAppInfValue('rule', 'min');
 193     * </code>
 194     *
 195     * @param string $option
 196     * @param string $keyname
 197     * @param mixed $default
 198     *
 199     * @return mixed
 200     */
 201    function getAppInfValue($option, $keyname, $default = null)
 202    {
 203        if (!isset($GLOBALS[G_FLEA_VAR]['APP_INF'][$option])) {
 204            $GLOBALS[G_FLEA_VAR]['APP_INF'][$option] = array();
 205        }
 206        if (array_key_exists($keyname, $GLOBALS[G_FLEA_VAR]['APP_INF'][$option])) {
 207            return $GLOBALS[G_FLEA_VAR]['APP_INF'][$option][$keyname];
 208        } else {
 209            $GLOBALS[G_FLEA_VAR]['APP_INF'][$option][$keyname] = $default;
 210            return $default;
 211        }
 212    }
 213
 214    /**
 215     * ??????????????????????????
 216     *
 217     * @param string $option
 218     * @param string $keyname
 219     * @param mixed $value
 220     */
 221    function setAppInfValue($option, $keyname, $value)
 222    {
 223        if (!isset($GLOBALS[G_FLEA_VAR]['APP_INF'][$option])) {
 224            $GLOBALS[G_FLEA_VAR]['APP_INF'][$option] = array();
 225        }
 226        $GLOBALS[G_FLEA_VAR]['APP_INF'][$option][$keyname] = $value;
 227    }
 228
 229    /**
 230     * ?????
 231     *
 232     * @param string $option
 233     * @param mixed $data
 234     */
 235    function setAppInf($option, $data = null)
 236    {
 237        if (is_array($option)) {
 238            $GLOBALS[G_FLEA_VAR]['APP_INF'] = array_merge($GLOBALS[G_FLEA_VAR]['APP_INF'], $option);
 239        } else {
 240            $GLOBALS[G_FLEA_VAR]['APP_INF'][$option] = $data;
 241        }
 242    }
 243
 244    /**
 245     * ????????
 246     *
 247     * FLEA::loadClass()?FLEA::getSingleton() ????????????????????
 248     * ?????? FLEA::import() ????????????????????
 249     * ?????????????????????????????????????????????
 250     *
 251     * ?????? Table_Posts???????? ./APP/Table/Posts.php?
 252     * ??????????? ./APP???? ./APP/Table ?
 253     *
 254     * example:
 255     * <code>
 256     * FLEA::import(APP_DIR . '/LIBS');
 257     * </code>
 258     *
 259     * @param string $dir
 260     */
 261    function import($dir)
 262    {
 263        if (array_search($dir, $GLOBALS[G_FLEA_VAR]['CLASS_PATH'], true)) { return; }
 264        if (DIRECTORY_SEPARATOR == '/') {
 265            $dir = str_replace('\\', DIRECTORY_SEPARATOR, $dir);
 266        } else {
 267            $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir);
 268        }
 269        $GLOBALS[G_FLEA_VAR]['CLASS_PATH'][] = $dir;
 270    }
 271
 272    /**
 273     * ???????
 274     *
 275     * FLEA::loadFile() ? $filename ???? “_” ?????????
 276     *
 277     * example:
 278     * <code>
 279     * FLEA::loadFile('Table_Posts.php');
 280     * // ??? include 'Table/Posts.php';
 281     * </code>
 282     *
 283     * @param string $className
 284     * @param boolean $loadOnce ??? true ??FLEA::loadFile() ??? require_once
 285     *
 286     * @return boolean
 287     */
 288    function loadFile($filename, $loadOnce = false)
 289    {
 290        static $is_loaded = array();
 291
 292        $path = FLEA::getFilePath($filename);
 293        if ($path != '') {
 294            if (isset($is_loaded[$path]) && $loadOnce) { return true; }
 295            $is_loaded[$path] = true;
 296            if ($loadOnce) {
 297                return require_once($path);
 298            } else {
 299                return require($path);
 300            }
 301        }
 302
 303        FLEA::loadClass('FLEA_Exception_ExpectedFile');
 304        __THROW(new FLEA_Exception_ExpectedFile($filename));
 305        return false;
 306    }
 307
 308    /**
 309     * ??????????
 310     *
 311     * ????? “_” ??????????????????????????
 312     *
 313     * example:
 314     * <code>
 315     * FLEA::loadClass('Table_Posts');
 316     * // ?????? Table_Posts ?????? Table/Posts.php
 317     * // ?????????? Table/Posts.php ??
 318     * </code>
 319     *
 320     * @param string $filename
 321     * @param boolean $noException ??? true????????????????
 322     *
 323     * @return boolean
 324     */
 325    function loadClass($className, $noException = false)
 326    {
 327        if (PHP5) {
 328            if (class_exists($className, false) || interface_exists($className, false)) { return true; }
 329        } else {
 330            if (class_exists($className)) { return true; }
 331        }
 332
 333        if (preg_match('/[^a-z0-9\-_.]/i', $className) === 0) {
 334            $filename = FLEA::getFilePath($className . '.php');
 335            if ($filename) {
 336                require($filename);
 337                if (PHP5) {
 338                    if (class_exists($className, false) || interface_exists($className, false)) { return true; }
 339                } else {
 340                    if (class_exists($className)) { return true; }
 341                }
 342            }
 343        }
 344
 345        if ($noException) { return false; }
 346
 347        $filename = FLEA::getFilePath($className . '.php', true);
 348        require_once(FLEA_DIR . '/Exception/ExpectedClass.php');
 349        __THROW(new FLEA_Exception_ExpectedClass($className, $filename, file_exists($filename)));
 350        return false;
 351    }
 352
 353    /**
 354     * ?? FleaPHP ??????????
 355     *
 356     * FleaPHP ????????????“_”?????????
 357     *
 358     * @param string $filename
 359     * @param boolean $return ??????????????????????????
 360     *
 361     * @return string
 362     */
 363    function getFilePath($filename, $return = false)
 364    {
 365        $filename = str_replace('_', DIRECTORY_SEPARATOR, $filename);
 366        if (DIRECTORY_SEPARATOR == '/') {
 367            $filename = str_replace('\\', DIRECTORY_SEPARATOR, $filename);
 368        } else {
 369            $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
 370        }
 371
 372        if (strtolower(substr($filename, -4)) != '.php') {
 373            $filename .= '.php';
 374        }
 375
 376        // ????????
 377        if (is_file($filename)) { return $filename; }
 378
 379        foreach ($GLOBALS[G_FLEA_VAR]['CLASS_PATH'] as $classdir) {
 380            $path = $classdir . DIRECTORY_SEPARATOR . $filename;
 381            if (is_file($path)) { return $path; }
 382        }
 383
 384        if ($return) { return $filename; }
 385        return false;
 386    }
 387
 388    /**
 389     * ????????????
 390     *
 391     * example:
 392     * <code>
 393     * $obj =& FLEA::getSingleton('Table_Posts);
 394     * ......
 395     * $obj2 =& FLEA::getSingleton('Table_Posts);
 396     * // ?????????????????
 397     * echo $obj === $obj2 ? 'Equals' : 'Not equals';
 398     * </code>
 399     *
 400     * @param string $className
 401     *
 402     * @return object
 403     */
 404    function & getSingleton($className)
 405    {
 406        static $instances = array();
 407        if (FLEA::isRegistered($className)) {
 408            // ???????????
 409            return FLEA::registry($className);
 410        }
 411        if (PHP5) {
 412            $classExists = class_exists($className, false);
 413        } else {
 414            $classExists = class_exists($className);
 415        }
 416        if (!$classExists) {
 417            if (!FLEA::loadClass($className)) {
 418                $return = false;
 419                return $return;
 420            }
 421        }
 422
 423        $instances[$className] =& new $className();
 424        FLEA::register($instances[$className], $className);
 425        return $instances[$className];
 426    }
 427
 428    /**
 429     * ???????????????????????
 430     *
 431     * example:
 432     * <code>
 433     * $obj =& new MyClass();
 434     * // ????????
 435     * FLEA::register($obj, 'MyClass');
 436     * .....
 437     * // ??????????
 438     * $obj2 =&  FLEA::registry('MyClass');
 439     * // ??????????
 440     * echo $obj === $obj2 ? 'Equals' : 'Not equals';
 441     * </code>
 442     *
 443     * @param object $obj
 444     * @param string $name
 445     *
 446     * @return object
 447     */
 448    function & register(& $obj, $name = null)
 449    {
 450        if (!is_object($obj)) {
 451            FLEA::loadClass('FLEA_Exception_TypeMismatch');
 452            return __THROW(new FLEA_Exception_TypeMismatch($obj, 'object', gettype($obj)));
 453        }
 454
 455        if (is_null($name)) {
 456            $name = get_class($obj);
 457        }
 458
 459        if (isset($GLOBALS[G_FLEA_VAR]['OBJECTS'][$name])) {
 460            FLEA::loadClass('FLEA_Exception_ExistsKeyName');
 461            return __THROW(new FLEA_Exception_ExistsKeyName($name));
 462        } else {
 463            $GLOBALS[G_FLEA_VAR]['OBJECTS'][$name] =& $obj;
 464            return $obj;
 465        }
 466    }
 467
 468    /**
 469     * ????????????????????????????????????????
 470     *
 471     * example:?? FLEA::register()
 472     *
 473     * @param string $name
 474     *
 475     * @return object
 476     */
 477    function & registry($name = null)
 478    {
 479        if (is_null($name)) {
 480            return $GLOBALS[G_FLEA_VAR]['OBJECTS'];
 481        }
 482        if (isset($GLOBALS[G_FLEA_VAR]['OBJECTS'][$name]) && is_object($GLOBALS[G_FLEA_VAR]['OBJECTS'][$name])) {
 483            return $GLOBALS[G_FLEA_VAR]['OBJECTS'][$name];
 484        }
 485        FLEA::loadClass('FLEA_Exception_NotExistsKeyName');
 486        return __THROW(new FLEA_Exception_NotExistsKeyName($name));
 487    }
 488
 489    /**
 490     * ???????????????
 491     *
 492     * example:
 493     * <code>
 494     * if (FLEA::isRegistered('MyClass')) {
 495     *      $obj =& FLEA::registry('MyClass');
 496     * } else {
 497     *      $obj =& new MyClass();
 498     * }
 499     * </code>
 500     *
 501     * @param string $name
 502     *
 503     * @return boolean
 504     */
 505    function isRegistered($name)
 506    {
 507        return isset($GLOBALS[G_FLEA_VAR]['OBJECTS'][$name]);
 508    }
 509
 510
 511    /**
 512     * ?????????????????????????? false
 513     *
 514     * example:
 515     * <code>
 516     * $cacheId = 'my_cache_id';
 517     * if (!($data = FLEA::getCache($cacheId))) {
 518     *      $data = 'Data';
 519     *      FLEA::writeCache($cacheId, $data);
 520     * }
 521     * </code>
 522     *
 523     * ?? $cacheIdIsFilename ??? true??????????? $cacheId ????????
 524     * ???????????? $cacheIdIsFilename ????? true?
 525     *
 526     * $time ??????????????????????????????????????????????????????
 527     *
 528     * ?? $timeIsLifetime ? false?? $time ????????????????????????
 529     * ?? $time ??????????????????????????????
 530     *
 531     * @param string $cacheId ??ID???????????????ID
 532     * @param int $time ?????????????
 533     * @param boolean $timeIsLifetime ?? $time ?????
 534     * @param boolean $cacheIdIsFilename ????? $cacheId ?????
 535     *
 536     * @return mixed ??????????????????? false
 537     */
 538    function getCache($cacheId, $time = 900, $timeIsLifetime = true, $cacheIdIsFilename = false)
 539    {
 540        $cacheDir = FLEA::getAppInf('internalCacheDir');
 541        if (is_null($cacheDir)) {
 542            FLEA::loadClass('FLEA_Exception_CacheDisabled');
 543            __THROW(new FLEA_Exception_CacheDisabled($cacheDir));
 544            return false;
 545        }
 546
 547        if ($cacheIdIsFilename) {
 548            $cacheFile = $cacheDir . DS . preg_replace('/[^a-z0-9\-_]/i', '_', $cacheId);
 549        } else {
 550            $cacheFile = $cacheDir . DS . md5($cacheId);
 551        }
 552        if (!file_exists($cacheFile)) { return false; }
 553
 554        if ($timeIsLifetime && $time == -1) {
 555            $data = safe_file_get_contents($cacheFile);
 556            return $data !== false ? unserialize($data) : false;
 557        }
 558
 559        $filetime = filemtime($cacheFile);
 560        if ($timeIsLifetime) {
 561            if (time() >= $filetime + $time) { return false; }
 562        } else {
 563            if ($time >= $filetime) { return false; }
 564        }
 565        $data = safe_file_get_contents($cacheFile);
 566        return $data !== false ? unserialize($data) : false;
 567    }
 568
 569    /**
 570     * ?????????
 571     *
 572     * example:
 573     * <code>
 574     * $data = .....; // ????????????????
 575     * // cache id ???????????????????????
 576     * $cacheId = 'data_cahce_1';
 577     * FLEA::writeCache($cacheId, $data);
 578     * </code>
 579     *
 580     * @param string $cacheId
 581     * @param mixed $data
 582     * @param boolean $cacheIdIsFilename
 583     *
 584     * @return boolean
 585     */
 586    function writeCache($cacheId, $data, $cacheIdIsFilename = false)
 587    {
 588        $cacheDir = FLEA::getAppInf('internalCacheDir');
 589        if (is_null($cacheDir)) {
 590            FLEA::loadClass('FLEA_Exception_CacheDisabled');
 591            __THROW(new FLEA_Exception_CacheDisabled($cacheDir));
 592            return false;
 593        }
 594
 595        if ($cacheIdIsFilename) {
 596            $cacheFile = $cacheDir . DS . preg_replace('/[^a-z0-9\-_]/i', '_', $cacheId);
 597        } else {
 598            $cacheFile = $cacheDir . DS . md5($cacheId);
 599        }
 600        if (!safe_file_put_contents($cacheFile, serialize($data))) {
 601            FLEA::loadClass('FLEA_Exception_CacheDisabled');
 602            __THROW(new FLEA_Exception_CacheDisabled($cacheDir));
 603            return false;
 604        } else {
 605            return true;
 606        }
 607    }
 608
 609    /**
 610     * ?????????
 611     *
 612     * @param string $cacheId
 613     * @param boolean $cacheIdIsFilename
 614     *
 615     * @return boolean
 616     */
 617    function purgeCache($cacheId, $cacheIdIsFilename = false)
 618    {
 619        $cacheDir = FLEA::getAppInf('internalCacheDir');
 620        if (is_null($cacheDir)) {
 621            FLEA::loadClass('FLEA_Exception_CacheDisabled');
 622            __THROW(new FLEA_Exception_CacheDisabled($cacheDir));
 623            return false;
 624        }
 625
 626        if ($cacheIdIsFilename) {
 627            $cacheFile = $cacheDir . DS . preg_replace('/[^a-z0-9\-_]/i', '_', $cacheId);
 628        } else {
 629            $cacheFile = $cacheDir . DS . md5($cacheId);
 630        }
 631
 632        if (file_exists($cacheFile)) {
 633            return unlink($cacheFile);
 634        }
 635        return true;
 636    }
 637
 638
 639    /**
 640     * ??? WebControls??? FLEA_WebControls ????
 641     *
 642     * ?????????? webControlsClassName?????? WebControls ??
 643     *
 644     * @return FLEA_WebControls
 645     */
 646    function & initWebControls()
 647    {
 648        return FLEA::getSingleton(FLEA::getAppInf('webControlsClassName'));
 649    }
 650
 651    /**
 652     * ??? Ajax??? FLEA_Ajax ????
 653     *
 654     * ?????????? ajaxClassName?????? Ajax ??
 655     *
 656     * @return FLEA_Ajax
 657     */
 658    function & initAjax()
 659    {
 660        return FLEA::getSingleton(FLEA::getAppInf('ajaxClassName'));
 661    }
 662
 663    /**
 664     * ??????
 665     *
 666     * ???????????????????? helper. ???
 667     * ?? helper.array ??? FLEA_Helper_Array?helper.image ??? FLEA_Helper_Image?
 668     *
 669     * @param string $helperName
 670     */
 671    function loadHelper($helperName)
 672    {
 673        $settingName = 'helper.' . strtolower($helperName);
 674        $setting = FLEA::getAppInf($settingName);
 675        if ($setting) {
 676            return FLEA::loadFile($setting, true);
 677        } else {
 678            FLEA::loadClass('FLEA_Exception_NotExistsKeyName');
 679            return __THROW(new FLEA_Exception_NotExistsKeyName('helper.' . $helperName));
 680        }
 681    }
 682
 683    /**
 684     * ???????????
 685     *
 686     * ????? $dsn ????? $dsn ??? 0????????? dbDSN ? DSN ???
 687     *
 688     * DSN ? Database Source Name ???????????????
 689     * ? FleaPHP ??DSN ???????????????????????????????????
 690     *
 691     * DSN ??????
 692     *
 693     * example:
 694     * <code>
 695     * $dsn = array(
 696     *      'driver'   => 'mysql',
 697     *      'host'     => 'localhost',
 698     *      'login'    => 'username',
 699     *      'password' => 'password',
 700     *      'database' => 'test_db',
 701     *      'charset'  => 'utf8',
 702     * );
 703     *
 704     * $dbo =& FLEA::getDBO($dsn);
 705     * </code>
 706     *
 707     * @param array|string|int $dsn
 708     *
 709     * @return FLEA_Db_Driver_Abstract
 710     */
 711    function & getDBO($dsn = 0)
 712    {
 713        if ($dsn == 0) {
 714            $dsn = FLEA::getAppInf('dbDSN');
 715        }
 716        $dsn = FLEA::parseDSN($dsn);
 717
 718        if (!is_array($dsn) || !isset($dsn['driver'])) {
 719            FLEA::loadClass('FLEA_Db_Exception_InvalidDSN');
 720            return __THROW(new FLEA_Db_Exception_InvalidDSN($dsn));
 721        }
 722
 723        $dsnid = $dsn['id'];
 724        if (isset($GLOBALS[G_FLEA_VAR]['DBO'][$dsnid])) {
 725            return $GLOBALS[G_FLEA_VAR]['DBO'][$dsnid];
 726        }
 727
 728        $driver = ucfirst(strtolower($dsn['driver']));
 729        $className = 'FLEA_Db_Driver_' . $driver;
 730        if ($driver == 'Mysql' || $driver == 'Mysqlt') {
 731            require_once(FLEA_DIR . '/Db/Driver/Mysql.php');
 732        } else {
 733            FLEA::loadClass($className);
 734        }
 735        $dbo =& new $className($dsn);
 736        /* @var $dbo FLEA_Db_Driver_Abstract */
 737        $dbo->connect();
 738
 739        $GLOBALS[G_FLEA_VAR]['DBO'][$dsnid] =& $dbo;
 740        return $GLOBALS[G_FLEA_VAR]['DBO'][$dsnid];
 741    }
 742
 743    /**
 744     * ?? DSN ??????????? DSN ???????????? false
 745     *
 746     * @param string|array $dsn
 747     *
 748     * @return array
 749     */
 750    function parseDSN($dsn)
 751    {
 752        if (is_array($dsn)) {
 753            $dsn['host'] = isset($dsn['host']) ? $dsn['host'] : '';
 754            $dsn['port'] = isset($dsn['port']) ? $dsn['port'] : '';
 755            $dsn['login'] = isset($dsn['login']) ? $dsn['login'] : '';
 756            $dsn['password'] = isset($dsn['password']) ? $dsn['password'] : '';
 757            $dsn['database'] = isset($dsn['database']) ? $dsn['database'] : '';
 758            $dsn['options'] = isset($dsn['options']) ? serialize($dsn['options']) : '';
 759            $dsn['prefix'] = isset($dsn['prefix']) ? $dsn['prefix'] : FLEA::getAppInf('dbTablePrefix');
 760            $dsn['schema'] = isset($dsn['schema']) ? $dsn['schema'] : '';
 761        } else {
 762            $dsn = str_replace('@/', '@localhost/', $dsn);
 763            $parse = parse_url($dsn);
 764            if (empty($parse['scheme'])) { return false; }
 765
 766            $dsn = array();
 767            $dsn['host']     = isset($parse['host']) ? $parse['host'] : 'localhost';
 768            $dsn['port']     = isset($parse['port']) ? $parse['port'] : '';
 769            $dsn['login']    = isset($parse['user']) ? $parse['user'] : '';
 770            $dsn['password'] = isset($parse['pass']) ? $parse['pass'] : '';
 771            $dsn['driver']   = isset($parse['scheme']) ? strtolower($parse['scheme']) : '';
 772            $dsn['database'] = isset($parse['path']) ? substr($parse['path'], 1) : '';
 773            $dsn['options']  = isset($parse['query']) ? $parse['query'] : '';
 774            $dsn['prefix'] = FLEA::getAppInf('dbTablePrefix');
 775            $dsn['schema']   = '';
 776        }
 777        $dsnid = "{$dsn['driver']}://{$dsn['login']}:{$dsn['password']}@{$dsn['host']}_{$dsn['prefix']}/{$dsn['database']}/{$dsn['schema']}/{$dsn['options']}";
 778        $dsn['id'] = $dsnid;
 779        return $dsn;
 780    }
 781
 782    /**
 783     * FleaPHP ???? MVC ????
 784     *
 785     * ?????????? FleaPHP ??? MVC ??????? FLEA.php ????????????????? FLEA::runMVC() ???????
 786     */
 787    function runMVC()
 788    {
 789        $MVCPackageFilename = FLEA::getAppInf('MVCPackageFilename');
 790        if ($MVCPackageFilename != '') {
 791            require_once($MVCPackageFilename);
 792        }
 793        FLEA::init();
 794
 795        // ??????????????
 796        $dispatcherClass = FLEA::getAppInf('dispatcher');
 797        FLEA::loadClass($dispatcherClass);
 798
 799        $dispatcher =& new $dispatcherClass($_GET);
 800        FLEA::register($dispatcher, $dispatcherClass);
 801        $dispatcher->dispatching();
 802    }
 803
 804    /**
 805     * ??????
 806     *
 807     * @param boolean $loadMVC
 808     */
 809    function init($loadMVC = false)
 810    {
 811        static $firstTime = true;
 812
 813        // ?????? FLEA::init()
 814        if (!$firstTime) { return; }
 815        $firstTime = false;
 816
 817        /**
 818         * ???????????????
 819         */
 820        __SET_EXCEPTION_HANDLER(FLEA::getAppInf('exceptionHandler'));
 821        if (PHP5) {
 822            set_exception_handler(FLEA::getAppInf('exceptionHandler'));
 823        }
 824
 825        /**
 826         * ??????????
 827         */
 828        if (FLEA::getAppInf('logEnabled') && FLEA::getAppInf('logProvider')) {
 829            FLEA::loadClass(FLEA::getAppInf('logProvider'));
 830        }
 831        if (!function_exists('log_message')) {
 832            // ?????????????????????? log_message() ??
 833            function log_message() {};
 834        }
 835
 836        /**
 837         * ?????????????????????
 838         */
 839        $cachedir = FLEA::getAppInf('internalCacheDir');
 840        if (empty($cachedir)) {
 841            FLEA::setAppInf('internalCacheDir', dirname(__FILE__) . DS . '_Cache');
 842        }
 843
 844        // ?? magic_quotes
 845        if (get_magic_quotes_gpc()) {
 846            $in = array(& $_GET, & $_POST, & $_COOKIE, & $_REQUEST);
 847            while (list($k,$v) = each($in)) {
 848                foreach ($v as $key => $val) {
 849                    if (!is_array($val)) {
 850                        $in[$k][$key] = stripslashes($val);
 851                        continue;
 852                    }
 853                    $in[] =& $in[$k][$key];
 854                }
 855            }
 856            unset($in);
 857        }
 858        set_magic_quotes_runtime(0);
 859
 860        // ?? URL ???????????? URL ?????
 861        if (FLEA::getAppInf('urlMode') != URL_STANDARD) {
 862            require(FLEA_DIR . '/Filter/Uri.php');
 863        }
 864
 865        // ?? requestFilters
 866        foreach ((array)FLEA::getAppInf('requestFilters') as $file) {
 867            FLEA::loadFile($file);
 868        }
 869
 870        // ?? $loadMVC
 871        if ($loadMVC) {
 872            $MVCPackageFilename = FLEA::getAppInf('MVCPackageFilename');
 873            if ($MVCPackageFilename != '') {
 874                require_once($MVCPackageFilename);
 875            }
 876        }
 877
 878        // ?? autoLoad
 879        foreach ((array)FLEA::getAppInf('autoLoad') as $file) {
 880            FLEA::loadFile($file);
 881        }
 882
 883        // ????? session ??????
 884        if (FLEA::getAppInf('sessionProvider')) {
 885            FLEA::getSingleton(FLEA::getAppInf('sessionProvider'));
 886        }
 887        // ???? session ??
 888        if (FLEA::getAppInf('autoSessionStart')) {
 889            session_start();
 890        }
 891
 892        // ?? I18N ?????
 893        define('RESPONSE_CHARSET', FLEA::getAppInf('responseCharset'));
 894        define('DATABASE_CHARSET', FLEA::getAppInf('databaseCharset'));
 895
 896        // ???????????
 897        if (FLEA::getAppInf('multiLanguageSupport')) {
 898            FLEA::loadClass(FLEA::getAppInf('languageSupportProvider'));
 899        }
 900        if (!function_exists('_T')) {
 901            function _T() {};
 902        }
 903
 904        // ?????????
 905        if (FLEA::getAppInf('autoResponseHeader')) {
 906            header('Content-Type: text/html; charset=' . FLEA::getAppInf('responseCharset'));
 907        }
 908    }
 909}
 910
 911/**
 912 * ?? FleaPHP ???????
 913 */
 914
 915/**
 916 * ?????????? URL
 917 *
 918 * @param string $url ????? url
 919 * @param int $delay ?????????
 920 * @param bool $js ??????????? JavaScript ??
 921 * @param bool $jsWrapped ???? JavaScript ??????? <script> ??????
 922 * @param bool $return ????????? JavaScript ??
 923 */
 924function redirect($url, $delay = 0, $js = false, $jsWrapped = true, $return = false)
 925{
 926    $delay = (int)$delay;
 927    if (!$js) {
 928        if (headers_sent() || $delay > 0) {
 929            echo <<<EOT
 930    <html>
 931    <head>
 932    <meta http-equiv="refresh" content="{$delay};URL={$url}" />
 933    </head>
 934    </html>
 935EOT;
 936            exit;
 937        } else {
 938            header("Location: {$url}");
 939            exit;
 940        }
 941    }
 942
 943    $out = '';
 944    if ($jsWrapped) {
 945        $out .= '<script language="JavaScript" type="text/javascript">';
 946    }
 947    if ($delay > 0) {
 948        $out .= "window.setTimeout(function () { document.location='{$url}'; }, {$delay});";
 949    } else {
 950        $out .= "document.location='{$url}';";
 951    }
 952    if ($jsWrapped) {
 953        $out .= '</script>';
 954    }
 955
 956    if ($return) {
 957        return $out;
 958    }
 959
 960    echo $out;
 961    exit;
 962}
 963
 964/**
 965 * ?? url
 966 *
 967 * ?? url ??????????????????????????????????????
 968 * ? url() ????????????????????????????????
 969 *
 970 * url() ????????? urlMode ????? URL ???
 971 * - URL_STANDARD - ??????????? index.php?url=Login&action=Reject&id=1
 972 * - URL_PATHINFO - PATHINFO ????? index.php/Login/Reject/id/1
 973 * - URL_REWRITE  - URL ??????? /Login/Reject/id/1
 974 *
 975 * ??? url ??????????????????
 976 *   - controllerAccessor
 977 *   - defaultController
 978 *   - actionAccessor
 979 *   - defaultAction
 980 *   - urlMode
 981 *   - urlLowerChar
 982 *
 983 * ???
 984 * <code>
 985 * $url = url('Login', 'checkUser');
 986 * // $url ??? ?controller=Login&action=checkUser
 987 *
 988 * $url = url('Login', 'checkUser', array('username' => 'dualface'));
 989 * // $url ??? ?controller=Login&action=checkUser&username=dualface
 990 *
 991 * $url = url('Article', 'View', array('id' => 1'), '#details');
 992 * // $url ??? ?controller=Article&action=View&id=1#details
 993 * </code>
 994 *
 995 * @param string $controllerName
 996 * @param string $actionName
 997 * @param array $params
 998 * @param string $anchor
 999 * @param array $options
1000 *
1001 * @return string
1002 */
1003function url($controllerName = null, $actionName = null, $params = null, $anchor = null, $options = null)
1004{
1005    static $baseurl = null, $currentBootstrap = null;
1006
1007    // ????? URL ??????????
1008    if (is_null($baseurl)) {
1009        $baseurl = detect_uri_base();
1010        $p = strrpos($baseurl, '/');
1011        $currentBootstrap = substr($baseurl, $p + 1);
1012        $baseurl = substr($baseurl, 0, $p);
1013    }
1014
1015    // ???? url ???? bootstrap
1016    $options = (array)$options;
1017    if (isset($options['bootstrap'])) {
1018        $bootstrap = $options['bootstrap'];
1019    } else if ($currentBootstrap == '') {
1020        $bootstrap = FLEA::getAppInf('urlBootstrap');
1021    } else {
1022        $bootstrap = $currentBootstrap;
1023    }
1024
1025    // ???????????
1026    $defaultController = FLEA::getAppInf('defaultController');
1027    $defaultAction = FLEA::getAppInf('defaultAction');
1028    $lowerChar = isset($options['lowerChar']) ? $options['lowerChar'] : FLEA::getAppInf('urlLowerChar');
1029    if ($lowerChar) {
1030        $defaultController = strtolower($defaultController);
1031        $defaultAction = strtolower($defaultAction);
1032    }
1033
1034    if ($bootstrap != $currentBootstrap && $currentBootstrap != '') {
1035        $controllerName = !empty($controllerName) ? $controllerName : null;
1036        $actionName = !empty($actionName) ? $actionName : null;
1037    } else {
1038        $controllerName = !empty($controllerName) ? $controllerName : $defaultController;
1039        $actionName = !empty($actionName) ? $actionName : $defaultAction;
1040    }
1041    if ($lowerChar) {
1042        $controllerName = strtolower($controllerName);
1043        $actionName = strtolower($actionName);
1044    }
1045
1046    $url = '';
1047    $mode = isset($options['mode']) ? $options['mode'] : FLEA::getAppInf('urlMode');
1048
1049    // PATHINFO ? REWRITE ??
1050    if ($mode == URL_PATHINFO || $mode == URL_REWRITE) {
1051        $url = $baseurl;
1052        if ($mode == URL_PATHINFO) {
1053            $url .= '/' . $bootstrap;
1054        }
1055        if ($controllerName != '' && $actionName != '') {
1056            $pps = isset($options['parameterPairStyle']) ? $options['parameterPairStyle'] : FLEA::getAppInf('urlParameterPairStyle');
1057            $url .= '/' . rawurlencode($controllerName);
1058            if (is_array($params) && !empty($params)) {
1059                $url .= '/' . rawurlencode($actionName);
1060                $url .= '/' . encode_url_args($params, $mode, $pps);
1061            } else {
1062                if (FLEA::getAppInf('urlAlwaysUseAccessor') || $actionName != $defaultAction) {
1063                    $url .= '/' . rawurlencode($actionName);
1064                }
1065            }
1066        }
1067        if ($anchor) { $url .= '#' . $anchor; }
1068        return $url;
1069    }
1070
1071    // ????
1072    $alwaysUseBootstrap = isset($options['alwaysUseBootstrap']) ? $options['alwaysUseBootstrap'] : FLEA::getAppInf('urlAlwaysUseBootstrap');
1073    $url = $baseurl . '/';
1074
1075    if ($alwaysUseBootstrap || $bootstrap != FLEA::getAppInf('urlBootstrap')) {
1076        $url .= $bootstrap;
1077    }
1078
1079    $parajoin = '?';
1080    if (FLEA::getAppInf('urlAlwaysUseAccessor')) {
1081        $defaultController = '';
1082        $defaultAction = '';
1083    }
1084    if ($controllerName != $defaultController && !is_null($controllerName)) {
1085        $url .= $parajoin . FLEA::getAppInf('controllerAccessor'). '=' . $controllerName;
1086        $parajoin = '&';
1087    }
1088    if ($actionName != $defaultAction && !is_null($actionName)) {
1089        $url .= $parajoin . FLEA::getAppInf('actionAccessor') . '=' . $actionName;
1090        $parajoin = '&';
1091    }
1092
1093    if (is_array($params) && !empty($params)) {
1094        $url .= $parajoin . encode_url_args($params, $mode);
1095    }
1096    if ($anchor) { $url .= '#' . $anchor; }
1097
1098    return $url;
1099}
1100
1101/**
1102 * ??????? URL ??
1103 *
1104 * ?? tsingson ?????????? FleaPHP ?? url() ?????? CGI ??????
1105 *
1106 * @param boolean $queryMode ??? URL ????????????
1107 *
1108 * @return string
1109 */
1110function detect_uri_base($queryMode = false)
1111{
1112    $aURL = array();
1113
1114    // Try to get the request URL
1115    if (!empty($_SERVER['SCRIPT_NAME'])) {
1116        $arr = parse_url($_SERVER['SCRIPT_NAME']);
1117        $aURL['path'] = $arr['path'];
1118    } elseif (!empty($_SERVER['REQUEST_URI'])) {
1119        $_SERVER['REQUEST_URI'] = str_replace(array('"',"'",'<','>'), array('%22','%27','%3C','%3E'), $_SERVER['REQUEST_URI']);
1120        $p = strpos($_SERVER['REQUEST_URI'], ':');
1121        if ($p > 0 && substr($_SERVER['REQUEST_URI'], $p + 1, 2) != '//') {
1122            $aURL = array('path' => $_SERVER['REQUEST_URI']);
1123        } else {
1124            $aURL = parse_url($_SERVER['REQUEST_URI']);
1125        }
1126        if (isset($aURL['path']) && isset($_SERVER['PATH_INFO'])) {
1127            $aURL['path'] = substr(urldecode($aURL['path']), 0, - strlen($_SERVER['PATH_INFO']));
1128        }
1129    }
1130
1131    // Fill in the empty values
1132    if (empty($aURL['scheme'])) {
1133        if (!empty($_SERVER['HTTP_SCHEME'])) {
1134            $aURL['scheme'] = $_SERVER['HTTP_SCHEME'];
1135        } else {
1136            $aURL['scheme'] = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? 'https' : 'http';
1137        }
1138    }
1139
1140    if (empty($aURL['host'])) {
1141        if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
1142            $p = strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ':');
1143            if ($p > 0) {
1144                $aURL['host'] = substr($_SERVER['HTTP_X_FORWARDED_HOST'], 0, $p);
1145                $aURL['port'] = substr($_SERVER['HTTP_X_FORWARDED_HOST'], $p + 1);
1146            } else {
1147                $aURL['host'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
1148            }
1149        } else if (!empty($_SERVER['HTTP_HOST'])) {
1150            $p = strpos($_SERVER['HTTP_HOST'], ':');
1151            if ($p > 0) {
1152                $aURL['host'] = substr($_SERVER['HTTP_HOST'], 0, $p);
1153                $aURL['port'] = substr($_SERVER['HTTP_HOST'], $p + 1);
1154            } else {
1155                $aURL['host'] = $_SERVER['HTTP_HOST'];
1156            }
1157        } else if (!empty($_SERVER['SERVER_NAME'])) {
1158            $aURL['host'] = $_SERVER['SERVER_NAME'];
1159        }
1160    }
1161
1162    if (empty($aURL['port']) && !empty($_SERVER['SERVER_PORT'])) {
1163        $aURL['port'] = $_SERVER['SERVER_PORT'];
1164    }
1165
1166    if (empty($aURL['path'])) {
1167        if (!empty($_SERVER['PATH_INFO'])) {
1168            $sPath = parse_url($_SERVER['PATH_INFO']);
1169        } else {
1170            $sPath = parse_url($_SERVER['PHP_SELF']);
1171        }
1172        $aURL['path'] = str_replace(array('"',"'",'<','>'), array('%22','%27','%3C','%3E'), $sPath['path']);
1173        unset($sPath);
1174    }
1175
1176    // Build the URL: Start with scheme, user and pass
1177    $sURL = $aURL['scheme'].'://';
1178    if (!empty($aURL['user'])) {
1179        $sURL .= $aURL['user'];
1180        if (!empty($aURL['pass'])) {
1181            $sURL .= ':'.$aURL['pass'];
1182        }
1183        $sURL .= '@';
1184    }
1185
1186    // Add the host
1187    $sURL .= $aURL['host'];
1188
1189    // Add the port if needed
1190    if (!empty($aURL['port']) && (($aURL['scheme'] == 'http' && $aURL['port'] != 80) || ($aURL['scheme'] == 'https' && $aURL['port'] != 443))) {
1191        $sURL .= ':'.$aURL['port'];
1192    }
1193
1194    $sURL .= $aURL['path'];
1195
1196    // Add the path and the query string
1197    if ($queryMode && isset($aURL['query'])) {
1198        $sURL .= $aURL['query'];
1199    }
1200
1201    unset($aURL);
1202    return $sURL;
1203}
1204
1205/**
1206 * ????????? url ????????
1207 *
1208 * ???
1209 * <code>
1210 * $string = encode_url_args(array('username' => 'dualface', 'mode' => 'md5'));
1211 * // $string ??? username=dualface&mode=md5
1212 * </code>
1213 *
1214 * @param array $args
1215 * @param enum $urlMode
1216 * @param string $parameterPairStyle
1217 *
1218 * @return string
1219 */
1220function encode_url_args($args, $urlMode = URL_STANDARD, $parameterPairStyle = null)
1221{
1222    $str = '';
1223    switch ($urlMode) {
1224    case URL_STANDARD:
1225        if (is_null($parameterPairStyle)) {
1226            $parameterPairStyle = '=';
1227        }
1228        $sc = '&';
1229        break;
1230    case URL_PATHINFO:
1231    case URL_REWRITE:
1232        if (is_null($parameterPairStyle)) {
1233            $parameterPairStyle = FLEA::getAppInf('urlParameterPairStyle');
1234        }
1235        $sc = '/';
1236        break;
1237    }
1238
1239    foreach ($args as $key => $value) {
1240        if (is_null($value) || $value === '') { continue; }
1241        if (is_array($value)) {
1242            $append = encode_url_args($value, $urlMode);
1243        } else {
1244            $append = rawurlencode($key) . $parameterPairStyle . rawurlencode($value);
1245        }
1246        if (substr($str, -1) != $sc) {
1247            $str .= $sc;
1248        }
1249        $str .= $append;
1250    }
1251    return substr($str, 1);
1252}
1253
1254/**
1255 * ?? HTML ???????? htmlspecialchars()
1256 *
1257 * @param string $text
1258 *
1259 * @return string
1260 */
1261function h($text)
1262{
1263    return htmlspecialchars($text);
1264}
1265
1266/**
1267 * ?? HTML ????????????
1268 *
1269 * ????? &nbsp; ??????? <br />?
1270 *
1271 * @param string $text
1272 *
1273 * @return string
1274 */
1275function t($text)
1276{
1277    return nl2br(str_replace(' ', '&nbsp;', htmlspecialchars($text)));
1278}
1279
1280/**
1281 * ?? JavaScript ???????????????????????
1282 *
1283 * ???
1284 * <code>
1285 * js_alert('Dialog message', '', $url);
1286 * // ??
1287 * js_alert('Dialog message', 'window.close();');
1288 * </code>
1289 *
1290 * @param string $message ??????
1291 * @param string $after_action ???????????
1292 * @param string $url ?????
1293 */
1294function js_alert($message = '', $after_action = '', $url = '')
1295{
1296    $out = "<script language=\"javascript\" type=\"text/javascript\">\n";
1297    if (!empty($message)) {
1298        $out .= "alert(\"";
1299        $out .= str_replace("\\\\n", "\\n", t2js(addslashes($message)));
1300        $out .= "\");\n";
1301    }
1302    if (!empty($after_action)) {
1303        $out .= $after_action . "\n";
1304    }
1305    if (!empty($url)) {
1306        $out .= "document.location.href=\"";
1307        $out .= $url;
1308        $out .= "\";\n";
1309    }
1310    $out .= "</script>";
1311    echo $out;
1312    exit;
1313}
1314
1315/**
1316 * ????????? JavaScript ??????????"?
1317 *
1318 * @param string $content
1319 *
1320 * @return string
1321 */
1322function t2js($content)
1323{
1324    return str_replace(array("\r", "\n"), array('', '\n'), addslashes($content));
1325}
1326
1327/**
1328 * safe_file_put_contents() ???????????????????????????????????????
1329 *
1330 * @param string $filename
1331 * @param string $content
1332 * @param int $flag
1333 *
1334 * @return boolean
1335 */
1336function safe_file_put_contents($filename, & $content)
1337{
1338    $fp = fopen($filename, 'wb');
1339    if ($fp) {
1340        flock($fp, LOCK_EX);
1341        fwrite($fp, $content);
1342        flock($fp, LOCK_UN);
1343        fclose($fp);
1344        return true;
1345    } else {
1346        return false;
1347    }
1348}
1349
1350/**
1351 * safe_file_get_contents() ???????????????????????????????????
1352 *
1353 * @param string $filename
1354 *
1355 * @return mixed
1356 */
1357function safe_file_get_contents($filename)
1358{
1359    $fp = fopen($filename, 'rb');
1360    if ($fp) {
1361        flock($fp, LOCK_SH);
1362        clearstatcache();
1363        $data = fread($fp, filesize($filename));
1364        flock($fp, LOCK_UN);
1365        fclose($fp);
1366        return $data;
1367    } else {
1368        return false;
1369    }
1370}
1371
1372if (!function_exists('file_put_contents'))
1373{
1374    function file_put_contents($filename, & $content)
1375    {
1376        return safe_file_put_contents($filename, $content);
1377    }
1378}
1379
1380/**
1381 * ??????????????
1382 */
1383
1384/**
1385 * ??????
1386 *
1387 * FleaPHP ???? PHP4????????????????????????????????
1388 * FleaPHP ?????????????
1389 *   - ? __TRY() ??? try ??????
1390 *   - ? __CATCH() ???????? catch?
1391 *   - ? __THROW() ?????
1392 *   - __TRY() ? __CATCH() ?????? PHP5 ?? throw ??????
1393 *   - ????? __THROW() ?????????? return false ????????????
1394 *   - __TRY() ? __CATCH() ????????? __CATCH() ?????????
1395 *   - ? __IS_EXCEPTION() ??? __CATCH() ????????????
1396 *   - ?? __TRY() ?????? __CATCH() ???????? __CANCEL_TRY() ?????
1397 *
1398 * ?? __THROW() ??????????????? FLEA_Exception ??????????
1399 * ???? FleaPHP ??????????? FLEA_Exception ????????????
1400 * FLEA_Exception ???????????????????????
1401 *
1402 * ?????????????????????
1403 * <code>
1404 * __TRY();
1405 * $ret = doSomething(); // ????????????
1406 * $ex = __CATCH();
1407 * if (__IS_EXCEPTION($ex)) {
1408 *     // ????
1409 * } else {
1410 *     echo $ret;
1411 * }
1412 *
1413 * function doSomething() {
1414 *     if (rand(0, 9) % 2) {
1415 *         __THROW(new MyException());
1416 *         return false;
1417 *     }
1418 *     return true;
1419 * }
1420 * </code>
1421 *
1422 * <strong>?????????? __THROW() ???????? return false</strong>
1423 *
1424 * ?? doSomething() ?? __THROW() ???????????????? doSomething() ?
1425 * ???????????????? doSomething() ?????????
1426 *
1427 * ???__TRY() ? __CATCH() ????????????
1428 *
1429 * <strong>?? __TRY() ? __CATCH() ??????</strong>
1430 *
1431 * FleaPHP ??? __TRY() ?????????????doSomething() ???????????
1432 * ???????? doSomething() ?????? __TRY() ? __CATCH() ??????
1433 *
1434 * <code>
1435 * function doSomething() {
1436 *     if (rand(0, 9) % 2) {
1437 *         __THROW(new MyException());
1438 *         return false;
1439 *     } else {
1440 *         __TRY();
1441 *         callAnotherFunc();
1442 *         $ex = __CATCH();
1443 *         if (__IS_EXCEPTION($ex)) {
1444 *             // ?? callAnotherFunc() ???????
1445 *             ...
1446 *             // ?????????? __THROW() ?????????
1447 *             // ??? doSomething() ?????????
1448 *             __THROW($ex);
1449 *             return false;
1450 *         }
1451 *         return true;
1452 *     }
1453 * }
1454 * </code>
1455 *
1456 * ???? __TRY() ??????? __CATCH() ????????? __CANCEL_TRY()
1457 * ??? __TRY() ???????
1458 *
1459 * @package Core
1460 *
1461 * @param FLEA_Exception $exception
1462 *
1463 * @return boolean
1464 */
1465function __THROW($exception)
1466{
1467    // ????
1468    if (function_exists('log_message')) {
1469        log_message(get_class($exception) . ': ' . $exception->getMessage(), 'exception');
1470    }
1471
1472    // ????????????
1473    if (isset($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']) && is_array($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']))
1474    {
1475        $point = array_pop($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']);
1476        if ($point != null) {
1477            array_push($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK'], $exception);
1478            $ret = false;
1479            return $ret;
1480        }
1481    }
1482
1483    if (isset($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_HANDLER'])) {
1484        call_user_func_array($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_HANDLER'], array(& $exception));
1485    } else {
1486        __FLEA_EXCEPTION_HANDLER($exception);
1487    }
1488    exit;
1489}
1490
1491/**
1492 * ???????
1493 *
1494 * @package Core
1495 */
1496function __TRY()
1497{
1498    static $point = 0;
1499    if (!isset($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']) ||
1500        !is_array($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']))
1501    {
1502        $GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK'] = array();
1503    }
1504
1505    $point++;
1506    array_push($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK'], $point);
1507}
1508
1509/**
1510 * ??????????????????? false
1511 *
1512 * @package Core
1513 *
1514 * @return FLEA_Exception
1515 */
1516function __CATCH()
1517{
1518    if (!is_array($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK'])) {
1519        return false;
1520    }
1521    $exception = array_pop($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']);
1522    if (!is_object($exception)) {
1523        $exception = false;
1524    }
1525    return $exception;
1526}
1527
1528/**
1529 * ?????? __TRY() ??????
1530 *
1531 * @package Core
1532 */
1533function __CANCEL_TRY()
1534{
1535    if (is_array($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK'])) {
1536        array_pop($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_STACK']);
1537    }
1538}
1539
1540/**
1541 * ?????????
1542 *
1543 * $type ?????????????????
1544 *
1545 * @package Core
1546 *
1547 * @param FLEA_Exception $exception
1548 * @param string $type
1549 */
1550function __IS_EXCEPTION($exception, $type = null)
1551{
1552    if (!is_object($exception) || !is_a($exception, 'FLEA_Exception')) {
1553        return false;
1554    }
1555    if (is_null($type)) {
1556        return true;
1557    } else {
1558        return strtoupper($type) == strtoupper(get_class($exception));
1559    }
1560}
1561
1562/**
1563 * ????????????????????????
1564 *
1565 * ?????????? __TRY() ??????????????FleaPHP ???
1566 * ????????????????????????????????????
1567 *
1568 * ???
1569 * <code>
1570 * // ?????????????
1571 * global $prevExceptionHandler;
1572 * $prevExceptionHandler = __SET_EXCEPTION_HANDLER('app_exception_handler');
1573 *
1574 * function app_exception_handler(& $ex) {
1575 *     global $prevExceptionHandler;
1576 *
1577 *     if (is_a($ex, 'APP_Exception')) {
1578 *        // ?????
1579 *        ...
1580 *     } else {
1581 *        // ???????????
1582 *        if ($prevExceptionHandler) {
1583 *            call_user_func_array($prevExceptionHandler, array(& $exception));
1584 *        }
1585 *     }
1586 * }
1587 * </code>
1588 *
1589 * ???????????????????????????????????????
1590 * ????????????????????????????????????????
1591 *
1592 * @package Core
1593 *
1594 * @param callback $callback
1595 *
1596 * @return mixed
1597 */
1598function __SET_EXCEPTION_HANDLER($callback)
1599{
1600    if (isset($GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_HANDLER'])) {
1601        $current = $GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_HANDLER'];
1602    } else {
1603        $current = null;
1604    }
1605    $GLOBALS[G_FLEA_VAR]['FLEA_EXCEPTION_HANDLER'] = $callback;
1606    return $current;
1607}
1608
1609/**
1610 * FleaPHP ?????????
1611 *
1612 * @package Core
1613 *
1614 * @param FLEA_Exception $ex
1615 */
1616function __FLEA_EXCEPTION_HANDLER($ex)
1617{
1618    if (!FLEA::getAppInf('displayErrors')) { exit; }
1619    if (FLEA::getAppInf('friendlyErrorsMessage')) {
1620        $language = FLEA::getAppInf('defaultLanguage');
1621        $language = preg_replace('/[^a-z0-9\-_]+/i', '', $language);
1622
1623        $exclass = strtoupper(get_class($ex));
1624        $template = FLEA_DIR . "/_Errors/{$language}/{$exclass}.php";
1625        if (!file_exists($template)) {
1626            $template = FLEA_DIR . "/_Errors/{$language}/FLEA_EXCEPTION.php";
1627            if (!file_exists($template)) {
1628                $template = FLEA_DIR . "/_Errors/default/FLEA_EXCEPTION.php";
1629            }
1630        }
1631        include($template);
1632    } else {
1633        print_ex($ex);
1634    }
1635    exit;
1636}
1637
1638/**
1639 * ?????????
1640 *
1641 * @package Core
1642 *
1643 * @param FLEA_Exception $ex
1644 * @param boolean $return ? true ???????????????
1645 */
1646function print_ex($ex, $return = false)
1647{
1648    $out = "exception '" . get_class($ex) . "'";
1649    if ($ex->getMessage() != '') {
1650        $out .= " with message '" . $ex->getMessage() . "'";
1651    }
1652    if (defined('DEPLOY_MODE') && DEPLOY_MODE != false) {
1653        $out .= ' in ' . basename($ex->getFile()) . ':' . $ex->getLine() . "\n\n";
1654    } else {
1655        $out .= ' in ' . $ex->getFile() . ':' . $ex->getLine() . "\n\n";
1656        $out .= $ex->getTraceAsString();
1657    }
1658
1659    if ($return) { return $out; }
1660
1661    if (ini_get('html_errors')) {
1662        echo nl2br(htmlspecialchars($out));
1663    } else {
1664        echo $out;
1665    }
1666
1667    return '';
1668}
1669
1670/**
1671 * ??????????????
1672 *
1673 * @package Core
1674 *
1675 * @param mixed $vars ??????
1676 * @param string $label
1677 * @param boolean $return
1678 */
1679function dump($vars, $label = '', $return = false)
1680{
1681    if (ini_get('html_errors')) {
1682        $content = "<pre>\n";
1683        if ($label != '') {
1684            $content .= "<strong>{$label} :</strong>\n";
1685        }
1686        $content .= htmlspecialchars(print_r($vars, true));
1687        $content .= "\n</pre>\n";
1688    } else {
1689        $content = $label . " :\n" . print_r($vars, true);
1690    }
1691    if ($return) { return $content; }
1692    echo $content;
1693    return null;
1694}
1695
1696/**
1697 * ?????????????????
1698 *
1699 * @package Core
1700 *
1701 * @return string
1702 */
1703function dump_trace()
1704{
1705    $debug = debug_backtrace();
1706    $lines = '';
1707    $index = 0;
1708    for ($i = 0; $i < count($debug); $i++) {
1709        if ($i == 0) { continue; }
1710        $file = $debug[$i];
1711        if ($file['file'] == '') { continue; }
1712        if (substr($file['file'], 0, strlen(FLEA_DIR)) != FLEA_DIR) {
1713            $line = "#<strong>{$index} {$file['file']}({$file['line']}): </strong>";
1714        } else {
1715            $line = "#{$index} {$file['file']}({$file['line']}): ";
1716        }
1717        if (isset($file['class'])) {
1718            $line .= "{$file['class']}{$file['type']}";
1719        }
1720        $line .= "{$file['function']}(";
1721        if (isset($file['args']) && count($file['args'])) {
1722            foreach ($file['args'] as $arg) {
1723                $line .= gettype($arg) . ', ';
1724            }
1725            $line = substr($line, 0, -2);
1726        }
1727        $line .= ')';
1728        $lines .= $line . "\n";
1729        $index++;
1730    } // for
1731    $lines .= "#{$index} {main}\n";
1732
1733    if (ini_get('html_errors')) {
1734        echo nl2br(str_replace(' ', '&nbsp;', $lines));
1735    } else {
1736        echo $lines;
1737    }
1738}
1739
1740/**
1741 * ??????????????
1742 *
1743 * @param mixed $time
1744 *
1745 * @return float
1746 */
1747function microtime_float($time = null)
1748{
1749    list($usec, $sec) = explode(' ', $time ? $time : microtime());
1750    return ((float)$usec + (float)$sec);
1751}
1752
1753/**
1754 * ???????????????
1755 *
1756 * ???????????? 'defaultLanguage' ??????????????
1757 * ?????????????????????????
1758 *
1759 * ??????????????????????? default ??????
1760 *
1761 * ? $appError ? true ??_ET() ??????????
1762 * 'languageFilesDir' ?????????????
1763 *
1764 * @package Core
1765 *
1766 * @param int $errorCode
1767 * @param boolean $appError
1768 *
1769 * @return string
1770 */
1771function _ET($errorCode, $appError = false)
1772{
1773    static $message = array();
1774
1775    $language = FLEA::getAppInf('defaultLanguage');
1776    $language = preg_replace('/[^a-z0-9\-_]+/i', '', $language);
1777
1778    if (!isset($message[$language])) {
1779        if ($appError) {
1780            $filename = FLEA::getAppInf('languageFilesDir') . DS .
1781                $language . DS . 'ErrorMessage.php';
1782        } else {
1783            // ?? FleaPHP ?????????
1784            $filename = FLEA_DIR . "/_Errors/{$language}/ErrorMessage.php";
1785        }
1786        if (!is_readable($filename)) {
1787            $filename = FLEA_DIR . '/_Errors/default/ErrorMessage.php';
1788        }
1789        $message[$language] = include($filename);
1790    }
1791
1792    return isset($message[$language][$errorCode]) ?
1793        $message[$language][$errorCode] :
1794        '';
1795}
1796
1797/**
1798 * PHP4 ? PHP5 ????????
1799 */
1800if (PHP5) {
1801
1802    class FLEA_Exception extends Exception
1803    {
1804        function FLEA_Exception($message = '', $code = 0)
1805        {
1806            parent::__construct($message, $code);
1807        }
1808    }
1809
1810} else {
1811
1812    /**
1813     * FLEA_Exception ????????
1814     *
1815     * ? PHP5 ??FLEA_Exception ??? PHP ??? Exception ??
1816     * ? PHP4 ???????????
1817     *
1818     * @package Exception
1819     * @author ???? (www.qeeyuan.com)
1820     * @version 1.0
1821     */
1822    class FLEA_Exception
1823    {
1824        /**
1825         * ????
1826         *
1827         * @var string
1828         */
1829        var $message = 'Unknown exception';
1830
1831        /**
1832         * ????
1833         */
1834        var $code = 0;
1835
1836        /**
1837         * ???????
1838         *
1839         * @var string
1840         */
1841        var $file;
1842
1843        /**
1844         * ?????????
1845         *
1846         * @var int
1847         */
1848        var $line;
1849
1850        /**
1851         * ????
1852         *
1853         * @var array
1854         */
1855        var $trac;
1856
1857        /**
1858         * ????
1859         *
1860         * @param string $message
1861         * @param int $code
1862         *
1863         * @return FLEA_Exception
1864         */
1865        function FLEA_Exception($message = null, $code = 0)
1866        {
1867            $this->message = $message;
1868            $this->code = $code;
1869            $this->trac = debug_backtrace();
1870
1871            // ??????????????
1872            $last = array_shift($this->trac);
1873            $this->file = $last['file'];
1874            $this->line = $last['line'];
1875        }
1876
1877        /**
1878         * ????????
1879         *
1880         * @return string
1881         */
1882        function getMessage()
1883        {
1884            return $this->message;
1885        }
1886
1887        /**
1888         * ????????
1889         *
1890         * @return int
1891         */
1892        function getCode()
1893        {
1894            return $this->code;
1895        }
1896
1897        /**
1898         * ??????????
1899         *
1900         * @return string
1901         */
1902        function getFile()
1903        {
1904            return $this->file;
1905        }
1906
1907        /**
1908         * ???????????
1909         *
1910         * @return int
1911         */
1912        function getLine()
1913        {
1914            return $this->line;
1915        }
1916
1917        /**
1918         * ??????
1919         *
1920         * @return array
1921         */
1922        function getTrace()
1923        {
1924            return $this->trac;
1925        }
1926
1927        /**
1928         * ????????????
1929         */
1930        function getTraceAsString()
1931        {
1932            $out = '';
1933            $ix = 0;
1934            foreach ($this->trac as $point) {
1935                $out .= "#{$ix} {$point['file']}({$point['line']}): {$point['function']}(";
1936                if (is_array($point['args']) && count($point['args']) > 0) {
1937                    foreach ($point['args'] as $arg) {
1938                        switch (gettype($arg)) {
1939                        case 'array':
1940                        case 'resource':
1941                            $out .= gettype($arg);
1942                            break;
1943                        case 'object':
1944                            $out .= get_class($arg);
1945                            break;
1946                        case 'string':
1947                            if (strlen($arg) > 30) {
1948                                $arg = substr($arg, 0, 27) . ' ...';
1949                            }
1950                            $out .= "'{$arg}'";
1951                            break;
1952                        default:
1953                            $out .= $arg;
1954                        }
1955                        $out .= ', ';
1956                    }
1957                    $out = substr($out, 0, -2);
1958                }
1959                $out .= ")\n";
1960                $ix++;
1961            }
1962            $out .= "#{$ix} {main}\n";
1963
1964            return $out;
1965        }
1966
1967        /**
1968         * ??????????
1969         *
1970         * @return string
1971         */
1972        function __toString()
1973        {
1974            $out = "exception '" . get_class($this) . "'";
1975            if ($this->message != '') {
1976                $out .= " with message '{$this->message}'";
1977            }
1978            $out .= " in {$this->file}:{$this->line}\n\n";
1979            $out .= $this->getTraceAsString();
1980            return $out;
1981        }
1982    }
1983
1984}
1985
1986/**
1987 * Ajax ?????
1988 */
1989 /**
1990 * ????? PHP ??? JSON ?????? PEAR::Service_JSON ??? JSON ??????
1991 *
1992 * ?????? PHP ???? JSON ?????????????
1993 */
1994
1995if (!function_exists('json_encode')) {
1996    /**
1997     * ?????? JSON ???
1998     *
1999     * @param mixed $value
2000     *
2001     * @return string
2002     */
2003    function json_encode($value)
2004    {
2005        static $instance = array();
2006        if (!isset($instance[0])) {
2007            require_once(FLEA_DIR . '/Ajax/JSON.php');
2008            $instance[0] =& new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
2009        }
2010        return $instance[0]->encode($value);
2011    }
2012}
2013
2014if (!function_exists('json_decode')) {
2015    /**
2016     * ? JSON ????????
2017     *
2018     * @param string $jsonString
2019     *
2020     * @return mixed
2021     */
2022    function json_decode($jsonString)
2023    {
2024        static $instance = array();
2025        if (!isset($instance[0])) {
2026            require_once(FLEA_DIR . '/Ajax/JSON.php');
2027            $instance[0] =& new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
2028        }
2029        return $instance[0]->decode($jsonString);
2030    }
2031}