On this page
Reference
String Inflection
Laminas\Filter\Inflector
is a general purpose tool for rule-based inflection of strings to a given target.
As an example, you may find you need to transform MixedCase or camelCasedWords into a path;
for readability, OS policies, or other reasons, you also need to lower case this;
and finally, you want to separate the words using a dash (-
).
An inflector can do this for you.
Laminas\Filter\Inflector
implements Laminas\Filter\FilterInterface
; you perform
inflection by calling filter()
on the object instance.
Options Reference
target
(required) The target string containing the placeholders to replacerules
(required) An array of inflection rulestargetReplacementIdentifier
Can be used to override the default placeholder delimiter of':'
throwTargetExceptionsOn
A boolean to indicate whether an exception should be thrown for un-processed placeholders (true
by default)
Example: Transform Mixed Case and Camel Cased Text to Another Format
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => 'pages/:page.:suffix',
'rules' => [
':page' => [
Laminas\Filter\Word\CamelCaseToDash::class,
Laminas\Filter\StringToLower::class,
],
'suffix' => 'html',
],
]);
$filtered = $inflector->filter(['page' => 'camelCasedWords']);
// pages/camel-cased-words.html
$filtered = $inflector->filter(['page' => 'this_is_not_camel_cased']);
// pages/this_is_not_camel_cased.html
Operation
An inflector requires a target and one or more rules.
A target
is basically a string that defines placeholders for variables you wish to substitute.
These are specified by prefixing the placeholder name with a :
, for example :script
.
When calling filter()
, you then pass in an array of key and value pairs corresponding to the placeholder names in the target.
Each variable in the target can have zero or more rules associated with them. Rules may be either static or refer to a filter type, or callable. Static Rules define straight-forward string replacement. Filter Rules define one or more filters that operate on the value.
Filters can be specified using:
- The FQCN of a filter such as
Laminas\Filter\StringToLower::class
- An alias of a known filter such as
stringtolower
- A concrete filter instance, i.e.
new Laminas\Filter\StringToLower()
- Any callable, for example a closure such as
static fn (string $input): string => strtolower($input)
Using Custom Filters
Laminas\Filter\Inflector
uses Laminas\Filter\FilterPluginManager
to manage loading filters to use with inflection.
By default, all standard filters are available by referencing any FQCN, or known alias of the filter type.
If you have configured your application with custom filters, these will also be available in any rules you define.
Tip
Try to prefer fully qualified class names (FQCNs) rather than aliases or 'short names'. It will be easier for your IDE or text editor to identify specific filter usage when you use FQCNs.
Setting the Inflector Target
As previously mentioned, the required option target
is a string with some placeholders for variables.
Placeholders take the form of an identifier, a colon (:
) by default, followed by a variable name: :script
, :path
, etc.
The filter()
method looks for the identifier followed by the variable name being replaced.
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => 'pages/:page.:suffix',
// ... Other Options
]);
Changing the Target Placeholder Delimiter
By setting the targetReplacementIdentifier
option to the delimiter of your choice, you can prevent issues where the delimiter might need to be part of the target
option:
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => '?host:?port/?page.?suffix',
'targetReplacementIdentifier' => '?',
'rules' => [
'host' => 'example.com',
'port' => '80',
'page' => 'anything',
'suffix' => 'html',
],
]);
$inflector->filter(['page' => 'index']); // example.com:80/index.html
Inflection Rules
As mentioned in the introduction, there are two types of rules: static and filter-based.
Specifying Static Rules
Static rules are key-value items, where ['placeholder' => 'replacement']
.
Static rule names lack a leading ':'
.
Filter input can be used to override the replacement value for a placeholder:
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => ':a,:b,:c',
'rules' => [
'a' => 'one',
'b' => 'two',
'c' => 'three',
],
]);
$inflector->filter(['c' => 'foo']); // 'one,two,foo'
Order is important
It is important to note that regardless of the rule type, either static of filter based; the order is very important.
More specific names, or names that might contain other rule names, must be added before the least specific names.
For example, assuming two rule names moduleDir
and module
, the moduleDir
rule should appear before module since the word module
is contained within moduleDir
.
If module
were added before moduleDir
, module
will match part of moduleDir
and process it leaving Dir
inside of the target un-inflected.
Filter-Based Inflector Rules
Filters may be used as inflector rules as well. Just like static rules, these are bound to a target variable; unlike static rules, you may define multiple filters to use when inflecting. These filters are processed in order, so be careful to register them in an order that makes sense for the data you receive.
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => ':script.:suffix',
'rules' => [
':script' => [
Laminas\Filter\Word\CamelCaseToDash::class,
Laminas\Filter\StringToLower::class,
],
'suffix' => 'php',
],
]);
$inflector->filter(['script' => 'MyScript']); // "my-script.php"
Avoiding Exceptions
Finally, the option throwTargetExceptionsOn
defines whether an exception is thrown for un-processed placeholders.
By default, the following example will cause an exception:
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'target' => ':script.:suffix',
'rules' => [
':script' => [
Laminas\Filter\Word\CamelCaseToDash::class,
Laminas\Filter\StringToLower::class,
],
'suffix' => 'php',
],
]);
$inflector->filter(['wrong-key' => 'SomeValue']); // Laminas\Filter\Exception\RuntimeException
By setting throwTargetExceptionsOn
to false
, no exception will be thrown, but the filter output will contain un-processed placeholder values:
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = new Laminas\Filter\Inflector($pluginManager, [
'throwTargetExceptionsOn' => false,
'target' => ':script.:suffix',
'rules' => [
':script' => [
Laminas\Filter\Word\CamelCaseToDash::class,
Laminas\Filter\StringToLower::class,
],
'suffix' => 'php',
],
]);
$inflector->filter(['wrong-key' => 'SomeValue']); // ':script.php'
Filterable Values
The inflector can only process arrays or objects. Other types will be returned as-is, for example:
$inflector->filter('string'); // 'string
When an object is passed, it's public properties are extracted into an array using get_object_vars
.
This can be useful when you wish to use a readonly value object to define a specific, predictable set of data to be used for inflection with consistent type guarantees.
Filter Plugin Manager Requirement
In all the examples so far, you will notice that the first constructor argument is an instance of Laminas\Filter\FilterPluginManager
. The plugin manager is used to create filter instances for use with inflection and cannot be omitted.
During general usage of filters, you will typically be configuring filters as part of an input filter specification with laminas-inputfilter or laminas-form
. In these cases, the constructor dependencies are resolved automatically and you only need to concern yourself with setting the correct options.
If you find the need to use the inflector stand-alone, you can use Laminas\Filter\FilterPluginManager::build()
to create an instance by only specifying options:
$pluginManager = $container->get(Laminas\Filter\FilterPluginManager::class);
$inflector = $pluginManager->build(
Laminas\Filter\Inflector::class,
[
'target' => ':script.:suffix',
'rules' => [
':script' => [
Laminas\Filter\Word\CamelCaseToDash::class,
Laminas\Filter\StringToLower::class,
],
'suffix' => 'php',
],
],
);