PHP

индекс
206,80

#ifdef в PHP

В своем проекте мне понадобилось собирать различные версии исходников. Причём так что бы в различных сборках помещались различные куски кода. if-else мне здесь не подходил, потому что нужно было что бы код либо точно входил, либо не входил в сборку.

Решение


Поэтому я решил использовать директивы #ifdef/#endif. Для их реализации я создал небольшую программку на C#, которая обрабатывает эти директивы. В программе нужно указать исходный файл или папку, и папку куда нужно помещать готовый результат. На наличие директив обрабатываются только php файлы, остальные просто копируются.
PHP Ifdef Collector PrintScreen

Работа программы


Программа имеет глобальный массив defines, который создаётся из третьего поля («Defines (comma separated)»). Этот массив может быть дополнен директивой «#define TEXT» в php коде.
Программа умеет обрабатывать следующие директивы: «#ifdef TEXT», «#ifndef TEXT». Первая включает код если директива определена, вторая включает если не определена. Эти директивы обязательно должны иметь закрывающие «#endif».
Так же программа умеет обрабатывать «#else» и вложенность этих директив.

Заключение


Поскольку в php символ «#» определяет комментарий, то код может быть выполнен и без вырезания этих директив.
Однако, если использовать «#ifdef — #else — #endif» с кодом выполняющим различные действия с одними и теми же данными, то нужно закомментировать одно из этих действий для его выполнения без вырезания директив примерно следующим образом:

<?php
#ifdef COPY

$chat_page = new View('copy');
$chat_page->SetVars(array('copyright' => $this->Copyright()));
$this->html = $chat_page->Get();
$this->Display();

/*#else

$this->html = View('no_copy')::Call();
$this->Display();

*/#endif
?>


Скачать программу можно здесь: phpifdef.googlecode.com/files/Php%20Ifdef%20Collector.exe
Исходники программы тут: code.google.com/p/phpifdef/
–11
3 марта 2010, 13:59
1

комментарии (23)

НЛО прилетело и опубликовало эту надпись здесь
0
Elfet #
Просто у меня есть папка в которой я делаю свой проект, использую эти директивы, могу сразу посмотреть что получается. А затем когда хочу выложит готовую версию (обычно я сразу 3 различные версии выкладываю) то использую эту программку.
+2
fozzy #
Ну вот перед тем как выкладывать пропускаете через Сишный препроцессор… За старания конечно +, но зачем изобретать велосипед?
GNU C Preprocessor docs
+1
DevMan #
Думается не все знают, что такое «Сишный препроцессор» и с чем его едят.
–1
Elfet #
Я знаю что такое «Сишный препроцессор», но я не знал что им можно вот так-вот воспользоваться. Спасибо :)
0
DevMan #
Я в смысле, что получилась удобная для некоторых утилита, не требующая наличия компилятора в системе.
+1
DevMan #
Наверное имелось в виду, что наличие этих меток никак не скажется на работоспособности кода.
0
silentroach #
а почему стандартные define не использовать?
0
Elfet #
Потому что мне нужно что бы код в различных версия скрипта либо присутствовал, либо нет.
0
inkover #
Есть поддержка вложенности IFов?

Условие насколько сложным может быть? Или они только как boolean-флаги?
0
Elfet #
Да, поддержка вложенных if-ов есть.

Условия только самые простые. Только один флаг. Я поэтому и назвал их как «#ifdef», а не просто «#if»
0
forefinger #
В приведенном примере, думается, нужно будет заменить кусок "/*#else" на "#else /*", так как после вырезания директив получается висящий в воздухе либо начало комментария, либо конец.
0
Elfet #
Не, в примере всё правильно. Я забыл указать что директивы врезаются вместе со стройками на которых они находятся.
0
forefinger #
Ну или так =)
НЛО прилетело и опубликовало эту надпись здесь
0
Elfet #
Нет, почему это? :)
–1
tzlom #
<?php
define('COPY',true);

if(defined('COPY'))
{

$chat_page = new View('copy');
$chat_page->SetVars(array('copyright' => $this->Copyright()));
$this->html = $chat_page->Get();
$this->Display();

}else{

$this->html = View('no_copy')::Call();
$this->Display();

}
?>
+1
Elfet #
Это код будет включён во все версии исходников, а мне же нужно было что бы в разные версии исходников включался разный код.
НЛО прилетело и опубликовало эту надпись здесь
0
graber #
раскидать код по разным файлам/папкам. включать в сборку только нужную папку

в самом примитивном случае выглядит так:

define('DIR_CONTROLLER', COPY ? '/copy' : '/standart');
require_once DIR_CONTROLLER . '/index.php';

0
Elfet #
можно и так, мне больше по душе вариант с #ifdef
+1
graber #
остается только надеяться, что ваш код никто не будет поддерживать потом. а то он очень удивится :)
–1
Elfet #
О, да! :) Эту штуку я использую только для себя.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.