I am attempting to run a variable through several functions to obtain a desired outcome.
For example, the function to slugify a text works like this:
// replace non letter or digits by -
$text = preg_replace('~[^\\pL\d]+~u', '-', $text);
// trim
$text = trim($text, '-');
// transliterate
$text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
// lowercase
$text = strtolower($text);
// remove unwanted characters
$text = preg_replace('~[^-\w]+~', '', $text);
However, we can see that there is a pattern in this example. The $text
variable is passed through 5 function calls like this: preg_replace(..., $text) -> trim($text, ...) -> iconv(..., $text) -> strtolower($text) -> preg_replace(..., $text)
.
Is there a better way we can write the code to allow a variable sieve through several functions?
One way is to write the above code like this:
$text = preg_replace('~[^-\w]+~', '', strtolower(iconv('utf-8', 'us-ascii//TRANSLIT', trim(preg_replace('~[^\\pL\d]+~u', '-', $text), '-'))));
... but this way of writing is a joke and mockery. It hinders code readability.
Since your "function pipeline" is fixed then this is the best (and not coincidentally simplest) way.
If the pipeline were to be dynamically constructed then you could do something like:
// construct the pipeline
$valuePlaceholder = new stdClass;
$pipeline = array(
// each stage of the pipeline is described by an array
// where the first element is a callable and the second an array
// of arguments to pass to that callable
array('preg_replace', array('~[^\\pL\d]+~u', '-', $valuePlaceholder)),
array('trim', array($valuePlaceholder, '-')),
array('iconv', array('utf-8', 'us-ascii//TRANSLIT', $valuePlaceholder)),
// etc etc
);
// process it
$value = $text;
foreach ($pipeline as $stage) {
list($callable, $parameters) = $stage;
foreach ($parameters as &$parameter) {
if ($parameter === $valuePlaceholder) {
$parameter = $value;
}
}
$value = call_user_func_array($callable, $parameters);
}
// final result
echo $value;
use this as a combination of all five
$text = preg_replace('~[^-\w]+~', '', strtolower(iconv('utf-8', 'us-ascii//TRANSLIT', trim(preg_replace('~[^\\pL\d]+~u', '-', $text), '-'))));
but use as you are trying.because it is good practice rather than writing in one line.