phalcon/cphalcon · error · Phalcon\Support\Helper\Str\Exceptions\InvalidReplaceFormat

Parameter replace must be an array or a string

Error message

Parameter replace must be an array or a string

What it means

Phalcon\Support\Helper\Str\Friendly produces URL-friendly titles. Its 4th argument $replace (extra characters to strip, in addition to the built-in accent matrix) must be a string or an array of strings; checkReplace() throws Phalcon\Support\Helper\Str\Exceptions\InvalidReplaceFormat ('Parameter replace must be an array or a string') for any other type. Note that falsy values (null, '') are skipped safely — truthy non-strings (int, float, true, objects) are what throw.

Source

Thrown at phalcon/Support/Helper/Str/Friendly.zep:68

        if lowercase {
            let friendly = this->toLower(friendly);
        }

        let friendly = preg_replace("/[\\/_|+ -]+/", separator, friendly);

        return trim(friendly, separator);
    }

    /**
     * @param array<array-key, string>|string $replace
     *
     * @return array<array-key, string>
     * @throws InvalidReplaceFormat
     */
    private function checkReplace(var replace) -> array
    {
        if typeof replace !== "array" && typeof replace !== "string" {
            throw new InvalidReplaceFormat(
                "Parameter replace must be an array or a string"
            );
        }

        if typeof replace === "string" {
            let replace = [replace];
        }

        return replace;
    }

    /**
     * @param array<array-key, string> $replace
     *
     * @return array<string, string>
     */
    private function getMatrix(array replace) -> array
    {

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Pass a string ('.') or an array of strings (['-', '_', '.']) as $replace
  2. Omit the argument entirely when no extra replacements are needed
  3. Normalize at the boundary: $replace = is_string($r) || is_array($r) ? $r : [];

Example fix

// before
$slug = (new Friendly())($title, '-', true, 45); // int -> throws

// after
$slug = (new Friendly())($title, '-', true, ['-', '.']);
Defensive patterns

Strategy: validation

Validate before calling

if (!is_string($replace) && !is_array($replace)) {
    $replace = []; // null is also safe to pass; truthy scalars are not
}

$slug = (new \Phalcon\Support\Helper\Str\Friendly())($title, '-', true, $replace);

Type guard

function isValidFriendlyReplace($replace): bool
{
    return null === $replace || is_string($replace) || is_array($replace);
}

Try / catch

use Phalcon\Support\Helper\Str\Exceptions\InvalidReplaceFormat;

try {
    $slug = (new Friendly())($title, '-', true, $replace);
} catch (InvalidReplaceFormat $e) {
    $slug = (new Friendly())($title, '-', true); // retry without replace
}

Prevention

When it happens

Trigger: (new Friendly())('My Title', '-', true, 123); passing true or a float as $replace; a config-driven replace value that comes back typed as int (e.g. 45 instead of '45' or ['-']).

Common situations: Copy-pasting call sites where the 4th argument was numeric in a different helper; config values with wrong types feeding slug generation; passing an ASCII code instead of the character itself.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/b431e8ecbbf8a03c. Report an issue: GitHub.