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 ![]() Wednesday, August 15. 2007
Want to learn more about Design Patterns? If you are interested in learning more about applying common design patterns to your applications and are able to understand German, we have good news for you. Your first chance to get information about pattern driven development from the Stubbles developers is the International PHP 2007 Conference in November, where Frank and I will be giving a half-day workshop on PHP Design Patterns. As Frank wrote last month, we are also giving some more 1-hour talks at this conference.Your second chance to learn more about design patterns is the new German professional PHP training organized by Wolfgang Drews. The course consists of 12 different sessions, I'll be giving the talks about OO developement and PHP design patterns. Other trainers include Christian Wenz, Tobias Schlitt, Kore Nordmann and Tobias Hauser. The best part about this course is, that is an online training and you do not even have to leave the house. More information can be found at the course website or Wolfgang's blog. If you prefer to read or cannot afford any of the above options, there still is my book PHP Design Patterns published by O'Reilly. ![]() 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!
![]() Monday, June 18. 2007
We are hiring!
Are you looking for a job? Are you living in Germany? Do you like Java?
If you answer all these questions with 'yes' and would like to work with the Stubbles' developers, than you should apply for a job in my team. We are looking for two Java Web Developers, that are also familiar with XML/XSLT and OOD/OOA. Knowledge of other languages like PHP or Javascript are helpful, if you are applying for this job, as you might end up developing with Stubbles. If you are interested, take a look at the (German) job description. ![]() Friday, May 25. 2007
My wishlist for PHP6, pt5: ext/phar
To ease the deployment of Stubbles applications and new versions of the framework, Frank "invented" the Stubbles Archive (also referred to as STAR). This allows us to create a single file, that contains all PHP class files as well as other resources (like XML documents or XSL templates) that are required by Stubbles in one single file. This file can be included just like you would include any other PHP file:
require stubConfig::getLibPath() . DIRECTORY_SEPARATOR . 'stubbles.php';
// now, the classloader is available and can be used
stubClassLoader::load('net.stubbles.xml.stubXMLStreamWriterFactory');Of course, this does not load all classes in the archive, but just the base classes, that are needed to run the application, by making use of the __halt_compiler() function. All other classes will be loaded from the same file using PHP's stream wrapper API. Of course, this results in a performance loss, but according to our profiling, the loss is minimal. Greg Beaver and Marcus Börger developed a similar format (based on PHP_Archive in PEAR), but implemented it in C and released it as phar in the PECL repository. Currently, the PHP core developers are discussing, whether this extension should be added to the core in the next version of PHP. Since the announcement of the phar extension, we decided that we will deprecate STAR in favor of phar, once it stabilized and got included into the core. Currently, it seems, that this will not happen in any 5.x version of PHP, so this is another candidate for my PHP 6 wishlist. I think, it would be a great addition to PHP (from a developer's and marketing point of view) to bundle libraries and applications in one single file and deploy them by copying them to a specified folder. When using STAR for deployment you get a StarClassRegistry, that knowns about all available classes in any STAR-archive that has been deployed. Loading a class from any archive gets extremely easy: require '/path/to/starReader.php';
include StarClassRegistry::getUriForClass('com.example.MyClass');The getUriForClass() method scans all archives and will cache the results so they are only scanned once. Having something along those lines backed by a C implementation would be a huge benefit, IMHO. Combining this with namespaces would be great as we finally would introduce unique names for our classes. And yes, I still know, that PHP is not Java. If I want to develop in Java, I do this at work... ![]() Tuesday, May 22. 2007
Declarative Development Using Annotations
Today, Frank and I did a session about annotations in PHP at the International PHP Conference 2007 - Spring edition. The slides give you an overview, how annotations are used in Stubbles and how you can leverage them in your own application.
A PDF version of the slides is also available on the Stubbles download page. ![]() Saturday, March 31. 2007
Loading classes from the XP-Framework
Those who are familiar with the XP-Framework may be interested to hear that it is possible to load and use the classes of XP natively within Stubbles. Read on for an example how to do that.
Continue reading "Loading classes from the XP-Framework"
![]() Saturday, March 24. 2007
My wishlist for PHP6, pt4: static initializers
I'm using static properties quite a lot, often in combination with static classes. This is, where I often encounter a major drawback in PHP. It is not possible to write code like this:
<?php
class Foo {
private static $bar = new Bar();
public static function getBar() {
return self::$bar;
}
public static function modifyBar() {
self::$bar->doSomething();
}
}
?>In PHP. it is not possible to initialize a property with an object. As long as a constructor is involved, this is no problem, as the workaround is to initialize this properties in the constructor: <?php
class Foo {
private $bar;
public function __construct() {
$this->bar = new Bar();
}
}
?>But how could this be solved, when you never create an instance of Foo but only use static method calls? Continue reading "My wishlist for PHP6, pt4: static initializers" ![]() Wednesday, March 21. 2007
Why we develop Stubbles
In an earlier entry I promised that we will explain why we develop Stubbles. Well, there is a short version of it and a long version.
Short version: for us. Read on for the long version. Continue reading "Why we develop Stubbles" ![]() Wednesday, March 21. 2007
Some remarks to serialization without pity
Terry Chay made some remarks to my last blog entry about a solution for lazy class loading without using __autoload(). Some of his statements seem like I explained my implementation not good enough leading to wrong interpretations. In this blog entry I'll use some of his statements to take a deeper look into my implementation and show that he has drawed some conclusions which I want to disprove.
He writes: Frank makes his classes that need to be serialized implement an interface (technically, it is subclassed from his base object). This object has a method (not __sleep) that serializes itself into a special object containing this data along with a string containing the class path. This object is included before session_start and reads the full path name to include the class definition just in time. That is not correct. To show this I will dig into some technical details of my implementation:
class stubSerializedObject implements stubObject
{
/**
* full qualified class name of the serialized class
*
* @var string
*/
protected $className;
[...]
/**
* the serialized class data
*
* @var string
*/
protected $data;
/**
* constructor
*
* @param stubObject $object the stubObject instance to serialize
*/
public function __construct(stubObject $object)
{
$this->className = $object->getClassName();
$this->hashCode = $object->hashCode();
$this->data = serialize($object);
}
[... rest of class ...]
I have marked the important line. It shows that the object itself is serialized which means that one can still use __sleep() and __wakeup() within the class to serialize. Obviously, there is no parallel architecture for serialization and deserialization, its just wrapped. You can’t use two frameworks, because in this case they would have conflicting ways of deserializing themselves. If you wanted to use a library from PEAR, you’d be forced to put an adapter pattern in front of it just to get the fucker to serialize. As it should become clear from what I explained above you can still put any other classes you use (maybe those from PEAR) into the session without worrying about how they should be serialized - it just uses the default serialization mechanism.
$session->putValue('stubblesClass', $stubblesClass);
$session->putValue('PEAR_Example_Class', $pearExampleClass);
No need to have an adapter. More to the point, not storing classpaths with the serialized object is a Good Thing™. Since the session is most-likely stored across servers (via the memcache best practice), storing class paths with the sessions means the directory architecture has to be shared across servers. Well, not the whole classpath is stored. Our class loader knows where the classes reside. The "class path" is just the path from there to the correct subdirectory containing the file with the class. Therefore the directory structure can be different on another server, it is just required that the directory structure of your source directory is the same, but the path to the source directory can be different on each server. So there is nowhere a hard path, the stored class path is just a relative one. ![]() Friday, March 16. 2007
Lazy loading of classes stored in a session without __autoload()
In case you use the PHP session mechanism the manual has a warning for you:
If you do turn on session.auto_start then you cannot put objects into your sessions since the class definition has to be loaded before starting the session in order to recreate the objects in your session. This also applies if you use session_start() but did not load all classes that have been put into the session in earlier requests. This can result in problems if you have a very lazy class loading and do not want to use the __autoload() feature. In Stubbles we do not use __autoload() for several reasons, one of them is that we don't want PEARified class names in style of PACKAGE_SUBPACKAGE_ABSTRACTCLASS_CONCRETEIMPLEMENTATION. I simply don't like them, its one of the reasons why I choose SimpleTest over PHPUnit. But when there is no __autoload(), how could lazy loading work? A decision made earlier was to have a basic interface for all our classes, called stubObject. Every class implements this interface (of course there is a default implementation). The trick is done with an additional class, which represents a serialized state of the concrete class. Every stubObject offers a getSerialized() method which returns a stubSerializedObject. This contains the full qualified classname and a serialized representation of the stubObject. It also features a getUnserialized() method which will load the class if it has not been loaded yet and then unserializes the stubObject . Because the stubSerializedObject is always loaded in Stubbles our session implementation can now check if a value to store is an instance of stubObject. If it is, it just stores the return value of its getSerialized() method. On a later request, when the value should be retrieved from the session, the session checks if the instance to return is of type stubSerializedObject - if this is the case it returns the return value of its getUnserialized() method which loads the required class if this has not been done yet. This approach seems to me even better than using __autoload(): it will load the required classes only if they are really used. If they are stored within the session but the current request does not use it the appropriate class will not be loaded. Very lazy, isn't it? ![]() Thursday, March 15. 2007
PHP Magazin 3.07 publishedThe second half of the article deals with SOA (Service Oriented Architectures) and shows, how SCA_SDO (a reference implementation of SOA) makes use of annotations to convert components to services and automatically handles dependency injection of local or remote services. If you are interested in using either of the two projects, consider buying an issue of the PHP Magazin 3.07. ![]() ![]() |
![]() ![]() Calendar
![]() ![]() Categories![]() Quicksearch![]() Blogs we read...![]() Syndicate This Blog![]() Blog Administration![]() ![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||




