Pull to refresh

PHP класс для сборки инклюдов в один файл

Reading time2 min
Views1.1K
по мотивам коммента mocksoul из темы PHP: Введение в Zend Framework

Проблема


В кратце, речь шла о том, что одним из недостатков фреймворка является его концепция «один класс – один файл». И хотя, с моей точки зрения, это не является недостатком архитектуры ZF, это является недостатком PHP. Проблемы начинаются когда PHP начинает инклюдить десятки и сотни файлов, да еще проверять их на once.

Предложенное решение – сборка всех инклюдов в один файл. Класс, представленный ниже – не претендует на окончательный универсальный вариант решения проблемы. Он всего лишь демонстрирует один из методов сборки инклюдов. В данном случае он собирает только файлы фреймворка, игнорируя все остальные.

Класс


&lt?php
class ZendMake
{
/**
* Сборка заинклюденных файлов с удалением комментов, require/include, и проч
*
* param string $dest Абсолютное имя скомпиленного файла
* param string $includes Массив файлов ZF для сборки
* return array
*/
public static function make($dest, $includes = null)
{
$includes = is_array($includes)? $includes: self::_getZendIncludes();

// Удалить теги '&lt?php' '? &gt', комменты, пустые перводы строк и require/include[_once]
$pattern[] ='%(^\&lt\?php|\?\&gt$)%m';
$replacement[] = '';
$pattern[] ='%/\*.*?\*/%sm';
$replacement[] = '';
$pattern[] ='%//.*$%m';
$replacement[] = '';
$pattern[] ='%(require_once|include_once|require|include) [("\'](.*?)[)"\'];%sm';
$replacement[] = '';
$pattern[] ='%(\n){2,}%';
$replacement[] = "\n";

$body = "&lt?php\n";
foreach ($includes as $fname) {

$body .= preg_replace($pattern, $replacement, file_get_contents($fname, true));
}

$size = file_put_contents($dest, $body);

return array('includes' =&gt $includes, 'compiledBody' =&gt $body, 'compiledSize' =&gt $size);
}

/**
* Выбрать уникальные файлы ZF заинклюденные в проект
*
* return array
*/
private static function _getZendIncludes()
{
$required = array();
$included_files = get_included_files();
foreach ($included_files as $fname) {
if (!(strpos($fname, 'Zend') &gt 0) || (strstr($fname, __CLASS__. '.php'))) {
continue;
}

$required[] = str_replace('\\', '/', substr($fname, strpos($fname, 'Zend'), strlen($fname)));

// Все requires
$pattern ='%(require_once|include_once|require|include) [("\'](.*?)[)"\'];%sm';
preg_match_all($pattern, file_get_contents($fname), $pocket);

$required = array_merge($pocket[2], $required);
}

return array_unique($required);
}
}


Использование


В конце работы скрипта вставить строки
require 'ZendMake.php';
$result = ZendMake::make($libDir. 'Zend.Make.php');
Zend_Debug::dump($result['includes']);
Zend_Debug::dump($result['compiledSize']);


Результаты


С помощью этого класса я собрал более 60 файлов ZF из моего проекта (модули Controller, Session, Auth, View, Uri, Db, Config, Version, Debug, Registry). Собранный файл занял 231 кб.

Время работы скрипта с использованием собранного файла быстрее скрипта с использованием большого количества инклюдов более чем в 8 раз.
Tags:
Hubs:
+5
Comments16

Articles