PHP: A Custom Stream Wrapper Part 2: Reading and Seeking
In my previous post about the experimental DOM stream wrapper, I discussed the issues that came forth when opening the stream. Now, let’s take a look at another very important thing you want to do with a stream: read from and to it, and maybe move the pointer back and forth.
Reading from the stream
The DOM stream wrapper is already able to open an XML file and look for a specified node in the DOM:
PHP: Create an Object-Oriented XML Parser using the Built-in xml_* Functions
With all the fancy XML parsers/serializers/deserializers around, you would almost forget there are built-in PHP functions for defining highly customized XML parsers. You can use the xml_*
functions to assemble an XML parser step by step.
Setting up an XML parser - the procedural way
First, you create a new parser resource using
$encoding = 'UTF-8';
$parser = xml_parser_create($encoding);
The first and only argument of this function is the target encoding of the parser.
PHP: Setting up a Stream Wrapper for Manipulating the DOM
I recently felt a strong urge to write something about implementing a stream wrapper for PHP. A stream wrapper is a way to handle file interaction of any kind. PHP has built-in stream wrappers for HTTP, FTP, the filesystem, etc. But you are also allowed to implement custom protocols using your own stream wrapper. Stream wrappers are used by all file functions, like fopen()
and fgets()
. Creating a custom stream wrapper begins with creating a class (it does not have to extend anything) and then making a call to stream_wrapper_register
. In this post (and future posts on the same subject) I will develop a stream wrapper for manipulating a DOMNode
’s value using traditional file manipulation functions. The stream wrapper class is called “DOMStreamWrapper” and we register it for the protocol “dom”:
Symfony2: Setting up a Console-centered Application (with Composer)
I recently took a quick look at Composer and I have come to like it very much. I want to demonstrate the incredible ease of use. My example is also not trivial, it means to elaborate on the concept of a Console Application. The Symfony2 documentation does not tell us how to use the Console Component stand-alone, but only shows us how to add new commands to an already existing application. Therefore, let’s use Composer to set up a very light-weight Console Application, a good starting point from where you can add your own commands.
Symfony2 & Metadata: Caching Class- and PropertyMetadata
After creating a metadata factory and metadata drivers, we now need a way to cache the metadata, since collecting them at each request is way too inefficient. Luckily, the Metadata library provides us with a FileCache
(though it may be any kind of a cache, as long as it implements the same CacheInterface
). First, we make the FileCache
available as a service, and add a call to setCache
on the metadata factory:
<parameter key="matthias_annotation.metadata.cache_class">Metadata\Cache\FileCache</parameter>
<!-- ... -->
<service id="matthias_annotation.metadata.cache" class="%matthias_annotation.metadata.cache_class%" public="false">
<argument /><!-- the cache directory (to be set later) -->
</service>
<service id="matthias_annotation.metadata_factory" class="%matthias_annotation.metadata_factory.class%" public="false">
<argument type="service" id="matthias_annotation.driver_chain" />
<!-- call setCache with the new cache service: -->
<call method="setCache">
<argument type="service" id="matthias_annotation.metadata.cache" />
</call>
</service>
This provides the metadata factory with the file cache.
Symfony2: Writing a Yaml Driver for your Metadata Factory
In my previous post, I wrote about annotations and how to gather them using a metadata factory and an annotation driver. I also mentioned a future post in which I explain other ways of collecting metadata, namely by locating and parsing files in several different formats (distinguished by their extension). This is the post. In the case of our @DefaultValue
annotation, I’m thinking of a Yaml flavoured alternative. This allows us to store all default values as an array of property “name” - “value” pairs, like
Symfony2: Creating a Metadata Factory for Processing Custom Annotations
Earlier I wrote about how to create a custom annotation class. I used the annotation reader from Doctrine Common to check for the existence of the custom annotation inside the DocComment block. It is also possible to process the annotations on beforehand, and collect the processed data in ClassMetadata
and PropertyMetadata
objects. These objects are created by a MetadataFactory
. The factory uses Drivers
to collect the metadata.
My purpose in this article is to create a custom annotation @DefaultValue
which allows me to define default values for properties of a class. It should work like this:
Symfony2: creating a ParamConverter for deserializing request content
In my previous post I wrote about a listener that deserializes the request content and replaces controller arguments with the result. Johannes Schmitt made the suggestion to use a ParamConverter
for this. This of course makes sense: currently there is only a ParamConverter
for converting some “id” argument into an entity with the same id (see the documentation for @ParamConverter.
In this post I will show you how to create your own ParamConverter
and how we can specialize it in deserializing request content.
Symfony2: Deserializing request content right into controller arguments
Based on the list of most popular search results leading to my blog, using Symfony2 for building some kind of webservice seems to be quite “hot”. It also seems many people are struggling with the question how they should serialize their content to and from XML and/or JSON. Two beautiful bundles are already available for this, FOSRestBundle and JMSSerializerBundle. Both will help you a lot with this issue, by providing transparent conversion between formats for both the request content and the response body. Nevertheless, a few things are missing. For example, I want to really serialize and deserialize objects, for example, when I send a request with a comment (or part of it) like this:
Silex: creating a service provider for Buzz
The class Silex\Application
extends \Pimple
, a very lean dependency injection container, which itself implements \ArrayAccess
. This allows you to define parameters and services and retrieve them from the Application
like keys in an array. The first time I defined a service in a Silex application, in my case the Buzz Browser, I did it “inline”, i.e. inside my app.php
file. This is how I did it:
use Buzz\Browser;
$app = new Silex\Application();
$app['autoloader']->registerNamespace('Buzz', __DIR__.'/vendor/buzz/lib');
$app['buzz.client_class'] = 'Buzz\\Client\\Curl';
$app['browser'] = $app->share(function() use ($app) {
$clientClass = $app['buzz.client_class'];
return new Browser(new $clientClass);
});
// $app['browser'] is ready for use
But this is not very reusable; every Silex application that needs Buzz\Browser
as a service, needs to take care of the autoloading, configure and define the service. The Browser service is not such a very complex service, but think about everything that needs to be done to define and configure a service like the Doctrine DBAL (of course, Silex has a DoctrineServiceProvider for that already…).