Comments 19
<source> в помощь.
+20
Все, конечно, супер. Спасибо за статью. Но пожалуйста, отформатируйте исходные коды… Прям вырви глаз :)
+12
Не рекламы ради, здоровья для: моя старая статья про «честную генерацию ODT используя шаблонные документы»
+5
Еще с нетерпением жду описание цифровой подписи docx.
Всегда мечтал генерить при помощи пхп подписанные документы.
Всегда мечтал генерить при помощи пхп подписанные документы.
0
Можно попридираться к коду?
— Название класса Word не однозначно. Увидев где-то в его клиенте $word = new Word('Пример.docx'), я бы решил что какое-то слово извлекается из документа. Предлагаю DocxDocument или или даже DocxDocumentFromTemplate.
— Вызывает большое сомнение необходимость наследоваться от ZipArchive. Не буду заниматься излишними абстракциями вроде: «Хорошо бы иметь общий интерфейс для .txt, .doc, .docx, .odt, .rtf, пускай эта функциональность пока и не требуется и неизвестно потребуется ли когда либо». Поступлю проще, спрошу: «Вы уверены, что в классе Word вам нужны все методы ZipArchive? Его клиентам нужен к ним доступ?». Может лучше сделать ZipArchive свойством (приватным/защищенным)?
— параметр конструктора $template = '/template/' меня как-то ступорит. Привык, что template это файл, а путь начинающийся с '/' абсолютный от корня ФС. Может вообще передавать в конструктор нормальный шаблон (подготовленный в редакторе файл с полями {{CONTENT}}, а класс его будет разархивировать, заменять содержимое, а потом архивировать?
В общем придирки не к реализации, а к интерфейсу. Не слишком ли много клиенту нужно знать об устройстве и самого формата, и вашего класса?
— Название класса Word не однозначно. Увидев где-то в его клиенте $word = new Word('Пример.docx'), я бы решил что какое-то слово извлекается из документа. Предлагаю DocxDocument или или даже DocxDocumentFromTemplate.
— Вызывает большое сомнение необходимость наследоваться от ZipArchive. Не буду заниматься излишними абстракциями вроде: «Хорошо бы иметь общий интерфейс для .txt, .doc, .docx, .odt, .rtf, пускай эта функциональность пока и не требуется и неизвестно потребуется ли когда либо». Поступлю проще, спрошу: «Вы уверены, что в классе Word вам нужны все методы ZipArchive? Его клиентам нужен к ним доступ?». Может лучше сделать ZipArchive свойством (приватным/защищенным)?
— параметр конструктора $template = '/template/' меня как-то ступорит. Привык, что template это файл, а путь начинающийся с '/' абсолютный от корня ФС. Может вообще передавать в конструктор нормальный шаблон (подготовленный в редакторе файл с полями {{CONTENT}}, а класс его будет разархивировать, заменять содержимое, а потом архивировать?
В общем придирки не к реализации, а к интерфейсу. Не слишком ли много клиенту нужно знать об устройстве и самого формата, и вашего класса?
+3
Можно попридираться к коду?
Да, конечно.
Название класса — да, согласен. DocxDocument будет понятнее.
Наследование от ZipArchive — это концепция этого топика, я уверен, что именно так можно (не скажу что нужно, т.к. могут быть другие пути) генерить MSWord. Причина — в упаковщике. Если DocxDocument — генератор, то он должен быть и упаковщиком.
Вопрос про шаблон template — отдельная тема. В топике я реализовал лишь самое главное, применив str_replace. Но у каждого свои тараканы в голове — можно хоть Smarty применить.
Самое главное, что меня интересует — правильная ли реализация генерации контента при помощи метода assign? Ведь можно сделать assign методом регистрации переменных, как принято в Template-движках, а парсинг — методом pparse в конце. Что-то такое уже проглядывается в текущей реализации, поскольку весь контент регистрируется в одну переменную {CONTENT}, а в конце она одна парсится str_replac'ом. Но с другой стороны, мы изобретаем велосипед. Можно просто прикрутить готовый шаблонизатор в свойство и скармливать ему шаблон. Вопрос — какой шаблонизатор?
Да, конечно.
Название класса — да, согласен. DocxDocument будет понятнее.
Наследование от ZipArchive — это концепция этого топика, я уверен, что именно так можно (не скажу что нужно, т.к. могут быть другие пути) генерить MSWord. Причина — в упаковщике. Если DocxDocument — генератор, то он должен быть и упаковщиком.
Вопрос про шаблон template — отдельная тема. В топике я реализовал лишь самое главное, применив str_replace. Но у каждого свои тараканы в голове — можно хоть Smarty применить.
Самое главное, что меня интересует — правильная ли реализация генерации контента при помощи метода assign? Ведь можно сделать assign методом регистрации переменных, как принято в Template-движках, а парсинг — методом pparse в конце. Что-то такое уже проглядывается в текущей реализации, поскольку весь контент регистрируется в одну переменную {CONTENT}, а в конце она одна парсится str_replac'ом. Но с другой стороны, мы изобретаем велосипед. Можно просто прикрутить готовый шаблонизатор в свойство и скармливать ему шаблон. Вопрос — какой шаблонизатор?
0
Я имел в виду код вроде:
class DocxDocument {
protected $archive;
public function __construct($filename, $template_path = '/template/' ){
// Путь к шаблону
$this->path = dirname(__FILE__) . $template_path;
// Если не получилось открыть файл, то жизнь бессмысленна.
if ($this->archive->open($filename, ZIPARCHIVE::CREATE) !== TRUE) {
die("Unable to open <$filename>\n");
}
// Структура документа
$this->archive->files = array(
"word/_rels/document.xml.rels",
"word/theme/theme1.xml",
"word/fontTable.xml",
"word/settings.xml",
"word/styles.xml",
"word/document.xml",
"word/stylesWithEffects.xml",
"word/webSettings.xml",
"_rels/.rels",
"docProps/app.xml",
"docProps/core.xml",
"[Content_Types].xml" );
// Добавляем каждый файл в цикле
foreach( $this->archive->files as $f )
$this->addFile($this->archive->path . $f , $f );
}
//...
}
+1
Не вижу смысла, т.к. получается, что везде где есть $this, вы приписали ->archive.
Забыли приписать возле $this->addFile(…
Если еще путь к шаблону поместить в ->archive, тогда вообще вся работа будет идти только через одно свойство.
В принципе, если DocxDocument должен будет являться наследником какого-то другого класса, тогда ваша реализация — выход.
Забыли приписать возле $this->addFile(…
Если еще путь к шаблону поместить в ->archive, тогда вообще вся работа будет идти только через одно свойство.
В принципе, если DocxDocument должен будет являться наследником какого-то другого класса, тогда ваша реализация — выход.
-1
Люблю тонкий юмор в камментах)))
// Если не получилось открыть файл, то жизнь бессмысленна.
if ($this->open($filename, ZIPARCHIVE::CREATE) !== TRUE) {
die("Unable to open <$filename>\n");
}
+9
Быдлокод детектед!
Я думал тут хотябы пара слов про DOM или XPath будет. А тут «str_replace()»…
Да и про наследование ZipArchive правильно заметили.
Нафига разбили строки по переносам строки не понятно.
Я думал тут хотябы пара слов про DOM или XPath будет. А тут «str_replace()»…
Да и про наследование ZipArchive правильно заметили.
Нафига разбили строки по переносам строки не понятно.
+7
Большое спасибо! Давно искал подобную статью.
0
Садись, пять! Только, как это было уже замечено, оформление храмает.
Трилогия MS Office X:
1) .docx
2) .xlsx
3) .pptx
Ждем продолжение!
Трилогия MS Office X:
1) .docx
2) .xlsx
3) .pptx
Ждем продолжение!
-1
UFO just landed and posted this here
Спасибо!
0
Sign up to leave a comment.
Честная генерация DOCX на PHP. Часть 1