Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Database\Parser;
|
||||
|
||||
/**
|
||||
* @example
|
||||
* self::rebuild('SELECT * FROM foo WHERE id IN (:ids)', ['ids' => [1, 2, 3]])
|
||||
* Erzeugt:
|
||||
* [
|
||||
* 'statement' => 'SELECT * FROM foo WHERE id IN (:ids_expl_0_, :ids_expl_1_, :ids_expl_2_)',
|
||||
* 'values' => [
|
||||
* '_ids_expl_0_' => 1,
|
||||
* '_ids_expl_1_' => 2,
|
||||
* '_ids_expl_2_' => 3,
|
||||
* ]
|
||||
* ]
|
||||
*/
|
||||
final class MysqliArrayValueParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $statement
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
* - Array key 'statement' contains the rebuild statement
|
||||
* - Array key 'values' contains the rebuild bind parameters
|
||||
*/
|
||||
public function rebuild($statement, array $values = [])
|
||||
{
|
||||
return $this->replaceArrayValues($statement, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $statement
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function replaceArrayValues($statement, array $values = [])
|
||||
{
|
||||
foreach ($values as $paramName => $paramValue) {
|
||||
if (is_array($paramValue)) {
|
||||
$counter = 0;
|
||||
$additionalParams = [];
|
||||
foreach ($paramValue as $arrayValue) {
|
||||
$additionalParamName = '_' . $paramName . '_expl_' . $counter . '_';
|
||||
$additionalParams[] = ':' . $additionalParamName;
|
||||
$values[$additionalParamName] = $arrayValue;
|
||||
$counter++;
|
||||
}
|
||||
|
||||
// Replace original named parameter by exploded parameters in statement
|
||||
$replaceString = implode(', ', $additionalParams);
|
||||
$statement = str_replace(':' . $paramName, $replaceString, $statement);
|
||||
|
||||
// Remove original parameter value
|
||||
unset($values[$paramName]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'statement' => $statement,
|
||||
'values' => $values,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Database\Parser;
|
||||
|
||||
use Xentral\Components\Database\Exception\MissingParameterException;
|
||||
|
||||
/**
|
||||
* Responsibility of this class is to make sql statement and bind values compatible with mysqli
|
||||
*
|
||||
* (Mysqli does not support named parameters)
|
||||
*
|
||||
* It does this by:
|
||||
* - Replacing named parameters (:param) by ?-Placeholder (in statement)
|
||||
* - Rearranging bind values in order of appearance of named parameters
|
||||
*/
|
||||
final class MysqliNamedParameterParser implements ParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $statement
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rebuild($statement, array $values = [])
|
||||
{
|
||||
return $this->replaceNamedParameters($statement, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $statement
|
||||
* @param array $values
|
||||
*
|
||||
* @throws MissingParameterException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function replaceNamedParameters($statement, array $values = [])
|
||||
{
|
||||
$result = [
|
||||
'statement' => $statement,
|
||||
'values' => [],
|
||||
'params' => [],
|
||||
];
|
||||
|
||||
if (empty($values)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Split statement on named parameters
|
||||
$parts = preg_split('/(:[a-zA-Z0-9_]+)/um', $statement, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($parts as &$part) {
|
||||
if (strpos($part, ':') !== 0) {
|
||||
continue; // SQL part does not contain named parameter
|
||||
}
|
||||
|
||||
$parameterName = substr_replace($part, '', 0, 1);
|
||||
if (!array_key_exists($parameterName, $values)) {
|
||||
throw new MissingParameterException(sprintf(
|
||||
'Parameter "%s" is missing from the bound values',
|
||||
$parameterName
|
||||
));
|
||||
}
|
||||
|
||||
// Push values in same order of parameters for binding
|
||||
$result['values'][] = $values[$parameterName];
|
||||
$result['params'][] = $parameterName; // For debugging only
|
||||
|
||||
// Replace named parameter by ?-Placeholder
|
||||
$part = '?';
|
||||
}
|
||||
unset($part);
|
||||
|
||||
// Rebuild statement from (changed) parts
|
||||
$result['statement'] = implode('', $parts);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Xentral\Components\Database\Parser;
|
||||
|
||||
interface ParserInterface
|
||||
{
|
||||
/**
|
||||
* @param string $statement
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
* - Array key 'statement' contains the corrected statement
|
||||
* - Array key 'values' contains the corrected bind values
|
||||
*/
|
||||
public function rebuild($statement, array $values = []);
|
||||
}
|
||||
Reference in New Issue
Block a user