Изменяем файлы с помощью Phing

Владимир | | Phing, Web разработка.

phing search replace

На сегодняшний день большинство web приложений содержит множество конфигурационных файлов с различными настройками. Например, имя домена, параметры подключения к базе данных, размещение библиотек и т.д.

В принципе, это довольно удобно, т.к. эти файлы можно легко отредактировать с помощью обычного текстового редактора. Но проблема в том, что редактировать их приходится постоянно.

Представьте ситуацию. Вы делаете сайт, сначала тестируете его локально, а затем переносите на сервер. Естественно, перед загрузкой на сервер нужно будет как минимум изменить параметры подключения к БД.

Затем вы находите ошибку (или просто решаете что-то изменить) и процесс повторяется заново.

Каждый раз менять настройки вам быстро надоест, особенно если изменить нужно не один файл, а несколько. Да и забыть что-то очень легко.

В этой статье я покажу небольшой пример как с помощью Phing можно автоматизировать такие операции.

Примечание. Почитать о том что такое Phing и зачем нужен можно здесь.

Прежде всего, сформулируем задачу.

Чтобы ничего не придумывать я возьму пример из предыдущей статьи. Напомню, речь там шла об использовании Яндекс.Карт.

Дело в том, что для вставки карты на свой сайт нужно получить у Яндекса специальный API-ключ, который выдается для каждого домена отдельно. Т.е. ключ, полученный для mydomen.local, не будет работать на mydomen.com.

Таким образом, перед переносом страницы с картой на сервер нужно изменить этот ключ.

UPD. Когда я практически дописывал этот пост пришел комментарий к предыдущей статье от Андрея Кармацкого, в котором он рассказал, что api-ключ, полученный для любого домена, будет работать и на localhost.

Напомню, ключ указывается внутри тега script в заголовке страницы.

<script src="http://api-maps.yandex.ru/1.0/index.xml?key=key_for_local_domen" type="text/javascript"></script>

Здесь нам нужно key_for_local_domen заменить на новый ключ.

Посмотрим как с помощью Phing решить эту задачу.

Создаем в корне проекта файл с названием build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="IPLocYandexMaps" default="deploy" basedir=".">
	
	<property name="DEPLOY_DIR" value="deploy" />
	<property name="SRC_DIR" value="public_html" />
	<property name="DEPLOY_KEY" value="api-key-for-my-host" />
	
	<target name="prepare">
		<echo msg="Removing old files..." />
		<delete dir="${DEPLOY_DIR}" includeemptydirs="true" verbose="true" failonerror="true" />
		<echo msg="Creating new dir..." />
		<mkdir dir="${DEPLOY_DIR}" />
	</target>
	
	<target name="copyfiles" depends="prepare">
		<echo msg="Copying main files..." />
		<copy todir="${DEPLOY_DIR}">
			<fileset dir="${SRC_DIR}">
				<include name="index.php" />
			</fileset>
			<filterchain>
				<replaceregexp>
					<regexp pattern="index.xml\?key=(.*?)"" replace="index.xml?key=${DEPLOY_KEY}"" />
				</replaceregexp>
			</filterchain>
		</copy>
	</target>

	<target name="deploy" depends="copyfiles">
	</target>
</project>

Теперь рассмотрим как это все работает.

В начале (строки 4-6) мы объявили три константы:
DEPLOY_DIR – имя папки, в которой будет размещен измененный файл (в данном примере – index.php);
SRC_DIR – имя папки с исходным файом;
DEPLOY_KEY – API-ключ.

Затем мы написали операцию prepare (строки 8-13). Она сначала удаляет папку ${DEPLOY_DIR} со всем содержимым, и сразу же создает её заново. Такой подход гарантирует, что если мы решим изменить имя файла со страницей, то в папке deploy не останется файл со старым именем.

И, самое интересное, операция copyfiles.

Сначала мы создаем задачу копирования (тег copy, строка 17) и указываем какие файлы нужно скопировать (в данном случае это только один файл – index.php).

После этого добавляем задачу filterchain (строки 21-25), т.е. создаем цепочку фильтров, которая будет применена к каждому копируемому файлу.

Чтобы заменить ключ нам хватит всего одного фильтра, который выполнит замену на основе регулярного выражения (строки 22-24). Фильтр создаем с помощью тегов replaceregexp и regexp.

Для regexp нужно задать параметры в атрибутах:

pattern – регулярное выражение;
replace – текст на который будет заменен результат поиска.

Вот и все, теперь с помощью этого build файла мы сможем изменять ключ буквально одним нажатием кнопки.

Примечание. Последняя операция сама по себе ничего не делает, а просто запускает предыдущие.

Кстати, есть ещё одно преимущество такого подхода. Т.к. Phing копирует файл с новым ключом в отдельную папку, то ваша локальная версия страницы остается в рабочем состоянии.

Представьте сколько времени можно сэкономить если вам нужно заниматься поддержкой страниц с такими картами на десятке разных доменов 😉

Удачи!

Интересно почитать.

Оригинальные и очень красивые отделочные материалы — РБО и сайдинг бамбуковый.
Создаем собственный микроклимат с помощью BIOCLIMATIC.

  • arygroup

    Дякую! Прочитав всі статті про phing. Дуже дякую!

    Скажи, а є можливість робити арифметичні дії?

    Задача в мене така. Роблю розширення під джумлу. Воно розкидано по локальній версії джумли, я час від часу його збираю в архів. І хочу при кожній збірці в файлі розширення вписувати, це збірка номер така-то.

    Для цього я в спеціальному файлі, скажімо в conf.ini, який підключаю в мій проект (там зберігаю налаштування шляхів, назви і т.д.) зокрема маю рядок
    buildnumber=1
    При кожному запуску phing-проекта я теоретично можу зкопіювати conf.ini в самого себе, замінивши регулярним виразом buildnumber=1 на buildnumber=2
    Але як мені додавати автоматичо кожен раз одиницю до buildnumber?

    Наскільки я розумію, засобами самого phing неможливо. Або писати спеціальний task, або просту програму на php, що змодифікує мій buildnumber в conf.ini, яку запускати з у phing-проекті. Перший варіант виглядає занадто громіздким заради додавання одинички, а другий вилазить з логіки phingа.

    Підкажи чи поправ. Дякую!

    • Не за что 🙂
      Вообще таски Phing очень удобный инструмент и создавать их не сложно. Если интересно, у меня есть пост на эту тему.