Skip to content

Instantly share code, notes, and snippets.

@vanchelo
Created August 20, 2014 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanchelo/a6f01f2717a8f2f2ccd5 to your computer and use it in GitHub Desktop.
Save vanchelo/a6f01f2717a8f2f2ccd5 to your computer and use it in GitHub Desktop.
<?php
class ArrayValidator
{
private $lasterror;
private $circuiterror;
public function __call($name, $args)
{
$name = $name . '_';
return call_user_func_array([self, $name], $args);
}
public static function __callStatic($name, $args)
{
$name = $name . '_';
return call_user_func_array([self, $name], $args);
}
private function arraySameKeys_(Array $array1, Array $array2)
{
if (array_merge(array_diff_key($array1, $array2), array_diff_key($array2, $array1)))
{
return self::setError('#! Не совпали ключи массивов.', [
'element' => $array1,
'prototype' => $array2
]);
}
else
{
return true;
}
}
private function validateValue_($value, $rule, $circuit)
{
if ( ! empty($this) && ! empty($this->callback))
{
$callback = $this->callback;
if ( ! $callback($value, $rule))
{
return self::setError('#! Значение {' . $value . '} не прошло валидацию по правилу {' . $rule . '}. (Коллбэк)', $circuit);
}
else
{
return true;
}
}
else
{
if ( ! preg_match($rule, $value))
{
return self::setError('#! Значение {' . $value . '} не прошло валидацию по правилу {' . $rule . '}.', $circuit);
}
else
{
return true;
}
}
}
private function setCallback_(callable $callback)
{
$this->callback = $callback;
return $this;
}
private function listValidate_($candidate, $prototype, $length = 0)
{
if ($length && $length != count($candidate))
{
return self::setError('#! Длина массива не соответствует заявленной. Получено: ' . count($candidate) . '. Должно быть: ' . $length . '.', $candidate);
}
if (is_array($prototype))
{
foreach ($candidate as $key => $value)
{
if ( ! self::protoValidate($value, $prototype))
{
return false;
}
}
}
else if (is_string($prototype))
{
foreach ($candidate as $key => $value)
{
if (is_string($value))
{
if ( ! self::validateValue($value, $prototype, $candidate))
{
return false;
}
}
}
}
else if ($prototype === null)
{
return true;
}
else
{
return self::setError('#! Не верный тип данных в прототипе.', $prototype);
}
return true;
}
private function protoValidate_($element, $prototype)
{
if (array_key_exists('_prototype_', $prototype) || array_key_exists('_length_', $prototype))
{
$_candidate_ = $element;
$_prototype_ = array_key_exists('_prototype_', $prototype) ? $prototype['_prototype_'] : null;
$_length_ = array_key_exists('_length_', $prototype) ? $prototype['_length_'] : 0;
if ( ! self::listValidate($_candidate_, $_prototype_, $_length_))
{
return false;
}
}
else
{
if ( ! self::arrayValidate($element, $prototype))
{
return false;
}
}
return true;
}
private function arrayValidate_($value, $prototype)
{
if (is_array($value))
{
if ( ! self::arraySameKeys($value, $prototype))
{
return false;
}
foreach ($value as $index => $element)
{
if (is_string($prototype[$index]) && is_string($element))
{
if ( ! self::validateValue($element, $prototype[$index], $value))
{
return false;
}
}
else if (is_array($element) && is_array($prototype[$index]))
{
if (!self::protoValidate($element, $prototype[$index]))
{
return false;
}
}
else
{
return self::setError('#! Не совпадают типы данных', [
'element' => $element,
'prototype' => $prototype[$index]
]);
}
}
}
else
{
return self::setError('#! Не верный тип данных элемента. Ожидался: массив. Получен: немассив :-)', $value);
}
return true;
}
private function getLastError_()
{
if ( ! empty($this))
{
return $this->lasterror;
}
else
{
return null;
}
}
private function getCircuitError_()
{
if ( ! empty($this))
{
return $this->circuiterror;
}
else
{
return null;
}
}
private function setError_($string, $circuit = null)
{
if ( ! empty($this))
{
$this->lasterror = $string;
$this->circuiterror = $circuit;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment