Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Патч модуля bcompiler для PHP 5.4

Мы тут по работе пытаемся закешировать байт-код некоторых мест кода, которые будут интенсивно вызываться и редактироваться пользователем из настроек. В ПХП для этого есть модуль bcompiler, но вот печаль — он не компилируется под версию 5.4.

Я посидел над сообщениями при компиляции, посмотрел что другие ребята делали в модуле xcache для того, чтобы он заработал в 5.4, посмотрел внутренние структуры ПХП и родил патч, который позволяет успешно скомпилировать модуль. Модуль мои простенькие тесты проходит, но это правда не значит, что всё действительно работает.

Добавлено позднее: на более сложных тестах модуль всё-таки падает.

diff -wrdu bcompiler-1.0.2/bcompiler_zend.c bcompiler-1.0.2.new/bcompiler_zend.c
--- bcompiler-1.0.2/bcompiler_zend.c	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/bcompiler_zend.c	2012-07-24 21:59:30.000000000 +0400
@@ -471,12 +471,6 @@
 		apc_serialize_zend_class_entry(zv->obj.ce, NULL, 0, NULL, 0 TSRMLS_CC);
 #endif
 		break;
-#ifdef ZEND_ENGINE_2_4
-	case IS_CLASS:
-	case IS_SCALAR:
-	case IS_NUMERIC:
-		break;
-#endif
 	default:
 		/* The above list enumerates all types.  If we get here,
 		 * something very very bad has happened. */
@@ -551,12 +545,6 @@
 		apc_create_hashtable(&zv->obj.properties, apc_create_zval, NULL, sizeof(zval *) TSRMLS_CC);
 #endif
 		break;
-#ifdef ZEND_ENGINE_2_4
-	case IS_CLASS:
-	case IS_SCALAR:
-	case IS_NUMERIC:
-		break;
-#endif
 	default:
 		/* The above list enumerates all types.  If we get here,
 		 * something very very bad has happened. */
@@ -636,8 +624,10 @@
 	}
 	SERIALIZE_SCALAR(arg_info->allow_null       , zend_bool);
 	SERIALIZE_SCALAR(arg_info->pass_by_reference, zend_bool);
+#ifndef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(arg_info->return_reference , zend_bool);
 	SERIALIZE_SCALAR(arg_info->required_num_args, int);
+#endif
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_write) > 20) {
 # ifdef ZEND_ENGINE_2_4
@@ -667,8 +657,10 @@
 	else ZS2SR(arg_info->class_name) = NULL;
 	DESERIALIZE_SCALAR(&arg_info->allow_null, zend_bool);
 	DESERIALIZE_SCALAR(&arg_info->pass_by_reference, zend_bool);
+#ifndef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&arg_info->return_reference, zend_bool);
 	DESERIALIZE_SCALAR(&arg_info->required_num_args, int);
+#endif
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_version) > 20) {
 # ifdef ZEND_ENGINE_2_4
@@ -883,7 +875,9 @@
 #else
 	SERIALIZE_SCALAR(*(zce->refcount)  	     , int);
 #endif
+#ifndef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(zce->constants_updated, zend_bool);
+#endif
 #ifdef ZEND_ENGINE_2
 	SERIALIZE_SCALAR(zce->ce_flags, 	 zend_uint);
 #endif
@@ -930,15 +924,15 @@
 	 * and all the functions. */
 	BCOMPILER_DEBUG(("-----------------------------\nBUILTIN:\n"));
 	count = 0;
-	if (zce->type == ZEND_INTERNAL_CLASS && zce->builtin_functions) { 
-		for (zfe = (zend_function_entry*)zce->builtin_functions; zfe->fname != NULL; zfe++) {
+	if (zce->type == ZEND_INTERNAL_CLASS && zce->info.internal.builtin_functions) { 
+		for (zfe = (zend_function_entry*)zce->info.internal.builtin_functions; zfe->fname != NULL; zfe++) {
 			count++;
 		}
 	}
 	
 	SERIALIZE_SCALAR(count, int);
 	for (i = 0; i < count; i++) {
-		apc_serialize_zend_function_entry((zend_function_entry *)&zce->builtin_functions[i] TSRMLS_CC);
+		apc_serialize_zend_function_entry((zend_function_entry *)&zce->info.internal.builtin_functions[i] TSRMLS_CC);
 	}
 #ifndef ZEND_ENGINE_2
 	/** old code: SERIALIZE_SCALAR(zce->handle_function_call, void*); */
@@ -974,12 +968,12 @@
 	/* do reflection info (file/start/end) !! TODO: check for PHP6 !! */
 #ifdef ZEND_ENGINE_2
 	if (BCOMPILERG(current_write) >= 25) {
-		char* fname = bcompiler_handle_filename(zce->filename TSRMLS_CC);
+		char* fname = bcompiler_handle_filename(zce->info.user.filename TSRMLS_CC);
 		apc_serialize_string(fname TSRMLS_CC);
-		SERIALIZE_SCALAR(zce->line_start, int);
-		SERIALIZE_SCALAR(zce->line_end, int);
-		apc_serialize_zstring(zce->doc_comment, zce->doc_comment_len TSRMLS_CC);
-		SERIALIZE_SCALAR(zce->doc_comment_len, int);
+		SERIALIZE_SCALAR(zce->info.user.line_start, int);
+		SERIALIZE_SCALAR(zce->info.user.line_end, int);
+		apc_serialize_zstring(zce->info.user.doc_comment, zce->info.user.doc_comment_len TSRMLS_CC);
+		SERIALIZE_SCALAR(zce->info.user.doc_comment_len, int);
 	}
 #endif
 
@@ -1089,7 +1083,9 @@
 		*zce->refcount = 1; /* val: to avoid memort leaks */
 	}
 #endif
+#ifndef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&zce->constants_updated, zend_bool);
+#endif
 #ifdef ZEND_ENGINE_2
 	DESERIALIZE_SCALAR(&zce->ce_flags, zend_uint);
 #endif
@@ -1184,11 +1180,11 @@
 	   zend_class_entry.builtin_functions member */
 
 	DESERIALIZE_SCALAR(&count, int);
-	zce->builtin_functions = NULL;
+	zce->info.internal.builtin_functions = NULL;
 	if (count > 0) {
-		zce->builtin_functions = (zend_function_entry*) ecalloc(count+1, sizeof(zend_function_entry));
+		zce->info.internal.builtin_functions = (zend_function_entry*) ecalloc(count+1, sizeof(zend_function_entry));
 		for (i = 0; i < count; i++) {
-			apc_deserialize_zend_function_entry((zend_function_entry*)&zce->builtin_functions[i] TSRMLS_CC);
+			apc_deserialize_zend_function_entry((zend_function_entry*)&zce->info.internal.builtin_functions[i] TSRMLS_CC);
 		}
 	}
 #ifndef ZEND_ENGINE_2
@@ -1237,11 +1233,11 @@
 	if (BCOMPILERG(current_version) >= 25) {
 		char* fname;
 		apc_create_string_u(&fname, -1 TSRMLS_CC);
-		zce->filename = fname ? fname : estrdup(BCOMPILERG(current_filename));
-		DESERIALIZE_SCALAR(&zce->line_start, int);
-		DESERIALIZE_SCALAR(&zce->line_end, int);
-		apc_create_string_u(ZS2SP(zce->doc_comment), -1 TSRMLS_CC);
-		DESERIALIZE_SCALAR(&zce->doc_comment_len, int);
+		zce->info.user.filename = fname ? fname : estrdup(BCOMPILERG(current_filename));
+		DESERIALIZE_SCALAR(&zce->info.user.line_start, int);
+		DESERIALIZE_SCALAR(&zce->info.user.line_end, int);
+		apc_create_string_u(ZS2SP(zce->info.user.doc_comment), -1 TSRMLS_CC);
+		DESERIALIZE_SCALAR(&zce->info.user.doc_comment_len, int);
 	}
 #endif
 
@@ -1564,7 +1560,7 @@
 
 #ifdef ZEND_ENGINE_2_4
 	SERIALIZE_SCALAR(zoa->last_literal, zend_uint);
-	SERIALIZE_SCALAR(zoa->size_literal, zend_uint);
+	//SERIALIZE_SCALAR(zoa->size_literal, zend_uint);
 	for (i = 0; i < (int) zoa->last_literal; i++) {
 		bc_serialize_zend_literal(&zoa->literals[i] TSRMLS_CC);
 	}
@@ -1572,7 +1568,7 @@
 
 	SERIALIZE_SCALAR(zoa->refcount[0], zend_uint);
 	SERIALIZE_SCALAR(zoa->last, zend_uint);
-	SERIALIZE_SCALAR(zoa->size, zend_uint);
+	//SERIALIZE_SCALAR(zoa->size, zend_uint);
 
 	/* If a file 'A' is included twice in a single request, the following 
 	 * situation can occur: A is deserialized and its functions added to
@@ -1595,7 +1591,7 @@
 
 	SERIALIZE_SCALAR(zoa->T, zend_uint);
 	SERIALIZE_SCALAR(zoa->last_brk_cont, zend_uint);
-	SERIALIZE_SCALAR(zoa->current_brk_cont, zend_uint);
+	//SERIALIZE_SCALAR(zoa->current_brk_cont, zend_uint);
 #ifndef ZEND_ENGINE_2
 	SERIALIZE_SCALAR(zoa->uses_globals, zend_bool);
 #endif
@@ -1608,8 +1604,8 @@
 	}
 	apc_serialize_hashtable(zoa->static_variables, apc_serialize_zval_ptr TSRMLS_CC);
 	assert(zoa->start_op == NULL);
-	SERIALIZE_SCALAR(zoa->return_reference, zend_bool);
-	SERIALIZE_SCALAR(zoa->done_pass_two, zend_bool);
+	//SERIALIZE_SCALAR(zoa->return_reference, zend_bool);
+	//SERIALIZE_SCALAR(zoa->done_pass_two, zend_bool);
 	fname = bcompiler_handle_filename(zoa->filename TSRMLS_CC);
 	apc_serialize_string(fname TSRMLS_CC);
 	if (fname) efree(fname);
@@ -1628,9 +1624,9 @@
 #endif
 		SERIALIZE_SCALAR(zoa->fn_flags, zend_uint);
 		SERIALIZE_SCALAR(zoa->required_num_args, zend_uint);
-		SERIALIZE_SCALAR(zoa->pass_rest_by_reference, zend_bool);
+		//SERIALIZE_SCALAR(zoa->pass_rest_by_reference, zend_bool);
 
-		SERIALIZE_SCALAR(zoa->backpatch_count, int);
+		//SERIALIZE_SCALAR(zoa->backpatch_count, int);
 #ifdef ZEND_ENGINE_2_3
 		SERIALIZE_SCALAR(zoa->this_var, zend_uint);
 #else
@@ -1642,7 +1638,7 @@
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_write) >= 0x0007) {
 		SERIALIZE_SCALAR(zoa->last_var, int);
-		SERIALIZE_SCALAR(zoa->size_var, int);
+		//SERIALIZE_SCALAR(zoa->size_var, int);
 		for (i = 0; i < zoa->last_var; i++) {
 			SERIALIZE_SCALAR(zoa->vars[i].name_len, int);
 			apc_serialize_zstring(ZS2S(zoa->vars[i].name), ZLEN(zoa->vars[i].name_len) TSRMLS_CC);
@@ -1706,7 +1702,7 @@
 
 #ifdef ZEND_ENGINE_2_4
 	DESERIALIZE_SCALAR(&zoa->last_literal, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->size_literal, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->size_literal, zend_uint);
 	zoa->literals = NULL;
 	if (zoa->last_literal) {
 		zoa->literals = (zend_literal*) ecalloc(zoa->last_literal, sizeof(zend_literal));
@@ -1722,7 +1718,7 @@
 		*zoa->refcount = 1; /* val: to avoid memort leaks */
 	}
 	DESERIALIZE_SCALAR(&zoa->last, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->size, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->size, zend_uint);
 
 	zoa->opcodes = NULL;
 
@@ -1736,7 +1732,7 @@
 
 	DESERIALIZE_SCALAR(&zoa->T, zend_uint);
 	DESERIALIZE_SCALAR(&zoa->last_brk_cont, zend_uint);
-	DESERIALIZE_SCALAR(&zoa->current_brk_cont, zend_uint);
+	//DESERIALIZE_SCALAR(&zoa->current_brk_cont, zend_uint);
 #ifndef ZEND_ENGINE_2
 	DESERIALIZE_SCALAR(&zoa->uses_globals, zend_bool);
 #endif
@@ -1749,10 +1745,10 @@
 	}
 	apc_create_hashtable(&zoa->static_variables, apc_create_zval, NULL, sizeof(zval *) TSRMLS_CC);
  
