Examples

The XP APIs by topic

at 2008-05-10 in ExamplesAnnouncements by friebe

The documentation website now contains an overview of the XP framework's APIs by topic - Databases, I/O, XML, Dates, Collections, Web and Imaging. Although the overview is initially done, there is still lots of text to write.

The first two topics to be covered are Databases in general and our Object persistence API.



Writing a parser: Calculator example

at 2008-02-10 in Examples by friebe

In many situations, we need to transform user input to machine readable data. Mostly, a regular expression, sscanf or even very simple handling via string functions will be sufficient. For more complex (and forgiving) input, and when we want to tell users what went wrong where these methods may not be enough.

Imagine a situation in which you would like to evaluate mathematical expressions, so, for example, the user would be inputting something like 1 + 2 or -1 / (3 * 6) and you would like output the expression's result. Something like this:

Calculator console screenshot

Using eval is not an option because you're not in control over what is passed - this creates security problems!


(more)

Using sscanf

at 2008-01-26 in Examples by friebe

To parse strings, you've probably used different of the many string functions that come bundled with PHP, strtok, explode, strstr, regular expressions and maybe even the more "exotic" C-like strcspn or strcasecmp. One of the candidates most often overlooked is sscanf.

Here are some examples.


(more)

Enum usecases: Replace switch/case blocks

at 2007-11-12 in Examples by friebe

When migrating parts of my photoblog's import scripts to command classes I stumbled upon the following block of code:

<?php 
switch
($group= $param->value('group')) {
case
'day': $strategy= new GroupByDayStrategy(); break;
case
'hour' : $strategy= new GroupByHourStrategy(); break;
default: throw
new IllegalArgumentException('No such grouping method "'.$group.'"');
}
?>

Except for putting this switch block into a GroupingStrategyFactory class to comply to DRY principles, this is basically OK, but I still wasn't happy having three (one interface, two concrete implementations) or four (for the case I'd add a factory) class files around for something this small.

Continue reading to see how this can be done with enums.


(more)

Enum usecases: Profiling

at 2007-07-29 in Examples by friebe

As you might now, from time to time, I investigate PHP language features on their performance. Examples include if / elseif vs. if / else if (no difference), testing control structures (switch vs. if / else cascades vs. the ternary operator - if / else cascades are the fastest, see entry #179) or whether default arguments have an impact (none).

What I did to compare these was to create a class for each strategy, use reflection to load it depending on the command line argument passed and then run it, printing out profiling information gathered via util.profiling.Timer. See here for an example.

The downsides of this approach were:

  • There was no way to run all strategies at once
  • Every strategy I added needed to be manually added to the usage
  • The profiling / runner sourcecode was copied every time

While searching for alternatives, I came up with a nice solution using enums (see also entry #200).


(more)

XPCLI: Command line classes

at 2007-07-22 in Examples by friebe

It's been a while since RFC #0102 has been implemented, and since then a couple of questions have arisen on how to use the runnable classes proposed within it and what their benefits over plain-old PHP scripts are.

Let's start with an overview of command line scripts' requirements:

  • Parameter handling
  • Usage
  • Output informational text to standard output, errors to standard error
  • Simulation mode/testability


(more)

Loading resources

at 2007-05-12 in Examples by friebe

Yesterday we talked about what is the most elegant way to load a resource existing "alongside" a class. With "alongside", we mean:

$ ls -a de/thekid/demo/
. .. BusinessLogic.class.php bl-config.ini

To load this resource, Alex was using the folllowing:
<?php 
$r= ClassLoader::getDefault()->getResource(
strtr
($this->getClass()->getPackage()->getName(), '.', '/').'/bl-config.ini'
);
?>

As of today, the lang.reflect.Package class was extended to provide this out of the box. The following is now possible:
<?php 
$r= $this->getClass()->getPackage()->getResource('bl-config.ini');
?>



Tokenizing

at 2007-05-11 in Examples by friebe

To split up a string into tokens, you may have used strtok() (although it has problems, as is documented here). The XP Framework offers a replacement - the text.StringTokenizer class, which you may use as follows:

<?php 
$st= new StringTokenizer("Hello World!\nThis is an example", " \n");
while
($st->hasMoreTokens()) {
printf
("- %s\n", $st->nextToken());
}
?>

This is nothing new - this API has existed for over two years now. Since yesterday, a couple of things have been added, though. Continue reading to find out what other new features there are.


(more)

Showcase: The create() function

at 2007-05-06 in Examples by friebe

As a side product of RFC #0106, the create() core functionality, which is used to create generic objects, provides an overloaded variant of itself: When passed an object, it will return it.

This may seem a bit strange (and kind of useless) in the first moment, but actually solves a deficit in the PHP parser, which does not allow chaining after new:

<?php 
$c= new Criteria()->add('author_id', 501, EQUAL); // Parse error
?>

By using create(), we can work around this as follows:
<?php 
$c= create(new Criteria())->add('author_id', 501, EQUAL);
?>



Introducing Generics

at 2007-04-29 in Examples by friebe

With RFC #0106 implemented, the collection API now offers generics support.

What are generics?
To best explain what generics are let's start with a non-generic example of a container class:

<?php 
class Container extends Object {
public
$elements= array();

public
function add(Generic $o) {
$this->elements[]= $o;
}
}
?>

The Container's add() method accepts any value, regardless of its class. Imagine we were using this container to store - say - integers, and suddenly someone was adding a string to this container:
<?php 
$container= new Container();
$container->add(new Integer(5));
$container->add(new Integer(1));

// ... and then somewhere later on:
$container->add(new String('Hello'));

// ... and finally, somewhere completely different:
foreach
($container->elements() as $number) {
Console::writeLine
($number->intValue());
}
?>

When the iteration reaches the offset containing the string object, the program will die with a fatal error, because the string class does not provide an intValue() method.

Continue reading to see how generics can help you in these situations!


(more)

Subscribe

You can subscribe to the XP framework's news by using RSS syndication.


Categories

News
General
PHP5
Announcements
RFCs
Further reading
Examples
Editorial
EASC
Experiments
Unittests
Databases