<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5540569973275631268</id><updated>2012-02-16T09:33:39.935+01:00</updated><category term='design decisions'/><category term='cms'/><category term='php'/><category term='bugs'/><category term='openx'/><category term='abusage'/><title type='text'>palbertini</title><subtitle type='html'>php engineering</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.patrickalbertini.de/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default'/><link rel='alternate' type='text/html' href='http://blog.patrickalbertini.de/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>palbertini</name><uri>http://www.blogger.com/profile/14668486542596348958</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_L_BczXTYu1A/SU-Cughm4_I/AAAAAAAAAAM/IjIxre7FDwg/s1600-R/patrick.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5540569973275631268.post-5532574381637766195</id><published>2011-08-09T08:29:00.002+02:00</published><updated>2011-08-09T08:49:35.314+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='abusage'/><category scheme='http://www.blogger.com/atom/ns#' term='cms'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='openx'/><title type='text'>(Ab)using an OpenX AdServer as noninvasive CMS</title><content type='html'>At work we've recently been working on and finally deploying an interesting use of an &lt;a href="http://www.openx.org/"&gt;openX &lt;/a&gt;ad-server: we use it as a CMS system. There were two basic reasons for us to do this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Requirements : Our PM required us to have a CMS system, where the content boxes could be served in a way you'd usually serve ads. Some have frequency cappings, others show up at certain times a day, some have randomly changeing contents.&lt;/li&gt;&lt;li&gt;Other CMS systems often bring a bunch of software we dont need. Many bring a complete framework (which usually consists of crap-code), require you to work with their administration to make changes to a site, prevent or countervail effective cacheing and are a boring solution anyways.&lt;/li&gt;&lt;/ol&gt;OpenX ships with an API, meets all requirements, may besides be used in they way its originally meant to work - as adserver - and can be modified building your own plugins.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;what we did&lt;/span&gt; &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Added openX XML-RPC API as possible Datasource in our Data-Access-Layer&lt;/li&gt;&lt;li&gt;Added roughly 10 plugins to meet our needs&lt;/li&gt;&lt;li&gt;Added Database sync and plugin installation to our build&lt;/li&gt;&lt;/ol&gt;Thanks to the plugins we didnt need to touch the also really crappy code openX is written in. Trust me, better dont risk a glimpse.&lt;br /&gt;This enabled us to apply cacheing mechanisms on different levels : DataAccess may store read contents in memcache, whole site cacheing is done with varnish. OpenX plugins sometimes read from our software via simple CURL requests, these also pass varnish and memcached.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;stumbled upon some problems&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In openX you dispatch so called zones. These are basically spaces which may contain banners (or boxes in our case). API calls read from openX via commands similar to "zone:1", where 1 is a openX given zone id. We didnt want our beautiful software to gain knowledge of all the IDs created by an anonymous server that should remain exchangeable. Also you'd need like 40 zones for a single webpage, since you'd always want PM to freely and easily change contents.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We solved this issue by creating a what we call ContainerBox-Plugin. This plugin does internal openX API calls and dispatches arbitrary many sub-zones. Our software only knows two container IDs per webpage, which leads to a straigforward number of zone (container) IDs, that are managed as constants in a single interface. By creating a small converter we use textual identifiers for zones all over the software, that wont need to be changed when exchanging the CMS/adserver and encapsulate all openX specific information in that single interface.&lt;/li&gt;&lt;/ul&gt;openX tries to emulate APC by "shrinking" all code needed in production for API calls. One of the silliest pratices I've ever seen and really a pain in the a**. You cannot simply require_once files in your plugins, f.e. to do the internal API calls to openX from openX, since the files included for administration and production are different ones (normal source vs. shrinked crap for the latter).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Since plugins weren't easy to test anyway (since they consist of a component file that is roughly OOP and a delivery function that by default is not) we build some kind of own openX internal API, that checks for function_defined's and requires files based on that. Also its injected into our plugin classes, so that we could make them testable without doing actual calls to the databases.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Another thing that not to cool is openX support. The documentationis not good at all, and the source code doesn't read understandable. Also known bugs and issues aren't solved within reasonable times.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5540569973275631268-5532574381637766195?l=blog.patrickalbertini.de' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.patrickalbertini.de/feeds/5532574381637766195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.patrickalbertini.de/2011/08/abusing-openx-adserver-as-noninvasive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/5532574381637766195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/5532574381637766195'/><link rel='alternate' type='text/html' href='http://blog.patrickalbertini.de/2011/08/abusing-openx-adserver-as-noninvasive.html' title='(Ab)using an OpenX AdServer as noninvasive CMS'/><author><name>palbertini</name><uri>http://www.blogger.com/profile/14668486542596348958</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_L_BczXTYu1A/SU-Cughm4_I/AAAAAAAAAAM/IjIxre7FDwg/s1600-R/patrick.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5540569973275631268.post-852091549781731953</id><published>2010-09-04T13:52:00.000+02:00</published><updated>2010-09-04T13:52:40.416+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design decisions'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Using helpers to emulate multiple inheritance in PHP</title><content type='html'>There's no multiple inheritance of classes in PHP. We all can be happy with &lt;a href="http://en.wikipedia.org/wiki/Diamond_problem"&gt;respect&lt;/a&gt; to some problems, but there is others arising from that:&lt;br /&gt;&lt;br /&gt;What we want to do is this: shared methods should be shared and not duplicated. So an action &lt;i&gt;AbstractArticleAction &lt;/i&gt;and another one, &lt;i&gt;AbstractBlogAction&lt;/i&gt;, both inherit from an AbstractPageAction and maybe add custom methods. And there is more special actions like &lt;i&gt;ArticleDetailAction &lt;/i&gt;and &lt;i&gt;BlogDetailAction &lt;/i&gt;which both do things like &lt;i&gt;stripForbiddenHtmlFromText()&lt;/i&gt;. And here is our problem: Where should we put our shared &lt;i&gt;stripForbiddenHtmlFromText &lt;/i&gt;method?&lt;i&gt; &lt;/i&gt;The only class our DetailActions both inherit is the AbstractPageAction - but there's many other actions who do inherit from this one, and our method is only needed in the two special cases presented.&lt;br /&gt;&lt;br /&gt;Now there are different approaches to a solution here:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a TextAction so that we gain an inheritance tree like this one:&lt;br /&gt;&lt;blockquote&gt;BlogDetailAction extends AbstractBlogAction extends TextAction extends AbstractPageAction&lt;/blockquote&gt;This won't solve any problem, since tomorrow we will need a MonetarizeAction which should be used only by articles and not by blog posts.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create Action Helpers and import/inject them into your actions when needed (plugins):&lt;br /&gt;&lt;blockquote&gt;class AbstractArticleAction extends AbstractPageAction {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function doExecute(ourRequest $request) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; $this-&amp;gt;loadHelpers(array(TextActionHelper,MonetarizeActionHelper));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; function __call($method, $args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $this-&amp;gt;{helpersMethods[$method]}($args);&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/blockquote&gt;Then the helper methods are magically added as methods to AbstractArticleAction.&lt;br /&gt;This solves our problem, but also creates new ones I'll describe later.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Make all action helper methods public static and call them statically from within your actions:&lt;br /&gt;&lt;blockquote&gt;class AbstractArticleAction extends AbstractPageAction {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function doExecute(ourRequest $request) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; $this-&amp;gt;article = TextActionHelper::stripForbiddenHtml(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;article, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $allowedHtml&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/blockquote&gt;Erm. Let's go back to the procedural paradigm, okay? ... We don't want to do this.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Work with dependecy injection and inject all helpers as services: &lt;br /&gt;&lt;blockquote&gt;class AbstractArticleAction extends AbstractPageAction {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function doExecute(ourRequest $request) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; $this-&amp;gt;article = $this-&amp;gt;_TextHelperService-&amp;gt;stripForbiddenHtml(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;article, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $allowedHtml&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/blockquote&gt;Not so nice, and leads to similar problems like 2. And: this is not quiet what a service is thought of be doing. And: you'd have public function injectStuff($stuffToInject) methods all over your actions.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use Singletons. No.&lt;/li&gt;&lt;/ol&gt;We decided for the second solution and built view helpers and action helpers which are imported when needed. As already mentioned this does solve the problem and gives our BlogDetailAction all the methods it needs while leaving everything else untouched. Also code duplication is avoided. The AbstractPageAction has a method called load() which will import an action helper. AbstractBlogAction and AbstractNewsAction both do import the text helpers.&lt;br /&gt;&lt;br /&gt;But there's also some problems with this solution:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Magic&lt;/b&gt;: neither from within the class, nor from it's parents you can directly see where a method comes from. So doesn't your IDE of choice. Forget about clickable method names, code completion and easy access to understanding. On the other hand: knowing about the action helper system might let you grasp from the method name, that It'll quiet likely be found in an action helper.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Naming conflicts&lt;/b&gt;: This one is classical about multiple inheritance. What happens if two or more of the view helper methods have the same name? This wouldn't be a problem within the two different helper classes, but would become one when an action imports both of them. Throwing an ActionHelperMethodNameConflictException does solve this during runtime. But one can easily imagine, that there are 12 action helper classes which are used for development for about one year (method names spread all over the project) and after the year we first stumble across a conflict because we before never had a case where two the conflicting helper classes were both imported by an action. Now we have to rename one of the methods...&lt;/li&gt;&lt;li&gt;&lt;b&gt;Statics&lt;/b&gt;: To avoid loading helpers all over in every action that inherits from f.a. AbstractBlogAction one has to make helpers a static property. I am still unsure if this is a good idea.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Function arguments&lt;/b&gt;:Since arguments are passed to the helpers via func_get_args() in the __call() method, the helpers are really hard to handle, iff they have multiple arguments, which are predefined [f.e. cropText($text, $length = 250)] and get passed the action as third argument like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;__call ($method, $args) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; return $this-&amp;gt;{helpermethods[$method]}(array_merge($args,$this));&lt;br /&gt;}&lt;/blockquote&gt;This is, because&amp;nbsp; the helper method would, if we omit the second argument ($length), have to decide, if $length is the length or the action object. &lt;/li&gt;&lt;/ul&gt;Note, that the same problems and solution strategies apply for views and view helpers. Zend also choosed the 2nd strategy with respect to &lt;a href="http://framework.zend.com/manual/en/zend.view.helpers.html"&gt;Zend view helpers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5540569973275631268-852091549781731953?l=blog.patrickalbertini.de' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.patrickalbertini.de/feeds/852091549781731953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.patrickalbertini.de/2010/09/using-helpers-to-emulate-multiple.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/852091549781731953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/852091549781731953'/><link rel='alternate' type='text/html' href='http://blog.patrickalbertini.de/2010/09/using-helpers-to-emulate-multiple.html' title='Using helpers to emulate multiple inheritance in PHP'/><author><name>palbertini</name><uri>http://www.blogger.com/profile/14668486542596348958</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_L_BczXTYu1A/SU-Cughm4_I/AAAAAAAAAAM/IjIxre7FDwg/s1600-R/patrick.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5540569973275631268.post-1821780867756449745</id><published>2010-09-01T20:53:00.000+02:00</published><updated>2010-09-04T13:24:48.696+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP: date() versus DateTime</title><content type='html'>Today I've stumbled upon an interesting bug in phps date() versus the DateTime object (since PHP 5.x). When writing unit test for an old view helper that creates parts of links from timestamps, I used &lt;i&gt;DateTime::createFromFormat&lt;/i&gt; to create my expected values while using the view helper relied on &lt;i&gt;date("d.m.Y")&lt;/i&gt; for it's return values.&lt;br /&gt;&lt;br /&gt;When setting up the test, I choosed to use a data provider and just typed in long integers to represent my unix timestamps without thinking about a realistic length for them. &lt;br /&gt;&lt;br /&gt;In the first step PHPunit confronted me with a typical result of the &lt;a href="http://www.sitepoint.com/blogs/2010/08/24/is-your-php-application-affected-by-the-y2k38-bug/"&gt;Y2K38&lt;/a&gt; problem, since I had choosen a number (123557556123) which represents the 20th of May in the year 5885 :&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1) onvLinkViewHelperTest::testCreatePortfolioChartDatesString with data set #5 (123557556123)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Failed asserting that two strings are equal.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--- Expected&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+++ Actual&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@@ @@&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-FROM=20.05.5885&amp;amp;TO=03.09.2010&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+FROM=04.06.1938&amp;amp;TO=03.09.2010 &lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;I'll not describe this bug here, since it's fairly known around the blogs. I then decided to ignore the problem, because a colleague was just about to refactor the date view helpers who were responsible for the bug and doing a job twice thus having to merge both results doesn't sound too agile.&lt;br /&gt;&lt;br /&gt;So I changed my data provider and randomliy choosed the number &lt;i&gt;12352343 &lt;/i&gt;as a date. Now I stumbled into another bug which in the first place made me think I've found a new bug in the DateTime object (or date() function).&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;1) onvLinkViewHelperTest::testCreatePortfolioChartDatesString with data set #4 (12352343)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Failed asserting that two strings are equal.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;--- Expected&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+++ Actual&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;@@ @@&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;-FROM=23.05.1970&amp;amp;TO=03.09.2010&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+FROM=24.05.1970&amp;amp;TO=03.09.2010&lt;/span&gt;&lt;/blockquote&gt;When inspecting the behaviour I found out, that there were 2 hours of difference in time, which - in some of the provided data - lead to that the next day was returned as FROM and TO.&lt;br /&gt;&lt;br /&gt;This is because there is a second difference in date()s and DateTime()s behaviour: DateTime will &lt;a href="http://de2.php.net/manual/de/function.date-create.php#74599"&gt;ignore&lt;/a&gt; your date_default_timezone_set setting.&lt;br /&gt;&lt;br /&gt;Working with both, date() and DateTime() really seems complicated in an unnecessary fashion. I'd stick to the latter, because of the Y2K38 bug and because I prefer objects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5540569973275631268-1821780867756449745?l=blog.patrickalbertini.de' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.patrickalbertini.de/feeds/1821780867756449745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.patrickalbertini.de/2010/09/php-date-versus-datetime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/1821780867756449745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5540569973275631268/posts/default/1821780867756449745'/><link rel='alternate' type='text/html' href='http://blog.patrickalbertini.de/2010/09/php-date-versus-datetime.html' title='PHP: date() versus DateTime'/><author><name>palbertini</name><uri>http://www.blogger.com/profile/14668486542596348958</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_L_BczXTYu1A/SU-Cughm4_I/AAAAAAAAAAM/IjIxre7FDwg/s1600-R/patrick.jpg'/></author><thr:total>0</thr:total></entry></feed>