-	zoa->start_op = NULL;
+	//zoa->start_op = NULL;
  
-	DESERIALIZE_SCALAR(&zoa->return_reference, zend_bool);
-	DESERIALIZE_SCALAR(&zoa->done_pass_two, zend_bool);
+	//DESERIALIZE_SCALAR(&zoa->return_reference, zend_bool);
+	//DESERIALIZE_SCALAR(&zoa->done_pass_two, zend_bool);
 	apc_create_string_u(&fname, -1 TSRMLS_CC);
 	if (fname) {
 		zoa->filename = zend_set_compiled_filename(fname TSRMLS_CC);
@@ -1798,8 +1794,8 @@
 		zoa->fn_flags &= ~ZEND_ACC_IMPLEMENTED_ABSTRACT; /* this is set later by zend_do_inheritance() */
 #endif
 		DESERIALIZE_SCALAR(&zoa->required_num_args, zend_uint);
-		DESERIALIZE_SCALAR(&zoa->pass_rest_by_reference, zend_bool);
-		DESERIALIZE_SCALAR(&zoa->backpatch_count, int);
+		//DESERIALIZE_SCALAR(&zoa->pass_rest_by_reference, zend_bool);
+		//DESERIALIZE_SCALAR(&zoa->backpatch_count, int);
 #ifdef ZEND_ENGINE_2_3
 		DESERIALIZE_SCALAR(&zoa->this_var, zend_uint);
 #else
@@ -1811,15 +1807,15 @@
 #ifdef ZEND_ENGINE_2_1
 	if (BCOMPILERG(current_version) >= 0x0007) {
 		DESERIALIZE_SCALAR(&zoa->last_var, int);
-		DESERIALIZE_SCALAR(&zoa->size_var, int);
-		if (zoa->size_var > 0) {
+		//DESERIALIZE_SCALAR(&zoa->size_var, int);
+		/*if (zoa->size_var > 0) {
 			zoa->vars = ecalloc(zoa->size_var, sizeof(zoa->vars[0]));
 			for (i = 0; i < zoa->last_var; i++) {
 				DESERIALIZE_SCALAR(&(zoa->vars[i].name_len), int);
 				apc_create_string_u(ZS2SP(zoa->vars[i].name), -1 TSRMLS_CC);
 				DESERIALIZE_SCALAR(&(zoa->vars[i].hash_value), ulong);
 			}
-		}
+		}*/
 	}
 #endif
 
diff -wrdu bcompiler-1.0.2/php_bcompiler.c bcompiler-1.0.2.new/php_bcompiler.c
--- bcompiler-1.0.2/php_bcompiler.c	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/php_bcompiler.c	2012-07-24 21:27:31.000000000 +0400
@@ -571,7 +571,7 @@
 #ifndef ZEND_ENGINE_2
 			if (i > n_old_class)
 #else
-			if (zc->filename && strcmp(zc->filename, real_path) == 0)
+			if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)
 #endif
 			{
 				SERIALIZE_SCALAR(BCOMPILER_CLASS_ENTRY, char)
@@ -632,7 +632,7 @@
 #ifndef ZEND_ENGINE_2
 			if (i > n_old_class)
 #else
-			if (zc->filename && strcmp(zc->filename, real_path) == 0)
+			if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)
 #endif
 			{
 #if PHP_MAJOR_VERSION >= 6
diff -wrdu bcompiler-1.0.2/php_bcompiler.h bcompiler-1.0.2.new/php_bcompiler.h
--- bcompiler-1.0.2/php_bcompiler.h	2011-06-09 15:58:42.000000000 +0400
+++ bcompiler-1.0.2.new/php_bcompiler.h	2012-07-24 22:13:31.000000000 +0400
@@ -22,7 +22,7 @@
 #ifndef PHP_BCOMPILER_H
 #define PHP_BCOMPILER_H
 
-#define PHP_BCOMPILER_VERSION "1.0.2"
+#define PHP_BCOMPILER_VERSION "1.0.2 (bolk) "
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"

Неудобно только то, что модуль не позволяет работать с объектами и анонимными функциями из ПХП 5.3 (которые тоже объекты), а так же компилирует всё в файл. Но второй недостаток легко обходится:

$fp = fopen('php://memory', 'rw');
bcompiler_write_header($fp);
bcompiler_write_function($fp, 'тут имя вашей функции, которую надо скомпилировать');
bcompiler_write_footer($fp);

fseek($fp, 0);
$compiled = stream_get_contents($fp); // байт-код теперь в переменной $compiled
fclose($fp);
17 комментариев
.silent 2012

а чем сам xcache не угодил? О.о

Евгений Степанищев (bolknote.ru) 2012

Комментарий для .silent:

Не знаю. Научите меня им пользоваться? Как взять какую-то функцию, скомпилировать её в байт-код и поместить в базу данных?

.silent 2012

Комментарий для Евгения Степанищева:

вот с этого и надо было начинать, что функцию надо где-то хранить.
я из поста понял что это только ради ускорения.

.silent 2012

кстати, ПХР — как-то оверрашенизировано :)

Евгений Степанищев (bolknote.ru) 2012

Комментарий для .silent:

Т. е. «некоторых мест кода» не указывает на то, что хранить надо какой-то определённый участок? А в примере кода на ПХП, в конце надо было мигающим жирным выделить фразу «тут имя вашей функции, которую надо скомпилировать»?

Евгений Степанищев (bolknote.ru) 2012

Комментарий для .silent:

кстати, ПХР — как-то оверрашенизировано :)

Что? Это опечатка просто.

Евгений Степанищев (bolknote.ru) 2012

Комментарий для .silent:

Оверрашенизировано — отличное русское слово, мой респект-ридер!

.silent 2012

Комментарий для Евгения Степанищева:

кошмар сколько агрессии.
извините что спросил.

samdark (rmcreative.ru) 2012

Как насчёт заслать авторам расширения?

Евгений Степанищев (bolknote.ru) 2012

Комментарий для .silent:

кошмар сколько агрессии.

Я был совершенно неагрессивен. Надо, видимо, смайлики ставить, кажется, уже любой текст по-умолчанию кажется агрессивным без них :)

Евгений Степанищев (bolknote.ru) 2012

Комментарий для rmcreative.ru:

Как насчёт заслать авторам расширения?

К сожалению, расширение хоть и работает с моим патчем, но нестабильно. Например, вывод «Hello, world!» работает, а если это завернуть в цикл — падает. :(

Acuna 2016

Евгений, здравствуйте! Имеются ли какие-либо сподвижки за четыре года в этом вопросе? Не поверю, что Вы в конечном итоге вывернули нежелательный код наизнанку)

Имею свой проект для души (консольная утилита для работы со звуком), у меня несколько иная задача: мне нужно собирать весь проект в экзешник и не выворачивать код наружу. Хоть утилита и свободная, но по некоторым причинам мне бы не хотелось выкладывать ее сорцы. Под одно хочу написать консольную утилиту для компиляции, так как пользую Notepad++ для разработки, это было бы очень удобно. Но это уже каждый сам решает что ему делать с бикомпилером, главное чтобы он работал на 5.4 хотя-бы. Сейчас я пользуюсь Фалангером. Он как раз имеет консольный компилятор, но имеет два существенных недостатка: требует установленного себя для работы собранных на нем скриптов, и компилирует код в .NET! То есть Вы понимаете, в чем суть, да?) PHP в .NET!))) Это самый лютый костыль, который только можно себе представить, но это единственное работающее решение. Поэтому очевидно, что параллельно я все время нахожусь в поиске решения сей задачи, и понял, что так как готовых решений не имеется, утилиту нужно писать самому. С этим сложностей возникнуть не должно, только все как раз и упирается именно в bcompiler. Собираю инфу по этому вопросу, даже спрашивал на Stackoverflow, тоже подтвердили что готовых решений нет, все предлагали Хипхоп. Я так и говорю, зачем мне этот Хипхоп, мне пару файлов собрать надо просто, зачем мне Хипхоп для этого поднимать?)

