Monday, July 13. 2009
Some minutes ago I released vfsStream 0.4.0, introducing support for file modes, owners and groups. While I planned to implement this at least since a year it took me three tries to get it implemented, and while implementing this I stumbled about some issues which can not be solved by vfsStream. Major problem is that the PHP functions chmod(), chown() and chgrp() do not work with vfsStream URLs due to limitations imposed by PHP (or possibly by underlying C, not sure). The stream wrapper API has no support to enable setting file modes, owner or group of a userland stream implementation. This means the usage of file mode support is limited and can not be applied to create tests for classes using one of the three functions. However, it is still possible to use file modes for testing correct usage of is_readable(), is_writable() and is_executable(). Another usage scenario is to make sure directories created with mkdir() receive the correct file mode, see the file mode example. I'm sure users will come up with other usage scenarios I did not even thought of.
Beside this new feature the release contains a bugfix for vfsStreamDirectory::addChild() to make sure adding another child of the same name as an existing child replaces this existing child, and a fix to return correct results for stat() calls. Grab the release via it's pear channel pear.php-tools.net and try it out. I suspect the file mode support may contain bugs because I did not have the time to use it in other projects, but after all, it is still in alpha stage.
Saturday, July 11. 2009
The current issue of the german PHP magazine features an article about vfsStream. On three pages Mike Wittje (I hope this is the correct Mike, just guessed ) describes how vfsStream can be used to simplify and improve unit tests for classes utilizing the file system and file system functions. Thanks to Mike for writing the article, helping to spread the word about vfsStream.
Over the weekend I'm going to test vfsStream with PHP 5.3 and try to fix any issues which pop up. I already received a patch by mail which is said to fix an issue with is_readable() (not tested yet), so it seems reasonable there will be a new release within the upcoming days.
Monday, February 16. 2009
Nearly about a year passed since the last release of vfsStream, and some bugs were found by users of vfsStream. This was quite a surprise for me since I did not expect that anybody would use it.
This evening I fixed another bug reported some days ago, and since a patch for another bug was submitted and committed about half a year ago I decided to release version 0.3.2 tonight, so these are the changes:
- added support for trailing slashes on directories in vfsStream urls, patch provided by Gabriel Birke
- fixed bug #4: vfsstream can only be read once, reported by Christoph Bloemer
- enabled multiple iterations at the same time over the same directory
A big thank you to the bug reporters for their help to improve vfsStream. This should give me some motivation to go for 0.4.0 and implement support for file modes, at least being able to store and read them - full file mode support will be a hell of a work, not sure if it is worth the effort.
Sunday, December 28. 2008
Books, tutorials and other design pattern featuring articles often tend to present the Singleton Design Pattern as the first one. This is for two reasons:
However, the Singleton design pattern is fundamentally flawed. This is nothing new and is discussed amongst developers since some years now (just search for "evil singleton"). The Singleton violates several rules of good object oriented design. Code using the Singleton class depends on that class. It is not usable without this class, which in turn makes the client code hard to test. The client code is not programmed against an interface but against a concrete class, though promoting tight coupling between the client and the Singleton, instead of the desired loose coupling. Additionally, classes implementing the Singleton pattern itself are hard to test. Singleton just replaces a global variable and hides it in a class - the global state stays in your application. So, when everybody agrees that global state is bad and that its appearance as Singleton implementations does not make the code any better, why is the Singleton design pattern so often used then? Continue reading "How to get a Singleton right"
Monday, November 10. 2008
Annotations are a really helpful feature in present-day development. An annotation is a special form of syntactic metadata that can be added to source code elements such as classes, methods, properties and parameters. They do not affect the program semantic directly, but can be used by tools and libraries to handle such annotated code in a certain way. Examples for such usage are marking classes or methods as accessible via web services, marking methods as unit test methods, or to define how an object should be persisted.
Annotations are mainly known from the Java programming language, and since Java 5.0 annotations are a language feature. More important, these annotations are accessible at runtime, which allow various new meta-programming approaches where the domain object stays very clean and does not have any references to the handling code, i.e. when persisting domain objects or rendering them into XML.
Today I want to take a look on the state of annotations in the PHP world. PHP itself does not offer such a feature, so we have to take a look at userland implementations. Such implementations are possible using the reflection API introduced with PHP 5. When looking at userland implementations one has to differentiate between specialised and generic implementations. Continue reading "State of annotations in the PHP world"
Wednesday, August 6. 2008
As requested I did my homework today and tested Stubbles against PHP 5.3 alpha1. Well, actually alpha2-dev, but that should not make that much difference. I don't know whether 5.3 is PHP on drugs, but runtime of our unit tests dropped from around 45 seconds with 5.2.5 to around 15 seconds on 5.3. Down to one third! This is really impressive. We will have to see how 5.3 will perform with the applications itself, but this raises expectations.
The other good news is that we only had two forward compatibility issues, which I instantly fixed. One of them was in a unit test and not relevant to the framework itself, the other had to do with a new check on callbacks which now forbids using private methods in callbacks, even if the callback is triggered from inside the same class.
At first I thought of just another check for the callback thing, but the comments lead me to reinspect the code. I now think it might really be a bug in PHP 5.3, therefore I created a small script to reproduce the effect, see repository. I sent it it to Lars, who will make sure it gets fixed in the final release.
Tuesday, May 27. 2008
You can either view the presentation on slideshare.net, or get the PDF in our download area. If you decide to use our implementation, you can find more information in the Stubbles manual.
Tuesday, March 11. 2008
Ìn case you are interested in a new job and speak german: Read on after the break. Continue reading "Searching for a new job?"
Monday, February 18. 2008
Just stumbled over a proposal for traits in PHP, proposed by Stefan Marr. Being a bit sceptical at first I came to the conclusion that this would be a really useful feature - and save us a bunch of doubled code in Stubbles. After reading the RFC until the end I noticed that I saw a similar concept some weeks before in Java: Qi4J tries to achieve the same, but requires very much code to get this done. As a language construct within PHP it would be very easy to do the same, but easier to learn and to use. Beside some keyword issues (the RFC uses "use" as keyword, but this will of course conflict with namespaces) I'm wondering what this will have an impact on reflection - the RFC stays unclear about this. What do I get when reflecting a method from a trait, or a method in a class that originally comes out of a trait?
However I'm not very confident that this feature will make its way into PHP - maybe I've read to much internals...
Saturday, January 26. 2008
At least if it comes to internal classes. If you try to get informations about parameters from methods of internal classes - forget that. Examining several internal classes my key findings are: either there is no information about parameters available and the reflection API says the method does not have any parameters, or the information about the parameter is wrong. Some examples I retrieved with the following script:
Continue reading "Do not trust the reflection API"
Wednesday, January 2. 2008
Against my intent of starting to work on file modes for 0.3.0 I decided that it is time to get an own repository for vfsStream in order to maintain it independently from Stubbles, which was the perfect reason to open a new project on Google Code. I will see if this proves to be a good solution for day to day development.
The movement also marked the reason to try PHPUnit because I wanted to make use of its code coverage and its software metrics features. Especially the last one showed me a bunch of points that required refactoring before starting something big like supporting file modes. During refactoring some improvements made it into the code which justified a new release: vfsStream now supports rmdir(), and I made some API changes. I dropped vfsStreamDirectory::ceate() in favor of vfsStream::newDirectory() to be equivalent to vfsStream::newFile(). Additionally there is a new vfsStreamContent::at() method now, which allows to write code like this:
So far I'm very satisfied with the software analysis features of PHPUnit that I'm thinking very hard about saying good bye to SimpleTest in my other projects. Given the current state of SimpleTest's development I do not expect to get similar features in SimpleTest any time soon, and unfortunately I do not have the time to contribute to SimpleTest even if it would be a lot of fun I guess.
Saturday, December 29. 2007
Having done more work on vfsStream I felt it is time to do the next release before starting to work on the next big issue™. The new 0.2.0 release focuses on API improvements as well as support for differentiating between directories and files. API improvements are a new vfsStream::url() method to assist in creating correct vfsStream urls. Up until now you had to write something like
which is kind of ugly and unhandy to type. Now you can do
Another API improvement is the new vfsStream::newFile() method to be able to do
Following an advice by David Zülke I changed vfsStreamWrapper::register() to reset the directory root to null.
Additionally vfsStream now supports is_dir(), is_file() and is_readable(). However there is still a small drawback to is_readable(), as long as file mode is not supported existing pathes will lead to true, and non-existing pathes to false. Currently all files and directories always have 0777 as file mode. As I require support for file modes now this will be part of the 0.3.0 release.
Another thing I found during the last days is that realpath() seems only to work with real files, but not with any other URL types. That's a bit sad because it means one can not use this function if one wants to test its file operations with vfsStream.
Friday, December 14. 2007
Some minutes ago I released the first version of vfsStream. vfsStream is a stream wrapper for a virtual file system that may be helpful in unit tests to mock the real file system. It can be used with any unit test framework, like PHPUnit or SimpleTest.
The first idea for this came up when I prepared my talk about stream wrappers for the PHP conference in Frankfurt-Mörfelden earlier this year (slides still available). Everybody knows that you should not use real databases in unit tests, so why should one use the real file system? Of course you can create an IO abstraction layer, but PHP offers such easy access to file contents via its file_get_content() and file_put_content() functions as well as with its other file system functions that it would be a bit overdone to create such a layer just for testing purposes. Additionally there are stream wrappers which allow you to create your own protocol and use it with exactly this file functions.
This was the point where I started thinking about it, so hacked together a first version as a prove-of-concept. Because it worked like a charm I started to use it in my own unit tests, which already saved me some time and problems. Today I decided it is time to release this as open source to the public to see if other people like the idea and have a use for it, therefore I did some refactorings, and did a first release. Unfortunately not everything works by now: It is currently not possible to rename a file or directory, and it is not possible to remove directories. Additionally file modes are completely ignored. The main reason for this is that I did not need one of this features until now. Feel free to send patches, wait until I have a need for it or beg me to implement them.
Wednesday, December 12. 2007
So I put down this namespace examples together last night. But, what's happening in the examples regarding to resolution rules? (I won't post the code here again, have a look at the last entry for the example code.)
Version 1 and 2 two are the same, the place where we include other code does not influence naming rules in the current file. Why do we get instances of PHP's internal DateTime class instead of the one from Name::Space? Well, two things have to be considered:
1. We are in the global space, PHP will only look for DateTime in the global space.
2. The use-Statement declares that we want to create a shortcut to Name::Space, not to Name::Space::DateTime. If we wanted to use the class from Name::Space we would need to write $d = new Space::DateTime, which is version 3.
(We can not do a use Name::Space::DateTime here, this results in a fatal error. However, we could do use Name::Space::DateTime as DT and then write $d = new DT(), this will give instances of Name::Space::DateTime.)
With version 4 we have put our example code into its own namespace, but the result is still the same as in version 1 and 2. What's happening?
1. We are in namespace foo, and in namespace foo no class DateTime exists.
2. Our shortcut use Name::Space still does not refer to Name::Space::DateTime, to create instances from this class we still need to write $d = new Space::DateTime as in version 5. This means the class does not apply either in version 4.
3. As no further use declarations exist, PHP falls back to its internal DateTime class. (If this class would not exist, a call to the registered autoload function would be issued.)
Finally, version 6 gives the result we originally intended: The class Name::Space::DateTime is used instead of PHP's internal class. This is because we stated in the use declaration that we want to use Name::Space::DateTime as DateTime.
However, in the original posting of David Zülke in php internals he feared that the two instances of $d might be from different classes. Well, this might really happen under some circumstances. More after the break... Continue reading "Tricky namespaces? No."
Wednesday, December 12. 2007
Today on php-internals David Zülke posted an interesting example with namespaces which made me think about the result of the small example. Well, my first guess was not right as my experiments showed. Therefore I tried different versions of the example to see the impact of namespace and use declarations. But first, the example:
Version 1, the original from David's posting:
More after the break... Continue reading "Tricky namespaces"