{"record":{"id":"979481041c395702","repo":"phalcon/cphalcon","slug":"syntax-error-in-string-text","errorCode":null,"errorMessage":"Syntax error in string '{text}'","messagePattern":"Syntax error in string '(.+?)'","errorType":"exception","errorClass":"Phalcon\\Support\\Helper\\Str\\Exceptions\\SyntaxError","httpStatus":null,"severity":"error","filePath":"phalcon/Support/Helper/Str/Dynamic.zep","lineNumber":36,"sourceCode":" * by the separator\n */\nclass Dynamic\n{\n    /**\n     * @phpstan-param non-empty-string $separator\n     */\n    public function __invoke(\n        string text,\n        string leftDelimiter = \"{\",\n        string rightDelimiter = \"}\",\n        string separator = \"|\"\n    ) -> string\n    {\n        var ldS, rdS, matches, match, words, word, sub;\n        string pattern;\n\n        if unlikely mb_substr_count(text, leftDelimiter) !== mb_substr_count(text, rightDelimiter) {\n            throw new SyntaxError(text);\n        }\n\n        let ldS = preg_quote(leftDelimiter),\n            rdS = preg_quote(rightDelimiter),\n            pattern = \"/\" . ldS . \"([^\" . ldS . rdS . \"]+)\" . rdS . \"/\",\n            matches = [];\n\n        if !preg_match_all(pattern, text, matches, 2) {\n            return text;\n        }\n\n        if typeof matches == \"array\" {\n            for match in matches {\n                if !isset match[0] || !isset match[1] {\n                    continue;\n                }\n\n                let words = explode(separator, match[1]),","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Support/Helper/Str/Dynamic.zep#L18-L54","documentation":"Phalcon\\Support\\Helper\\Str\\Dynamic expands placeholder groups such as '{Hello|Hi} {world}' into every combination. Before matching it compares mb_substr_count() of the left vs right delimiter; a mismatch means a placeholder is unclosed or the content contains stray delimiters, and it throws Phalcon\\Support\\Helper\\Str\\Exceptions\\SyntaxError (\"Syntax error in string '{text}'\"). Delimiters are configurable (defaults '{' and '}').","triggerScenarios":"(new Dynamic())('Hello {name') — one '{', zero '}'; text containing literal unbalanced braces ('function() { return 1;'); custom delimiters that collide with characters occurring in the content.","commonSituations":"Generating message/subject variants from copy written by non-developers who drop a brace; passing snippets of code/CSS/JS through the helper; user-supplied template text with unmatched delimiters.","solutions":["Balance the delimiters — every '{' needs its matching '}'","For content with literal braces, switch to delimiters that cannot occur in it: (new Dynamic())($text, '{{', '}}') or ('<', '>')","Strip or escape stray delimiters from user input before processing"],"exampleFix":"// before\n$variants = (new Dynamic())('Hello {name'); // 1 '{' vs 0 '}' -> SyntaxError\n\n// after\n$variants = (new Dynamic())('Hello {name}'); // balanced","handlingStrategy":"validation","validationCode":"$left  = mb_substr_count($text, '{');\n$right = mb_substr_count($text, '}');\n\n$result = ($left === $right)\n    ? (new \\Phalcon\\Support\\Helper\\Str\\Dynamic())($text)\n    : str_replace(['{', '}'], '', $text); // or log and reject","typeGuard":"function hasBalancedDelimiters(string $text, string $left = '{', string $right = '}'): bool\n{\n    return mb_substr_count($text, $left) === mb_substr_count($text, $right);\n}","tryCatchPattern":"use Phalcon\\Support\\Helper\\Str\\Exceptions\\SyntaxError;\n\ntry {\n    $variants = (new Dynamic())($text);\n} catch (SyntaxError $e) {\n    // message embeds the offending text\n    $logger->warning($e->getMessage());\n    $variants = [$text];\n}","preventionTips":["Validate delimiter balance for any user-entered template string before processing","Pick delimiters that cannot occur in the content ('{{'/'}}', '<'/'>')","Keep brace-heavy literal content (code, CSS, JS) out of Dynamic input"],"tags":["phalcon","string","template","delimiters"],"backgroundTag":"template-syntax-error","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}