Скрипт подмены конфигов сайта на лету

Надоело каждый раз при переносе сайтов между серверами прописывать конфиги в нескольких местах. Каждый раз напрягаешься, чтобы не перепутать. Написал скрипт, который делает это автоматически в зависимости от $_SERVER['HTTP_HOST'] сервера на котором он запускается. Нужно лишь поправить один раз в конструкции switch переменные для каждого сервера, и пути ниже, если они отличаются от стандартных. И потом можно перетаскивать сайт с места на место, открывать страничку в браузере, а скрипт автоматически заменит файлы конфигов и почистит кеш. Закомментированные шаблоны файлов находятся прямо в нём, чтобы всё уместилось в одном файле. Ну в общем, думаю сами разберётесь.

Назовём файл migration.php поместим в корень сайта.

Предупреждение. Если что-то пошло не так, ко мне никаких претензий, что сайт перестал работать. Кто вообще не понимает в PHP, лучше делайте как привыкли) . По сути скрипт только 4 файла заменяет и чистит кеш.

<?php

header('Content-Type: text/html; charset=utf-8');

$params = [];      // список переменных для подстановки в шаблоны файлов
$params['database_port'] = '3306';

switch ($_SERVER['HTTP_HOST']) {
    case 'site.loc':
        $params['database_server'] = 'localhost';
        $params['dbase'] = 'dbname';
        $params['database_user'] = 'dbuser';
        $params['database_password'] = 'dbpassword';
        break;

    case 'site.ru':
        $params['database_server'] = 'localhost';
        $params['dbase'] = 'dbname';
        $params['database_user'] = 'dbuser';
        $params['database_password'] = 'dbpassword';
        break;

    default:
        exit;
}

$params['table_prefix'] = 'modx_';
$params['core_url'] = '/core/';
$params['connectors_url'] = '/connectors/';
$params['manager_url'] = '/manager/';
$params['assets_url'] = '/assets/';

/***************************************************************************/

$base_path = __DIR__;
$params['host'] = $_SERVER['HTTP_HOST'];
$params['base_path'] = $base_path . '/';
$params['base_url'] = '/';
$params['core_path'] = $base_path . $params['core_url'];
$params['manager_path'] = $base_path . $params['manager_url'];
$params['connectors_path'] = $base_path . $params['connectors_url'];
$params['assets_path'] = $base_path . $params['assets_url'];
$params['processors_path'] = $params['core_path'] . 'model/modx/processors/';

$markers = [];      // какой файл какому куску кода между маркерами соответствует
$markers[ $params['connectors_path'] . 'config.core.php' ] = 'config';
$markers[ $params['manager_path'] . 'config.core.php' ] = 'config';
$markers[ $params['base_path'] . '/config.core.php' ] = 'config';
$markers[ $params['core_path'] . 'config/config.inc.php' ] = 'core_config';

if( $params['database_port'] ) {
    $params['db_port'] = ':' . $params['database_port'];
} else {
    $params['db_port'] = '';
}

//echo '<pre>' . print_r($markers, 1) . '</pre>';
//echo '<pre>' . print_r($params, 1) . '</pre>';
//echo '<pre>' . print_r($_SERVER, 1) . '</pre>';

$thisfile = file_get_contents(__FILE__);
foreach ($markers as $path => $marker) {
    preg_match("#.+-----{$marker}-----[\r\n\s]*(.+)[\r\n\s]*-----{$marker}-----.+#sm", $thisfile, $matches);
    $file = $matches[1];
    foreach ($params as $key=>$value) {
        $file = str_replace("{%{$key}%}", $value, $file);
    }
    file_put_contents($path, $file);
}

// чистим папку кеша
function RDir( $path ) {
    if ( file_exists( $path ) AND is_dir( $path ) ) {
        $dir = opendir($path);
        while ( false !== ( $element = readdir( $dir ) ) ) {
            if ( $element != '.' AND $element != '..' )  {
                $tmp = $path . '/' . $element;
                if ( is_dir( $tmp ) ) {
                    RDir( $tmp );
                } else {
                    unlink( $tmp );
                }
            }
        }
        closedir($dir);
        if ( file_exists( $path ) ) {
            rmdir( $path );
        }
    }
}
RDir( $params['core_path'] . 'cache/' );


echo '<a href="/">' . $_SERVER['HTTP_HOST'] . '</a>   ';

$mysqli = new mysqli($params['database_server'], $params['database_user'], $params['database_password'], $params['dbase'], $params['database_port'] );

if (mysqli_connect_errno()) {
    printf('Connect failed: %s\n', mysqli_connect_error());
} else {
    echo 'cоединение с БД установлено! ';
}
echo "\r\n";

/* Шаблон файлов config.core.php лежащих в корне, manager и connectors
-----config-----
<?php
define('MODX_CORE_PATH', '{%core_path%}');
define('MODX_CONFIG_KEY', 'config');
?>
-----config----- */