Ну и собссно только на Ваше решение и напоролся. Еще вот товарищ в одно время с Вашим патчем для Сихосина написал патч, предлагал на SO в качестве рабочего решения для 5.4, ознакамливались, работает ли? https://bugs.php.net/patch-display.php?bug_id=59912%26patch=suhosin-class-destructor-fix%26revision=latest

Ну и еще вот имеется что-то вроде как для 5.4: https://github.com/kenjikobe/bcompiler тоже датированное 2012 годом.

Больше вообще инфы никакой нет членораздельной...

Заранее благодарен и жду ответа ;)

Евгений Степанищев (bolknote.ru) 2016

Комментарий для Acuna:

Доброе утро!

Байт-код из этой моей статьи — это несколько другая вещь, не машинный код, запустить его непосредственно не получится, нужна специальная машина, которая его выполнит. Найденное вами решение — компилировать PHP в .NET делает то же самое — компилирует PHP в байт-код .NET, насколько я понимаю идею.

Вы ведь хотите на выходе иметь что-то запускаемое из командной строки? У меня задача была другая, насколько я помню — прекомпилировать PHP во что-то более быстрое с последующим запуском из-под PHP же.

В вашем случае, если я верно понял задачу, вариантов не много: найти (написать) софт, который завернёт вашу программу на PHP с интерпретатором PHP в запускаемый архив, которые развернётся, распакуется, запустит что надо, после завершения удалит всё распакованное — такого софта раньше было в изобилии, не знаю как сейчас, либо второй вариант — преобразовать PHP во что-то другое из чего какие-то ещё инструменты сделают запускаемый файл (например, путь PHP → .NET → EXE это как раз этот вариант).

