Wednesday, December 12. 2007
Tricky namespaces? No.
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
Tricky namespaces
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:
Name/Space/DateTime.php
namespace Name::Space;
class DateTime {}
Name/Space/Ship.php
namespace Name::Space;
class Ship {
public static function __autoload($className) {
echo "loading $className\n";
// ... autoloader, can load Name::Space::DateTime
}
}
somestuff.php
function someStuffWeDoNotHaveControlOver() {
$foo = new Name::Space::DateTime();
var_dump($foo);
// ...
}
setup.php
require_once('Name/Space/Ship.php');
spl_autoload_register(array('Name::Space::Ship', '__autoload'));
Version 1, the original from David's posting:
require_once('setup.php');
use Name::Space;
$d = new DateTime();
var_dump($d);
require_once('somestuff.php'); // assumed to be here, was missing in the given example
someStuffWeDoNotHaveControlOver();
$d = new DateTime();
var_dump($d);
Result:
More after the break... Continue reading "Tricky namespaces" ![]() Sunday, November 11. 2007
Gathering practical experience with namespaces
Being a little bit bored today I started to port XJConf to PHP 5.3 using namespaces. Oh boy. You should never even think about porting your application completely to namespaces if you do not have enough unit tests! Consider something like this:
if (get_class($instance) == $someClassName) {
// do this
}
It is most likely that $someClassName does contain the name of the class only without the namespace prefix. As get_class() now returns the full qualified class name this comparison will fail - you need to make sure that $someClassName contains the full qualified class name. I'm sure there is a lot of code out there like this or similar. Another point is that you should not import classes from the same namespace, I had a situation where this lead to a fatal error because of loading the same class twice, however I was not able to create a reproducable test case after I solved the problem. As I said I would not recommend the transition without unit tests, but you have to adjust them as well. For XJConf I just had to change two things (I'm using SimpleTest): 1. expectException() requires the full qualified class name of the expected exception now 2. creating mock objects: Mock::generate('Tag'); needs to be changed to Mock::generate('net::xjconf::Tag', 'MockTag'); to enable SimpleTest finding the correct class (full qualified class name), additionally you need to state a class name for the mock class to be created, else SimpleTest will fail to create the mock class because it would produce something like Mocknet::xjconf::Tag which of course results in a parse error. Finally __autoload() makes really fun now. It receives the full qualified class name as argument, it is a simple task to change this into the correct path to the class file. If you do not use it until now due to the quirks required when not using class names like My_Application_Has_Really_Really_Long_Class_Names you should really consider using it after migrating your application to namespaces. ![]() Saturday, November 10. 2007
Subtle BC break in PHP 5.2.4
Today while evaluating PHP 5.3 I stumbled about a subtle BC break which has already been introduced in PHP 5.2.4. Consider the following code:
class Bar
{
public function dumpBar()
{
var_dump(get_object_vars($this));
}
}
class Foo extends Bar
{
public $public = 'public';
protected $protected = 'protected';
private $private = 'private';
public function dump()
{
var_dump(get_object_vars($this));
}
}
$foo = new Foo();
$foo->dump();
$foo->dumpBar();
Continue reading "Subtle BC break in PHP 5.2.4"
![]() Thursday, November 8. 2007
Slides from IPC 2007
I just put the slides from the presentations at the International PHP Conference online, you can find them in our downloads area. Unfortunately Stephan became ill some days before the conference, so I had to present the talks we intended to do together without him. However I think they went quite well and I hope everybody who listened got some new ideas for his programming work.
Those who attended my session about Dependency Injection might be interested in our new documentation for the Stubbles IoC container. It goes more into detail on how it can be used than it was possible to do in the session. As a side note, Robert Lemke had a very good session on Dependency Injection and AOP and how this is possible in the upcoming version 5.0 of the Typo3 framework. From those sessions I attended I think this was the best one. ![]() Tuesday, November 6. 2007
Tutorial for XJConf for PHP at IBM DeveloperWorks published
Just today a tutorial on XJConf for PHP was published on IBM DeveloperWorks: Process XML configuration files with PHP by Vikram Vaswani. This tutorial gives a very nice introduction into XJConf and what it is good for. I'm very thankful to Vikram Vaswani because the tutorial covers very much of the XJConf basics we should already have created user documentation for but did not due to lack of time. Additionally the article comes just in time for my talk at the International PHP Conference tomorrow morning where I will speak about Dependency Injection and how XJConf can help you with this (in parts).
![]() Tuesday, October 2. 2007
Stubbles 0.3.0 released
After three month of work we finally released version 0.3.0 of Stubbles. As all versions before this one is still an alpha version. While we had to introduce three BC breaks we also added a lot of improvements and new features. Some new major features are the completely rewritten Inversion of Control feature which is now based on Google Guice, lots of improvements to the JSON-RPC handling, a first alpha version of the XML/XSL view engine, the possibility to retrieve the return type of a method or function, and an enhancement to the persistence API which is now completely annotation based and does not force to implement a certain interface. Beside this a lot of bug fixes and smaller improvements found their way into this release. For a complete list of BC-breaks, feature enhancements and bug fixes please consult the changelog.
![]() Monday, September 24. 2007
XJConf for PHP 0.2.0 released
Some minutes ago I released version 0.2.0 of XJConf for PHP. XJConf allows to create simple to complex object structures from XML configuration files. Some of the new features include:
- abstract tags, which enable you to define the concrete type in the tag instead of the definition - define an explicit setter method for character data inside a tag - possibility to declare tags as static - new value type "xjconf:auto-primitive" to guess the type of a scalar value - implicit and explicit call to __set as well as possibility for setting public properties - XJConfFacade for a simplified usage of XJConf If you are already using version 0.1.2 you should definitely upgrade to the new version, as it offers more features as well as a simplified access to XJConf itself via the new facade. ![]() Monday, August 20. 2007
Return type hints
Just stumbled about some funny PHP behaviour: obviously there is already some return-type checking implemented.
class Foo
{
public function __toString()
{
return 313;
}
}
$foo = new Foo();
echo $foo;
Result: Catchable fatal error: Method Foo::__toString() must return a string value in ![]() Monday, August 6. 2007
Exception is an Inheritance Nazi
Warning: rant follows.
The built-in Exception class in PHP is total crap. It is an inheritance nazi preventing you from doing useful stuff in your own exception classes. Whoever made its get*() methods final and the trace property private did not thought any second about how exceptions may be used or that people need to implement their own stack trace handling. The reason I'm ranting about this is that I'm currently developing some classes that will interact directly with an application server and I need to map the exceptions thrown on the application server, delivered over the wire to my application, into my own exception classes. Of course the transferred exception contains a stack trace that I want to show within my application. But I can not create an exception instance and overload the stack trace with that one delivered over the wire and then throw this exception. The PHP exception class forces me to implement another stack trace in my exceptions, but it is nonsense, because if the exception is thrown and not caught and has no proper __toString() implementation it will just show the senseless stack trace from where it was thrown within my application, not the stack trace from the application server. Instead of reusing existing code the built-in exception class forces me to implement my own stack trace handling, overload the __toString() method and rewrite all stuff to display the correct stack trace as it is known from the native stack trace handling. Additionally I have to remind all developers using my exception that they can not call the default methods to get the stack trace but that they need to use special methods on this exceptions. Not to talk about increased memory usage because the exception contains two stack traces now. ![]() Sunday, August 5. 2007
My wishlist for PHP6, pt6: improvements to ext/reflection
For some reasons I had the need to reimplement PHP's serialize() and unserialize() functions in userland. While the Reflection API would be of great benefit for introspecting objects and grab the values of the object's properties it is not suited for this task - trying to read or set a protected or private property results in an ReflectionException. However, there are some ways to get around this restriction.
Getting the value of protected or private properties is somewhat simple: just cast the object to an array:
class Foo
{
public $foo = 'foo';
protected $bar = 'bar';
private $baz = 'baz';
}
$foo = new Foo();
$fooProperties = (array)$foo;
var_dump($fooProperties);
The result will look like: array(3) {Now it is very simple to iterate over the array and grab the values of the respective property. Using this it is just a bunch of some more code to reimplement serialize() in userland. Reimplementing unserialize() is a bit trickier, because it is really hard to set protected and private properties (but not impossible). Probably you already heard of var_export(). Using this function returns a string that can be eval()'d, that is it gives you valid PHP code to execute. This code contains a method call ClassName::__set_state(). Using this magic method you can recreate your object from userland unserialize(). Well, it is not that simple. It gets really tricky with nested objects and as soon as one of the objects you want to unserialize does not contain this method there is no way to set the protected and private properties. So, whats the lesson from this? If PHP offers possibilities to read the value of protected and private properties (and with some hackish workarounds even to set them) anyway, why just not allow this within the Reflection API? No, "because it allows developers to shoot themself in their foot" is not a valid reason. Developers will always find a way to shoot themself in their foot, regardless of the measures you undertake to protect them. By the way, it would be really nice if the reflection methods just return NULL instead of FALSE when something is not available. But that is another story about "the PHP way". ![]() Friday, July 27. 2007
Going to the International PHP Conference 2007, Part II
Since we both have been on the Spring Edition of the International PHP Conference this year, Stephan and I decided to continue with the one in November taking place in Frankfurt-Mörfelden. We will give several talks:
Stephan was notified that a workshop he submitted to be held by us both has been approved too, but it does not appear on the website (yet?). We will see what is going to happen with that one. Additionally Stephan will present a session on the AJAX in action which takes place at the same time on the same place: JSON-RPC-Proxy-Generierung mit PHP (german only). ![]() Thursday, July 26. 2007
Namespaces in action
Today I saw PHP namespaces in action. Timm Friebe, who backported the namespace patch to PHP5, showed me a namespaced version of the XP-Framework. This was very impressive! We experimented a bit with __autoload() and it was very nice to see that the function is not called on the import but actually when the class is used within the code. Additionally we played around with full and non qualified classnames, with and without the import statement. What I saw looks really promising. Keep your fingers crossed that we will get a PHP5.3 with namespaces!
![]() Sunday, July 1. 2007
Stubbles 0.2.0 released
The Stubbles team is proud to announce the release of Stubbles 0.2.0. This release is another alpha version and contains the basic MVC structure as well as support for JSON-RPC, utility packages for working with datespans, URLs and a cache package. Additionally the build system has been enhanced and a lot of bugs have been fixed. For a complete list of changes see the changelog. The release can be downloaded from our downloads page.
![]() Friday, April 27. 2007
Stubbles 0.1.0 released
The Stubbles team is proud to announce the release of Stubbles 0.1.0. This release is a first alpha version and contains the basic features of Stubbles like the Extended Reflection API, XML handling with XMLStreamWriter and XMLSerializer, Logging, Event handling, support for filtering and validating user input and session handling. The release additionally contains parts of packages that we announced to be in the next milestone 0.2.0.
![]() ![]() |
![]() ![]() Calendar
![]() ![]() Categories![]() Quicksearch![]() Blogs we read...![]() Syndicate This Blog![]() Blog Administration![]() ![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||