/* Шаблон файла core.config.inc
-----core_config-----
<?php

$database_type = 'mysql';
$database_server = '{%database_server%}{%db_port%}';
$database_user = '{%database_user%}';
$database_password = '{%database_password%}';
$database_connection_charset = 'utf8';
$dbase = '{%dbase%}';
$table_prefix = '{%table_prefix%}';
$database_dsn = 'mysql:host={%database_server%}{%db_port%};dbname={%dbase%};charset=utf8';
$config_options = array (
);
$driver_options = array (
);

$lastInstallTime = 1571553474;

$site_id = 'modx5dac00c2023563.39300708';
$site_sessionname = 'SN5bf2a43920e0f';
$https_port = '443';
$uuid = '2ddc828e-9ca5-401b-9cb9-f5883e2fd6ff';

if (!defined('MODX_CORE_PATH')) {
    $modx_core_path= '{%core_path%}';
    define('MODX_CORE_PATH', $modx_core_path);
}
if (!defined('MODX_PROCESSORS_PATH')) {
    $modx_processors_path= '{%processors_path%}';
    define('MODX_PROCESSORS_PATH', $modx_processors_path);
}
if (!defined('MODX_CONNECTORS_PATH')) {
    $modx_connectors_path= '{%connectors_path%}';
    $modx_connectors_url= '{%connectors_url%}';
    define('MODX_CONNECTORS_PATH', $modx_connectors_path);
    define('MODX_CONNECTORS_URL', $modx_connectors_url);
}
if (!defined('MODX_MANAGER_PATH')) {
    $modx_manager_path= '{%manager_path%}';
    $modx_manager_url= '{%manager_url%}';
    define('MODX_MANAGER_PATH', $modx_manager_path);
    define('MODX_MANAGER_URL', $modx_manager_url);
}
if (!defined('MODX_BASE_PATH')) {
    $modx_base_path= '{%base_path%}';
    $modx_base_url= '{%base_url%}';
    define('MODX_BASE_PATH', $modx_base_path);
    define('MODX_BASE_URL', $modx_base_url);
}
if(defined('PHP_SAPI') && (PHP_SAPI == "cli" || PHP_SAPI == "embed")) {
    $isSecureRequest = false;
} else {
    $isSecureRequest = ((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') || $_SERVER['SERVER_PORT'] == $https_port);
}
if (!defined('MODX_URL_SCHEME')) {
    $url_scheme=  $isSecureRequest ? 'https://' : 'http://';
    define('MODX_URL_SCHEME', $url_scheme);
}
if (!defined('MODX_HTTP_HOST')) {
    if(defined('PHP_SAPI') && (PHP_SAPI == "cli" || PHP_SAPI == "embed")) {
        $http_host='{%host%}';
        define('MODX_HTTP_HOST', $http_host);
    } else {
        $http_host= array_key_exists('HTTP_HOST', $_SERVER) ? htmlspecialchars($_SERVER['HTTP_HOST'], ENT_QUOTES) : '{%host%}';
        if ($_SERVER['SERVER_PORT'] != 80) {
            $http_host= str_replace(':' . $_SERVER['SERVER_PORT'], '', $http_host); // remove port from HTTP_HOST
        }
        $http_host .= ($_SERVER['SERVER_PORT'] == 80 || $isSecureRequest) ? '' : ':' . $_SERVER['SERVER_PORT'];
        define('MODX_HTTP_HOST', $http_host);
    }
}
if (!defined('MODX_SITE_URL')) {
    $site_url= $url_scheme . $http_host . MODX_BASE_URL;
    define('MODX_SITE_URL', $site_url);
}
if (!defined('MODX_ASSETS_PATH')) {
    $modx_assets_path= '{%assets_path%}';
    $modx_assets_url= '{%assets_url%}';
    define('MODX_ASSETS_PATH', $modx_assets_path);
    define('MODX_ASSETS_URL', $modx_assets_url);
}
if (!defined('MODX_LOG_LEVEL_FATAL')) {
    define('MODX_LOG_LEVEL_FATAL', 0);
    define('MODX_LOG_LEVEL_ERROR', 1);
    define('MODX_LOG_LEVEL_WARN', 2);
    define('MODX_LOG_LEVEL_INFO', 3);
    define('MODX_LOG_LEVEL_DEBUG', 4);
}
-----core_config-----*/
Николай
25 октября 2019, 10:17
modx.pro
14
2 036
+13
Поблагодарить автора Отправить деньги

Комментарии: 17

