Хочу рассказать вам про интересный опыт, с которым я столкнулся на своей последней работе. Нужна была гибкая система Environment-ов. После некоторого времени экспериментов я таки добился идеального варианта. Перейдем сразу к делу.
В protected я создал environment.php c такими вот 2я классами:
class Environment { /** * */ const PRODUCTION = 10; /** * */ const STAGING = 20; /** * */ const TESTING = 30; /** * */ const DEVELOPMENT = 40; /** * @var int */ protected static $current; /** * @var */ private static $currentObj; /** * */ public static function instance() { if(!self::$currentObj) { self::$currentObj = new self(); } return self::$currentObj; } /** * @param int $ENV * @return bool */ public function set($ENV = Environment::DEVELOPMENT) { if(self::$current) { return false; } if(isset($_GET['DEBUG'])) { $this->setEnvironment($_GET['DEBUG']); $_SESSION['systemEnvironment'] = $_GET['DEBUG']; } elseif(isset($_SESSION['systemEnvironment']) and $_SESSION['systemEnvironment'] !== 'off') { $this->setEnvironment($_SESSION['systemEnvironment']); } else { self::$current = $ENV; } return true; } /** * @return int */ public static function getCurrent() { return self::$current; } /** * @param $level */ private function setEnvironment($level) { switch($level) { case 'PRODUCTION': self::$current = self::PRODUCTION; break; case 'STAGING': self::$current = self::STAGING; break; case 'TESTING': self::$current = self::TESTING; break; case 'DEVELOPMENT': self::$current = self::DEVELOPMENT; break; case 'off': if(isset($_SERVER['ENVIRONMENT'])) { self::$current = constant('Environment::' . strtoupper($_SERVER['ENVIRONMENT'])); } $_SESSION['systemEnvironment'] = null; break; } } } /** * Class EnvironmentUtils */ class EnvironmentUtils extends Environment { /** * @param $rootDirectory * @param $fileName * @return string */ public static function getConfigFile($rootDirectory, $fileName) { $fileLink = $rootDirectory . '/config/'; switch(parent::$current) { case Environment::DEVELOPMENT: $fileLink .= 'Development/'; break; case Environment::PRODUCTION: $fileLink .= 'Production/'; break; case Environment::STAGING: $fileLink .= 'Staging/'; break; case Environment::TESTING: $fileLink .= 'Testing/'; break; } return $fileLink . $fileName; } }
После чего немного изменил структуру файлов в папке config:
│ ├── API
│ │ ├── Morpher.php
│ │ └── XmlRpcClient.php
│ ├── Common
│ │ ├── Daemon.php
│ │ ├── Email.php
│ │ └── Filtrator.php
│ ├── console.php
│ ├── DB
│ │ ├── 1c.php
│ │ └── BaseConnect.php
│ ├── main.php
│ ├── routes.php
├── Development
│ ├── cli.php
│ ├── DB
│ │ ├── 1c.php
│ │ ├── BaseConnect.php
│ └── Web.php
├── Production
│ ├── cli.php
│ ├── DB
│ │ ├── 1c.php
│ │ ├── BaseConnect.php
│ │ ├── Sape.php
│ └── Web.php
├── Staging
│ ├── cli.php
│ ├── DB
│ │ ├── 1c.php
│ │ ├── BaseConnect.php
│ └── Web.php
└── Testing
├── cli.php
├── DB
│ ├── 1c.php
│ └── BaseConnect.php
└── Web.php
В Base/Web.php находится базовый конфиг. Из серии:
return [ 'basePath' => PROTECTED_PATH, 'name' => 'MyApp', 'theme' => 'classic', 'language' => 'ru', 'defaultController' => 'user/login', // preloading 'log' component // autoloading model and component classes 'aliases' => [ 'bootstrap' => PROTECTED_PATH.'extensions/bootstrap', // change this if necessary ], 'preload' => [ 'log', 'bootstrap' ], 'import' => [ 'application.models.*', ]
Тоже самое в cli.php. А вот в Production/Web.php чтоб не копировать постоянно какой то параметр если меняешь, я сделал так:
return CMap::mergeArray(include(PROTECTED_PATH.'config/Base/main.php'), [ 'components'=> [ 'db' => include(dirname(__FILE__) . '/DB/BaseConnect.php'), 'db1c' => include(dirname(__FILE__) . '/DB/1c.php') ] ] );
Таким образом я просто перезаписываю настройки бд, ну или то, что мне нужно. Теперь самое интересное. Подгрузка. index.php.
P.S.: У меня в проекте ядро yii тянется через composer:
define("PROTECTED_PATH",realpath(dirname(__FILE__)).'/protected/'); if(!file_exists(PROTECTED_PATH.'vendor/autoload.php')) { die('autoload.php not found. Composer update!'); } require_once(PROTECTED_PATH.'vendor/autoload.php'); require_once(PROTECTED_PATH.'environment.php'); if(isset($_SERVER['HTTP_ORIGIN'])) { if(in_array($_SERVER['HTTP_ORIGIN'],[....])) { header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT'); header('Access-Control-Max-Age: 1728000'); header('Access-Control-Allow-Credentials: true'); header("Access-Control-Allow-Headers: access-token, expiry, token-type, uid, client"); header("Access-Control-Expose-Headers: access-token, expiry, token-type, uid, client"); } } if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("HTTP/1.0 204 No Content"); die(); } Environment::instance()->set(Environment::DEVELOPMENT); switch(Environment::getCurrent()) { case Environment::DEVELOPMENT: define('YII_DEBUG', false); define('YII_SKIP_AUTH', true); define('YII_KERNEL_LOG', true); define('DISPLAY_ERROR_TRACE', true); define('YII_TRACE_LEVEL', 0); define('MINIFY_INTERFACE', false); error_reporting(E_ALL); ini_set('display_errors','On'); break; case Environment::PRODUCTION: define('YII_DEBUG', false); define('YII_SKIP_AUTH', false); define('YII_KERNEL_LOG', false); define('DISPLAY_ERROR_TRACE', false); define('YII_TRACE_LEVEL', 3); define('MINIFY_INTERFACE', true); error_reporting(0); ini_set('display_errors','Off'); break; case Environment::STAGING: define('YII_DEBUG', true); define('YII_SKIP_AUTH', false); define('YII_KERNEL_LOG', true); define('DISPLAY_ERROR_TRACE', true); define('YII_TRACE_LEVEL', 0); error_reporting(E_ALL); ini_set('display_errors','On'); break; } /** @noinspection PhpUndefinedClassInspection */ Yii::$enableIncludePath = true; //For init Yii kernel $config = EnvironmentUtils::getConfigFile(PROTECTED_PATH,'Web.php'); //Other constants define('DATE_FORMAT', 'Y/m/d'); define('STATUS_NOACTIVE', 0); define('STATUS_ACTIVE', 1); date_default_timezone_set("Europe/Kiev"); /** @noinspection PhpUndefinedClassInspection */ Yii::createWebApplication($config)->run();
По аналогии сделано и в cli.php. Система себя отлично зарекомендовала.
ссылка на оригинал статьи http://habrahabr.ru/post/264877/
Добавить комментарий