{"record":{"id":"981a23ca27429a37","repo":"phalcon/cphalcon","slug":"invalid-bind-parameter-1","errorCode":null,"errorMessage":"Invalid bind parameter (1)","messagePattern":"Invalid bind parameter \\(1\\)","errorType":"exception","errorClass":"Phalcon\\Db\\Exceptions\\InvalidBindParameter","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Adapter/Pdo/AbstractPdo.zep","lineNumber":514,"sourceCode":"     *         \"inv_title\" => \"Test Invoice\",\n     *     ],\n     *     [\n     *         \"inv_title\" => Column::BIND_PARAM_STR,\n     *     ]\n     * );\n     *```\n     */\n    public function executePrepared(<\\PDOStatement> statement,  array placeholders, array dataTypes = []) -> <\\PDOStatement>\n    {\n        var wildcard, value, type, castValue, parameter, position, itemValue;\n\n        for wildcard, value in placeholders {\n            if typeof wildcard == \"integer\" {\n                let parameter = wildcard + 1;\n            } elseif typeof wildcard == \"string\" {\n                let parameter = wildcard;\n            } else {\n                throw new InvalidBindParameter();\n            }\n\n            if fetch type, dataTypes[wildcard] {\n                /**\n                 * The bind type needs to be string because the precision\n                 * is lost if it is casted as a double\n                 */\n                if type == Column::BIND_PARAM_DECIMAL {\n                    let castValue = (string) value,\n                        type = Column::BIND_SKIP;\n                } else {\n                    if Settings::get(\"db.force_casting\") {\n                        if typeof value != \"array\" {\n                            switch type {\n\n                                case Column::BIND_PARAM_INT:\n                                    let castValue = intval(value, 10);\n                                    break;","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Adapter/Pdo/AbstractPdo.zep#L496-L532","documentation":"executePrepared(statement, placeholders, dataTypes) iterates the placeholders array by key; integer keys are treated as positional parameters (key + 1) and string keys as named parameters. Any key of another type throws InvalidBindParameter ('Invalid bind parameter (1)'). In pure PHP, array keys are always int or string, so this surfaces through non-userland placeholders — e.g. structures produced by json_decode() with unexpected keys, generators collapsed wrongly, or direct calls from other extension/Zephir code.","triggerScenarios":"Calling executePrepared() directly (it is public) with a malformed placeholders array whose keys are not plain integers or strings; passing a data structure where values ended up as keys or where key normalization (floats, nulls) happened upstream.","commonSituations":"Custom query layers that build bind arrays from decoded JSON or object casts; integrating with libraries that hand over untyped maps; rare direct use of this low-level method instead of query()/execute().","solutions":["Pass placeholders as a positional list [value, value, ...] built with array_values(), or an assoc [name => value] map with string keys","Normalize any incoming bind structure before calling: cast keys, re-index lists","Prefer the public query()/execute() APIs which run the same pipeline with validated input"],"exampleFix":"// before\n$stmt = $connection->prepare('SELECT * FROM users WHERE id = ?');\n$connection->executePrepared($stmt, $maybeMalformedBindArray, []);\n\n// after\n$stmt = $connection->prepare('SELECT * FROM users WHERE id = ?');\n$connection->executePrepared($stmt, array_values($maybeMalformedBindArray), []);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"/** Ensure every placeholder key is int (positional) or string (named). */\nfunction normalizeBindKeys(array $placeholders): array\n{\n    $out = [];\n    foreach ($placeholders as $k => $v) {\n        if (is_int($k) || is_string($k)) {\n            $out[$k] = $v;\n        } else {\n            throw new InvalidArgumentException('Invalid bind key type: ' . gettype($k));\n        }\n    }\n    return $out;\n}\n\n$connection->executePrepared($stmt, normalizeBindKeys($placeholders), $dataTypes);","tryCatchPattern":null,"preventionTips":["Prefer query()/execute() over calling the low-level public executePrepared() directly","Re-index positional bind arrays with array_values() before passing","Reject bind structures from external sources (decoded JSON, object casts) unless keys are verified int/string"],"tags":["php","phalcon","db","bind","pdo","type-error"],"backgroundTag":"invalid-bind-parameter-key","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}