Doctrine\DBAL\Driver\OCI8\OCI8Statement::convertPositionalToNamedPlaceholders PHP Method

convertPositionalToNamedPlaceholders() public static method

Oracle does not support positional parameters, hence this method converts all positional parameters into artificially named parameters. Note that this conversion is not perfect. All question marks (?) in the original statement are treated as placeholders and converted to a named parameter. The algorithm uses a state machine with two possible states: InLiteral and NotInLiteral. Question marks inside literal strings are therefore handled correctly by this method. This comes at a cost, the whole sql statement has to be looped over.
public static convertPositionalToNamedPlaceholders ( string $statement ) : string
$statement string The SQL statement to convert.
return string
    public static function convertPositionalToNamedPlaceholders($statement)
    {
        $count = 1;
        $inLiteral = false;
        // a valid query never starts with quotes
        $stmtLen = strlen($statement);
        $paramMap = array();
        for ($i = 0; $i < $stmtLen; $i++) {
            if ($statement[$i] == '?' && !$inLiteral) {
                // real positional parameter detected
                $paramMap[$count] = ":param{$count}";
                $len = strlen($paramMap[$count]);
                $statement = substr_replace($statement, ":param{$count}", $i, 1);
                $i += $len - 1;
                // jump ahead
                $stmtLen = strlen($statement);
                // adjust statement length
                ++$count;
            } elseif ($statement[$i] == "'" || $statement[$i] == '"') {
                $inLiteral = !$inLiteral;
                // switch state!
            }
        }
        return array($statement, $paramMap);
    }

Usage Example

 /**
  * @dataProvider dataConvertPositionalToNamedParameters
  * @param string $inputSQL
  * @param string $expectedOutputSQL
  * @param array $expectedOutputParamsMap
  */
 public function testConvertPositionalToNamedParameters($inputSQL, $expectedOutputSQL, $expectedOutputParamsMap)
 {
     list($statement, $params) = \Doctrine\DBAL\Driver\OCI8\OCI8Statement::convertPositionalToNamedPlaceholders($inputSQL);
     $this->assertEquals($expectedOutputSQL, $statement);
     $this->assertEquals($expectedOutputParamsMap, $params);
 }