iWatchYouFromAfar
25 октября 2019, 10:29
0
Круто! А шаблоны вы для примера показали? Или они тоже что-то выполняют в данном скрипте?
    Николай
    25 октября 2019, 10:35
    +1
    Код в файлах конфигов заменяется на эти шаблоны, там если приглядеться есть переменные типа {%database_user%}, которые заменяются реальными значениями в зависимости от сервера. То есть скрипт парсит шаблон из самого себя) Лучше открыть в редакторе, там где шаблоны эти куски кода закомментированны, а тут на сайте этого не видно.
      iWatchYouFromAfar
      25 октября 2019, 10:44
      0
      Понял, спасибо! На выходных протестирую скрипт, как раз нужно копию рабочего проекта развернуть. Если скрипт заведется, с меня плюха.
    Николай
    25 октября 2019, 12:43
    0
    Небольшой косячок был исправлен)
      Семён Кудрявцев
      25 октября 2019, 13:00
      0
      Попробовал, но при таком свиче у меня всегда отрабатывает только второй кейс, и соответственно параметры базы не перезаписываются на нужные. Всё остальное вроде работает норм.
        Семён Кудрявцев
        25 октября 2019, 13:01
        0
        Всё теперь вижу в заметке появились исправления) спасибо!
          Николай
          25 октября 2019, 13:09
          0
          Да, я поторопился, свичами редко как-то пользуюсь, всё время из головы вылетает как они пишутся и как работают) Пожалуйста
        Николай
        25 октября 2019, 13:59
        +4
        Расскажу одну историю связанную с этим скриптом, поучительную, и со счастливым концом)) Короче, доделал сайт, замотался с ним, недели на 3 растянулось, сроки уже к критической отметке приближаются. Вчера договорился, что перенесу. Ну и вспомнил старую идею насчёт этого скрипта, типа сейчас напишу, и как раз опробую в деле. Дело уже ночью было, голова с трудом соображала. В попыхах в строке про чистку кеша:

        RDir( $params['core_path'] . 'cache/' );

        забыл дописать 'cache/', запускаю скрипт… И тут на моих глазах все папки в core по очереди куда-то исчезают, а там лежит 80% работы. Всё на файлах было)) Сразу не понял, а потом когда дошло, спохватился, но было поздно… У меня аж адреналин подскочил как в момент опасности. Я уже трясущимися руками метаюсь в корзину, но… там ничего, оно и понятно, ведь папки удалил скрипт работающий в linux (подсистема винды), а не сама винда. Одна часть меня говорит: да ладно, быть такого не может, чтобы нельзя было обратно вернуть. А другая понимает, что так оно и есть)) И резервных копий нет, точнее есть одна, но слишком старая. И тут я начинаю представлять, что меня ждёт впереди: недели 2+ интенсивной работы за бесплатно, объяснения с заказчиком, а того будет трясти клиент… Ну думаю писец, попал… первый раз такой косяк. А потом вспоминаю, что в шторме была история файлов. Я ей не пользовался никогда, даже толком и не знал возможности. Немного поковырявшись, восстановил полностью весь сайт на момент до этого косяка. Шторм спас меня))

        Выводы: делать резервные копии регулярно, пользоваться гитом, не работать сверх меры, phpStorm — лучшая прога, а VSCode и тому подобные редакторы, это просто удобные редакторы.
          Miša Bulic
          25 октября 2019, 23:12
          0
          На модхост такую кнопочку в админку бы прикрутить, тем более там через поля уже все переменные можно ввести.
            Ivan
            06 ноября 2019, 23:42
            0
            Странно почему там просто не прописан $_SERVER['DOCUMENT_ROOT'], ну а кому нужно уже менял бы на другие пути…
              Max
              Max
              30 июня 2020, 15:49
              0
              Добрый день! Попробовал ваш скрипт, но он просто удалил из файлов конфигов все содержимое, в шторме откатил все назад (конечно проект тестовый, но все же), блин, не понимаю в чем причина (((
                Николай
                01 июля 2020, 01:09
                +1
                Я пользуюсь на постоянной основе, работает как часы. Но правда были какие-то косяки с регуляркой. Обновил заметку, попробуйте мой текущий вариант. Нужно указать пути и настройки БД до звёздочек.
                  Max
                  Max
                  01 июля 2020, 10:52
                  0
                  Заработал вроде, переносить с ним еще не пробовал, но вроде все подменяет как нужно, по win правда нужно слэши в обратную сторону менять в путях, а такой слэш экранирует кавычку и стринга, делаю два подряд ('\core\\'), вроде работает, хотя перенос на win это редкость, обычно с win на хостинг.
                  Спасибо за скрипт, думаю оч облегчит работу по переносу!
                    Николай
                    01 июля 2020, 11:45
                    0
                    Это конечно усложняет дело. Виндой вообще не пользуюсь. В крайнем случае можно WSL использовать. Всё-таки родная среда для большинства сайтов это Linux.
                      Max
                      Max
                      01 июля 2020, 11:48
                      0
                      Пока что привычка сильнее, но уже задумываюсь над переходом хотя бы на Linux Mint, был не большой опыт, использовал около 2 месяцев, но не зашел, много очень привычного софта осталось в win, поэтому пока вернулся на нее
                        Николай
                        01 июля 2020, 11:55
                        0
                        В таком случае данный вариант как компромисс — Установка локального веб-сервера на подсистему Windows для Linux
                          Max
                          Max
                          01 июля 2020, 12:02
                          0
                          Вариант, но блин запаришься с настройками))) думаю проще пилить уже на хостинге на субдомене своего сайта, чанки и сниппеты делать файловыми, и пилить их в любой IDE локально, но сейчас работаю на даче, и с приездом дачников, скорость инета иногда проседает, поэтому пришлось пока переехать на локальный OpenServer, дальше буду смотреть как будет работать, склоняюсь все же к переезду на линукс, хотя бы на виртуальной машине для начала
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                17