function NamedPlaceholderConverter::parse

Parses an SQL statement with named placeholders.

This method explodes the SQL statement in parts that can be reassembled into a string with positional placeholders.

Parameters

string $sql: The SQL statement with named placeholders.

array<string|int, mixed> $args: The statement arguments.

File

core/modules/mysqli/src/Driver/Database/mysqli/NamedPlaceholderConverter.php, line 114

Class

NamedPlaceholderConverter
A class to convert a SQL statement with named placeholders to positional.

Namespace

Drupal\mysqli\Driver\Database\mysqli

Code

public function parse(string $sql, array $args) : void {
  // Reset the object state.
  $this->originalParameters = [];
  $this->originalParameterIndex = 0;
  $this->convertedSQL = [];
  $this->convertedParameters = [];
  foreach ($args as $key => $value) {
    if (is_int($key)) {
      // Positional placeholder; edge case.
      $this->originalParameters[$key] = $value;
    }
    else {
      // Named placeholder like ':placeholder'; remove the initial colon.
      $parameter = $key[0] === ':' ? substr($key, 1) : $key;
      $this->originalParameters[$parameter] = $value;
    }
  }
  /** @var array<string,callable> $patterns */
  $patterns = [
    self::NAMED_PARAMETER => function (string $sql) : void {
      $this->addNamedParameter($sql);
    },
    self::POSITIONAL_PARAMETER => function (string $sql) : void {
      $this->addPositionalParameter($sql);
    },
    $this->sqlPattern => function (string $sql) : void {
      $this->addOther($sql);
    },
    self::SPECIAL => function (string $sql) : void {
      $this->addOther($sql);
    },
  ];
  $offset = 0;
  while (($handler = current($patterns)) !== FALSE) {
    if (preg_match('~\\G' . key($patterns) . '~s', $sql, $matches, 0, $offset) === 1) {
      $handler($matches[0]);
      reset($patterns);
      $offset += strlen($matches[0]);
    }
    elseif (preg_last_error() !== PREG_NO_ERROR) {
      throw new \RuntimeException('Regular expression error');
    }
    else {
      next($patterns);
    }
  }
  assert($offset === strlen($sql));
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.