<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Makura no Soshi &#187; PHP</title>
	<atom:link href="http://mschuette.name/wp/category/digital/php-digital-2/feed/" rel="self" type="application/rss+xml" />
	<link>http://mschuette.name/wp</link>
	<description>枕草子</description>
	<lastBuildDate>Tue, 22 May 2012 08:32:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Measuring PHP code complexity</title>
		<link>http://mschuette.name/wp/2010/09/measuring-php-code-complexity/</link>
		<comments>http://mschuette.name/wp/2010/09/measuring-php-code-complexity/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 16:23:37 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[complexity]]></category>
		<category><![CDATA[measure]]></category>
		<category><![CDATA[metric]]></category>
		<category><![CDATA[pdepend]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[phpcs]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">https://mschuette.name/wp/?p=612</guid>
		<description><![CDATA[What makes good code and why is some code better than others? One quantitative approach to answer this is the use of software metrics. These metrics try to capture the size and complexity of code in numbers (e.g. &#8216;lines of code&#8216;, &#8216;cyclomatic complexity&#8216;) and can be useful indicators for maintainability and simplicity (or more often [...]]]></description>
			<content:encoded><![CDATA[<p>What makes good code and why is some code better than others? One quantitative approach to answer this is the use of <a href="http://en.wikipedia.org/wiki/Programming_Complexity">software metrics</a>. These metrics try to capture the size and complexity of code in numbers (e.g. &#8216;<a href="http://en.wikipedia.org/wiki/Lines_of_code">lines of code</a>&#8216;, &#8216;<a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>&#8216;) and can be useful indicators for maintainability and simplicity (or more often the lack thereof).</p>
<p>I found three ways to get complexity measures for PHP code.</p>
<p>The most advanced technique is to use a continuous integration server. One good example is the server at <a href="http://test.pear.php.net:8080/cruisecontrol/">test.pear.php.net</a> which uses <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> (a Java CI server) with <a href="http://phpundercontrol.org/">phpUnderControl</a> for the PHP specific parts. Certainly a nice solution for big projects, but nothing to use on your own laptop to improve a single package.</p>
<p>Often the easiest way is to use <a href="http://pear.php.net/package/PHP_CodeSniffer">PHP_CodeSniffer</a>, which includes checks for cyclomatic complexity and nesting level (causing warnings and errors above some thresholds). If you already use it to maintain a uniform coding style (e.g. PEAR, Zend) then you just have to add these checks to your standard definition. These commands add metrics to the PEAR standard:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">cd /usr/local/share/pear/PHP/CodeSniffer/Standards
sudo cp -R Generic/Sniffs/Metrics PEAR/Sniffs
sudo sed -I .bck -e 's/Squiz_/PEAR_/' PEAR/Sniffs/Metrics/*</pre></div></div>

<p>The program <a href="http://pdepend.org/">PDepend</a> creates a more detailed analysis of methods, classes, and projects (see this <a href="http://manuel-pichler.de/archives/28-PHP_Depend-0.8.0beta1-released.html">release note</a> for details). Because it is intended as a component within a CI server its primary output is in XML. So I wrote myself a small wrapper (<a href="/files/pdepend_summary.phps">pdepend_summary.php</a>) to format the data as an ASCII table. This allows for quick edit-check-cycles and now I run it along with phpcs and phpunit before I commit PEAR code.</p>
<p>Example output:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Package              Class                                  LoC %Comment Variables Methods Class_SiZe   WMC
-------              -----                                  --- -------- --------- ------- ----------   ---
Payment_DTA          DTA                                   1084     36.3         3      15        114   111
Payment_DTA          DTAZV                                  757     37.1         1      12         72    71
Payment_DTA          DTABase                                563     33.0         6      19         33    27
Payment_DTA          Payment_DTA_ChecksumException            3      0.0         0       0          0     0
Payment_DTA          Payment_DTA_FatalParseException          3      0.0         0       0          0     0
Payment_DTA          Payment_DTA_Exception                    3      0.0         0       0          0     0
Payment_DTA          Payment_DTA_ParseException               3      0.0         0       0          0     0
&nbsp;
Package/Class             Method                                   LoC %Comment    CCN    NPath
-------------             ------                                   --- --------    ---    -----
Payment_DTA/DTA           _generateCrecord                         158     25.9     13     1600
Payment_DTA/DTA           _parseCextension                          81     30.9     13       93
Payment_DTA/DTA           _processCextension                        47      2.1      8        8
Payment_DTA/DTA           parse                                     59     35.6      7       36
Payment_DTA/DTAZV         _exchangeFillSender                       33      0.0      7       64
Payment_DTA/DTAZV         parse                                     41     17.1      7       36
Payment_DTA/DTAZV         _exchangeFillReceiver                     26      7.7      6       24
Payment_DTA/DTA           _exchangeFillArrays                       31      0.0      6       32
Payment_DTA/DTA           _parseCrecord                            109     27.5      6       72
Payment_DTA/DTAZV         setAccountFileSender                      41      0.0      5       15
Payment_DTA/DTA           _parseErecord                             49     30.6      5       16
Payment_DTA/DTABase       getStr                                    18      0.0      4        8
Payment_DTA/DTAZV         __construct                               19     10.5      4        4
...</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2010/09/measuring-php-code-complexity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP/CGI und die Internal Server Errors</title>
		<link>http://mschuette.name/wp/2010/09/phpcgi-und-die-internal-server-errors/</link>
		<comments>http://mschuette.name/wp/2010/09/phpcgi-und-die-internal-server-errors/#comments</comments>
		<pubDate>Tue, 07 Sep 2010 22:34:59 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[500]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[internal server error]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webserver]]></category>

		<guid isPermaLink="false">https://mschuette.name/wp/?p=604</guid>
		<description><![CDATA[Falls er per (F)CGI eingebundene PHP-Interpreter viele &#8220;Internal Server Errors&#8221; verursacht, sich aber im Apache-Log keine Fehlermeldung findet&#8230; dann sollte man nachsehen ob die PHP-Prozesse überhaupt durchlaufen oder aber abstürzen. Falls nämlich das Kernel-Log von SIGABRTs berichtet und überall Core-Dumps rumliegen, dann kann man sich langes rumschrauben am Logging sparen und stattdessen gleich die fehlerhafte [...]]]></description>
			<content:encoded><![CDATA[<p>Falls er per (F)CGI eingebundene PHP-Interpreter viele &#8220;Internal Server Errors&#8221; verursacht, sich aber im Apache-Log keine Fehlermeldung findet&#8230; dann sollte man nachsehen ob die PHP-Prozesse überhaupt durchlaufen oder aber abstürzen.<br />
Falls nämlich das Kernel-Log von SIGABRTs berichtet und überall Core-Dumps rumliegen, dann kann man sich langes rumschrauben am Logging sparen und stattdessen gleich die fehlerhafte PHP-Extension suchen und neuinstallieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2010/09/phpcgi-und-die-internal-server-errors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>DTA-Leser</title>
		<link>http://mschuette.name/wp/2010/07/dta-leser/</link>
		<comments>http://mschuette.name/wp/2010/07/dta-leser/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 21:46:43 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[dta]]></category>
		<category><![CDATA[dtaus]]></category>
		<category><![CDATA[dtazv]]></category>
		<category><![CDATA[payment_dta]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">https://mschuette.name/wp/?p=583</guid>
		<description><![CDATA[Das PEAR-DTA-Paket bekommt zur Zeit eine Lese-Funktion, um DTA/DTAZV-Dateien auch einlesen zu können. Mit dem DTA-Leser stelle ich nun ein Beispielskript online um Dateien entgegenzunehmen und ihren Inhalt anzuzeigen. Ist in einigen Situationen recht nützlich&#8230;]]></description>
			<content:encoded><![CDATA[<p>Das <a href="http://pear.php.net/package/Payment_DTA">PEAR-DTA-Paket</a> bekommt zur Zeit eine Lese-Funktion, um DTA/DTAZV-Dateien auch einlesen zu können.</p>
<p>Mit dem <a href="https://www.stud.uni-potsdam.de/~schuette/dta/">DTA-Leser</a> stelle ich nun ein Beispielskript online um Dateien entgegenzunehmen und ihren  Inhalt anzuzeigen. Ist in einigen Situationen recht nützlich&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2010/07/dta-leser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP syslog patch</title>
		<link>http://mschuette.name/wp/2010/03/php-syslog-patch/</link>
		<comments>http://mschuette.name/wp/2010/03/php-syslog-patch/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 13:04:30 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[english]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Syslog]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[suphp]]></category>
		<category><![CDATA[webserver]]></category>

		<guid isPermaLink="false">https://mschuette.name/wp/?p=502</guid>
		<description><![CDATA[Given a multiuser webserver with PHP and error logging to syslog. Problem: how do you correlate error messages with users? This patch lets PHP call openlog() with a configurable program name. My first approach was to filter by file and path names, but not every message includes a filename, so I was left with some [...]]]></description>
			<content:encoded><![CDATA[<p>Given a multiuser webserver with PHP and error logging to syslog. Problem: how do you correlate error messages with users? This patch lets PHP call <code>openlog()</code> with a configurable program name.</p>
<p>My first approach was to filter by file and path names, but not every message includes a filename, so I was left with some lines like these:</p>
<blockquote><p><code>2010-03-15T00:00:15.00+01:00 server php-cgi: Undeclared entity warning at line 54, column 8</code></p></blockquote>
<p>To overcome the problem I introduce two new php.ini variables: <code>syslog.program</code>, to give the program name, and the boolean <code>syslog.pid</code>, to enable logging the PID. Default values are <code>""</code> and <code>Off</code>, resulting in the previous behaviour (using the executable name as program name without PID). I use <a href="http://www.suphp.org/">suphp</a>, so every user has an own php.ini with <code>syslog.program</code> set to &#8220;php/username&#8221;, thus writing log lines like:</p>
<blockquote><p><code>2010-03-19T09:00:14.00+01:00 server php/mschuett[87777]: Undeclared entity warning at line 54, column 8</code></p></blockquote>
<p>With mod_php the variables can also be set per directory with <code>php_admin_value</code>. Changing them with <code>ini_set()</code> is not supported (not necessary because a new call to <code>openlog()</code> has the same effect). For enhanced security one could/should also use the php.ini setting <code>disable_functions=openlog</code> to prevent users from overriding these settings.</p>
<p>Because the source file is also affected by the <a href="http://www.hardened-php.net/suhosin/">Suhosin</a> patch, I prepared two diffs:</p>
<ul>
<li>PHP 5.2.12:<a href="/files/patch-php5.2.12.ext_standard_syslog.diff">patch-php5.2.12.ext_standard_syslog.diff</a></li>
<li>PHP  5.2.12 with Suhosin: <a href="/files/patch-php5.2.12.suhosin.ext_standard_syslog.diff">patch-php5.2.12.suhosin.ext_standard_syslog.diff</a></li>
</ul>
<p>[<strong>Update:</strong> the patches still work for PHP 5.3.6]<br />
[<strong>Update2:</strong> finally got around to write a <a href="http://bugs.php.net/bug.php?id=54144">Feature Request #54144</a>] </p>
]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2010/03/php-syslog-patch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to create OpenDocument texts with PHP</title>
		<link>http://mschuette.name/wp/2009/09/creating-opendocument-texts-with-php/</link>
		<comments>http://mschuette.name/wp/2009/09/creating-opendocument-texts-with-php/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 11:05:11 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[english]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[data export]]></category>
		<category><![CDATA[odt]]></category>
		<category><![CDATA[opendocument]]></category>
		<category><![CDATA[openoffice]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">https://mschuette.name/wp/?p=392</guid>
		<description><![CDATA[The problem: take a PHP/SQL web application and add a function to export form letters. Because they might have to be edited later, the letters are not to be exported as PDFs but as ODT files for word processing. When I implemented this I could not find documentation about this, so I wrote a small [...]]]></description>
			<content:encoded><![CDATA[<p>The problem: take a PHP/SQL web application and add a function to export form letters. Because they might have to be edited later, the letters are not to be exported as PDFs but as <a href="http://en.wikipedia.org/wiki/OpenDocument">ODT</a> files for word processing.</p>
<p>When I implemented this I could not find documentation about this, so I wrote a small how-to.</p>
<p>First create a template file (I use OpenOffice) with filler text. Include all images, fields, tables, paragraph styles, etc. you want to use later. Save the file in ODT format.</p>
<p>A <a href="http://en.wikipedia.org/wiki/OpenDocument_technical_specifications">.odt file</a> is a zip file containing all document components as XML files (as well all embedded files like pictures). Use <code>unzip</code> to extract the content into a subfolder.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[mschuett@dagny] ~&gt; mkdir newdoc &amp;&amp; unzip -d newdoc Untitled 1.odt
Archive:  Untitled 1.odt
 extracting: newdoc/mimetype
   creating: newdoc/Configurations2/statusbar/
  inflating: newdoc/Configurations2/accelerator/current.xml
   creating: newdoc/Configurations2/floater/
   creating: newdoc/Configurations2/popupmenu/
   creating: newdoc/Configurations2/progressbar/
   creating: newdoc/Configurations2/menubar/
   creating: newdoc/Configurations2/toolbar/
   creating: newdoc/Configurations2/images/Bitmaps/
 extracting: newdoc/Pictures/1000000000000181000000AD6DC45DA5.png
  inflating: newdoc/content.xml
  inflating: newdoc/styles.xml
 extracting: newdoc/meta.xml
  inflating: newdoc/Thumbnails/thumbnail.png
  inflating: newdoc/settings.xml
  inflating: newdoc/META-INF/manifest.xml</pre></div></div>

<p>The subdirectories <code>Configurations2</code> and <code>Thumbnails</code> as well as the file <code>settings.xml</code> are not required and can be deleted. The file <code>META-INF/manifest.xml</code> contains a list of all files, so the corresponding entries should be removed from this list.</p>
<p>That leaves us with three significant files: <code>meta.xml</code> for document metadata, <code>styles.xml</code> for styles and page elements (headers, footers), and <code>content.xml</code> for the main text. Use <code>xmllint --format</code> (part of <a href="http://xmlsoft.org/">libxml</a>) to make the XML somewhat readable and then open it in an editor to take a look at the general structure and to locate your filler texts. More information about the files can be found in the free book “<a href="http://books.evc-cit.info/">OASIS OpenDocument Essentials</a>”.</p>
<p>After a modification the files can be zipped again to verify the resulting ODF can be opened:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[mschuett@dagny] ~&gt; cd newdoc &amp;&amp; zip -r ../newdoc.odt * &amp;&amp; cd ..</pre></div></div>

<p>Now it&#8217;s up to you to write your application data into all the right places. I simply use <a href="http://www.php.net/str_replace">str_replace()</a> to substitute a number of variables, thus I have a PHP string with the text of <code>content.xml</code> and place holders like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"> <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text:p</span> <span style="color: #000066;">text:style-name</span>=<span style="color: #ff0000;">&quot;P2&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>%(FirstName) %(LastName)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text:p</span> <span style="color: #000066;">text:style-name</span>=<span style="color: #ff0000;">&quot;P1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>%(AddrComplement)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text:p</span> <span style="color: #000066;">text:style-name</span>=<span style="color: #ff0000;">&quot;P1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>%(Street)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text:p</span> <span style="color: #000066;">text:style-name</span>=<span style="color: #ff0000;">&quot;P1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>%(ZIP) %(City)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text:p</span> <span style="color: #000066;">text:style-name</span>=<span style="color: #ff0000;">&quot;P1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>%(Country)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The replacement uses two arrays &#8212; one with all place holders and one with all strings to replace them with. (Note: Because the database is still in Latin-1 but the XML files declare a UTF-8 encoding, all strings have to be converted. The call to utf8() is just shorthand for a call to <a href="http://www.php.net/manual/en/function.mb-convert-encoding.php">mb_convert_encoding()</a>.)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$replace_from</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&quot;%(FirstName)&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">&quot;%(LastName)&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">// etc.</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$replace_to</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    utf8<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbentry</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'firstname'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    utf8<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbentry</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'lastname'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #666666; font-style: italic;">// etc.</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$content_xml</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$replace_from</span><span style="color: #339933;">,</span> <span style="color: #000088;">$replace_to</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ODT</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'content_xml'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>When the document&#8217;s content is thus prepared, the files have to be zipped and sent to the user. In this example I change only the file <code>content.xml</code> and decide to zip all other files beforehand. (Because my files contain pictures I assume this is more efficient than creating everything on the fly.)</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[mschuett@dagny] ~&gt; cd newdoc &amp;&amp; zip -r ../template.zip * --exclude content.xml &amp;&amp; cd ..</pre></div></div>

<p>Finally this is the output function at the end of the PHP file:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// headers for download and correct MIME type</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-disposition: attachment; filename=&quot;letter.odt&quot;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Content-Type: application/vnd.oasis.opendocument.text'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// this is slightly magic</span>
File_Archive<span style="color: #339933;">::</span><span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span>
    File_Archive<span style="color: #339933;">::</span><span style="color: #004000;">readMulti</span><span style="color: #009900;">&#40;</span>    <span style="color: #666666; font-style: italic;">// read sources</span>
        <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
            <span style="color: #666666; font-style: italic;">// a) an existing archive</span>
            File_Archive<span style="color: #339933;">::</span><span style="color: #004000;">read</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;template.zip/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
            <span style="color: #666666; font-style: italic;">// b) our memory buffers to be named</span>
            File_Archive<span style="color: #339933;">::</span><span style="color: #004000;">readMemory</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$content_xml</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;content.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    File_Archive<span style="color: #339933;">::</span><span style="color: #004000;">toArchive</span><span style="color: #009900;">&#40;</span>  <span style="color: #666666; font-style: italic;">// combine sources into one output</span>
        <span style="color: #0000ff;">'letter.odt'</span><span style="color: #339933;">,</span>
        File_Archive<span style="color: #339933;">::</span><span style="color: #004000;">toOutput</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>  <span style="color: #666666; font-style: italic;">// send to stdout = browser</span>
        <span style="color: #000088;">$type</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'zip'</span>
    <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>First the HTTP headers are sent, so the browser knows it will receive a file in OpenDocument format (it should then ask the user whether to save the file or open it immediately in a word processor). The PEAR package <a href="http://pear.php.net/package/File_Archive">File_Archive</a> is used for all zipfile actions: first the prepared zipfile is read, then the string <code>$content_xml</code> is added with file name <code>"content.xml"</code>, at last the new zipfile is sent to the user. And that&#8217;s it.</p>
<p>If necessary the other files can be customized in the same way. If the ODT files are not only used for printing but are archived or send to an end-user then you probably want to set a correct document creation date, generator, author information, etc. in <code>meta.xml</code>.</p>
<p>If you are looking for PHP library support of OpenDocument files then take a look at the <a href="http://pear.php.net/package/OpenDocument/">PEAR OpenDocument class</a>. Just like all other projects I have found it is in early alpha status, but now that <a href="http://cweiske.de/tagebuch/OpenDocument%200.2.0%20released.htm">Christian Weiske took over maintainership</a> recently it seems to be the only one under active development.</p>
<p>Last but not least: you can use the <a href="http://tools.odftoolkit.org/odfvalidator/">ODF Validator</a> to validate your documents against the ODF Specification (without having to rely on the &#8220;it is correct if OOo can open it&#8221; approach).</p>
]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2009/09/creating-opendocument-texts-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DTAZV mit PHP</title>
		<link>http://mschuette.name/wp/2008/09/dtazv-mit-php/</link>
		<comments>http://mschuette.name/wp/2008/09/dtazv-mit-php/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 21:51:47 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Digital]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[dta]]></category>
		<category><![CDATA[dtaus]]></category>
		<category><![CDATA[dtazv]]></category>
		<category><![CDATA[pear]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[überweisung]]></category>

		<guid isPermaLink="false">http://mschuette.name/wp/?p=143</guid>
		<description><![CDATA[Ich betreue eine PHP-Anwendung die Überweisungen vorbereitet, mithilfe der PEAR Payment_DTA Klasse als DTA-Datei formatiert und per E-Mail an die Finanzabteilung schickt. Um damit auch EU-Überweisungen erfassen zu können habe ich eine Klasse DTAZV geschrieben. Es ist eine direkte Erweiterung der Klasse DTA von Hermann Stainer und soll dem bestehenden PEAR-Paket hinzugefügt werden; wegen SVN-Problemen [...]]]></description>
			<content:encoded><![CDATA[<p>Ich betreue eine PHP-Anwendung die Überweisungen vorbereitet, mithilfe der <a href="http://pear.php.net/package/Payment_DTA">PEAR Payment_DTA</a> Klasse als <a href="http://de.wikipedia.org/wiki/Datentr%C3%A4geraustauschverfahren">DTA-Datei</a> formatiert und per E-Mail an die Finanzabteilung schickt.<br />
Um damit auch EU-Überweisungen erfassen zu können habe ich eine Klasse DTAZV geschrieben.</p>
<p>Es ist eine direkte Erweiterung der Klasse DTA von Hermann Stainer und soll dem bestehenden PEAR-Paket hinzugefügt werden; wegen SVN-Problemen ist das bisher aber noch nicht geschehen&#8230;  Daher veröffentliche ich den Code erstmal hier: <a href="/files/DTA/DTAZV.phps">DTAZV.php</a></p>
<p>Die Implementierung erfolgte auf Grundlage der <a href="http://www.bundesbank.de/download/meldewesen/aussenwirtschaft/vordrucke/pdf/dtazv_2007_kunde_bank.pdf">DTAZV-Spezifikation der Bundesbank vom 22. November (pdf)</a>. Zur Korrektheit kann ich nur sagen dass die erzeugten Dateien von SFirm importiert werden <span style="text-decoration: line-through;">und es im praktischen Einsatz seit März 2008 noch keine Probleme gab</span> [Korrektur: der Sprung vom Test- auf's Produktivsystem steht noch aus]; für darüber hinausgehende Urteile fehlt mir die Grundlage, dazu bräuchte ich Testdatensätze oder eine Referenzimplementierung.</p>
<p>Außerdem habe ich noch einen <a href="/files/DTA/DTA.patch">Patch für die DTA.php</a> mit allen Änderungen die ich an der Grundklasse selbst vorgenommen hab (ergänzt mehr Sonderzeichen, zusätzliche Parameter-Validierung und eine neue Methode <code>count()</code>).</p>
]]></content:encoded>
			<wfw:commentRss>http://mschuette.name/wp/2008/09/dtazv-mit-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