Из описания bcompliler выходит, что он идёт по некому гибридному пути, который больше напоминает первый вариант — кладёт внутрь EXE интерпретатор PHP, себя и программу в байт-коде, которая потом всем этим интерпретируется.

В общем, какой бы вы путь не выбрали, решений на нём масса. Я когда-то смотрел вот эти, работали, не знаю в каком они сейчас состоянии:
http://develstudio.ru
https://github.com/jphp-compiler/jphp

Acuna 2016

Комментарий для Евгения Степанищева:

Да Вы правы, у меня ситуация иная, мне надо этот код где-то запустить. Ну по сути дела у Вас он выполняется на сервере, а мне тоже нужно найти что-то, где его можно запустить. С Вами решил связаться, так как вижу, что Вы работаете над адаптацией bcompiler’а, в котором у меня так же имеется заинтересованность. И все-таки, мне до сих пор интересно, чем закончилась эта Ваша эпопея, удалось ли в конечном итоге спрятать код?

Ну а я решение с bcompiler’ом обнаружил совершенно неожиданно для себя самого. На SO где-то совершенно вскольз упомянули о том, что bcompiler уже не в тренде, и что прогрессивная молодежь пользуется исключительно BLENC. Тоже расширение для Пекла. Появился он в 2004, и одной версией все и ограничилось, однако стал очень активно развиваться через два года после того, как умер bcompiler. Собссно на сегодняшний день поддерживает все аж до PHP 5.6! Единственное, что даже сами разрабы пишут, что особо полагаться на него не стоит, ибо можно дизассемблировать его хоть XDebug’ом. Но, как говорится, на безрыбье... В общем подарок)

Acuna 2016

Комментарий для Евгения Степанищева:

Ах да, насчет решений — для себя выбрал следующее, самое оптимальное не только в этой ситуации, да и вообще) Написал скрипт, который регуляркой проходит по всем require/include в файле рекурсией, прогоняет их через BLENC, и вставляет получившийся код в тот же файл. Благодаря этому из кучи разрозненных файлов мы получаем один. Затем батник запускает интерпретатор PHP, который выполняет этот файл. А уже сам этот батник уже компилю в экзешник первой попавшейся консольной утилитой bat2exe. И даже не придерешься!) И все это делается через консоль, как я и планировал. А сам интерпретатор PHP можно отдельно иметь где-то установленным, ибо просто бессмысленно таскать его за каждым приложением. Уже собрал свою утилиту через него, все работает, могу поделиться ссылочкой на SF, когда залью...

Евгений Степанищев (bolknote.ru) 2016

Комментарий для Acuna:

С Вами решил связаться, так как вижу, что Вы работаете над адаптацией bcompiler’а, в котором у меня так же имеется заинтересованность.

Нет, над этим я не работаю :)

И все-таки, мне до сих пор интересно, чем закончилась эта Ваша эпопея, удалось ли в конечном итоге спрятать код?

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

Acuna 2016

Комментарий для Евгения Степанищева:

Работать-то может и не работаете, однако патч успешно написали)

В общем решил проблему, благодарю...