My favorites | Sign in
Project Home Downloads Issues Source
Project Information
Members
Featured
Downloads
Links

Объекты: String, Map, Number - аналоги примитивов string, array, float+integer из PHP-Core

Описание, Преимущества

В отличии от большинства известных оберток(в том числе в отличии от встроенного ArrayObject), которые есть только "демонстрацией возможностей" и базируются на рефлексии и лени автора - данная библиотека создана для полной замены встроенных примитивов полноценными объектами.

Более логические и последовательные названия методов, порядок аргументов в них и возвращаемые значения, чем в встроенных функциях php (смотрите интерфейсы соответствующих объектов. Обратите внимание на, например String::preg*() методы)

Поддерживается цепочка вызовов с плавным переходом между объектами

$map = new Map('a', 'b', 'c');
$map
  ->join() // String object
  ->add('def') // 'abcdef'
  ->split(2) // Map object
  ->length(); // Number object

Плавное "встраивание" в интерфейс заменяющее примитивы в таких переменных, как $GLOBALS, $_POST и т.п. на соответствующие объекты:

Map::found(); // Основаться
$GLOBALS->dump();

Позволяет работать с объектами и как с примитивами и как с объектами (тем не менее, нельзя забывать, что объекты передаются по ссылке, тогда как массивы копируются, из-за чего может быть несущественное отличие в поведении):

$map = new Map('a', 'b', 'c');
foreach ($map as $val) {
  echo $val; // 'abc'
}
while($map->each($val)) {
  echo $val; // 'abc'
}

Имеется встроенный объект для создания дампа объектов (аналог var_dump), который не выводит лишнюю информацию о данных объектах как встроенные аналоги, и метод dump() у каждого из объектов, чтобы можно было получить значение объекта не выходя из цепочки:

Map::create('a', 'b', 'c')
  ->join(',')
  ->dump()
  ->replace('b', 'e')
  ->dump();

/**
(String) 'a,b,c'
(String) 'a,e,c'
 */

echo new Dump($somevar); // Если мы не знаем, каким объектом будет $somevar

Возможность создания объекта через статический метод, или функцию для того, чтобы сразу начать работать с цепочкой:

$map = String::create('def')
  ->insert('abc ')
  ->changeCase(Str::TITLE, Str::UP_FORCED)
  ->split()
  ->dump();

$map = o('def')
  ->insert('abc ')
  ->changeCase(Str::TITLE, Str::UP_FORCED)
  ->split()
  ->dump();
/**
Map [
	0 : 'A'
	1 : 'b'
	2 : 'c'
	3 : ' '
	4 : 'D'
	5 : 'e'
	6 : 'f'
]
 */

Все методы, которые должны работать с примитивами - одинаково хорошо работают что с примитивами, что с их объектными аналогами:

o('a', 'b')
  ->merge(
    new Map('c', 'd'),
    array('e', 'f'),
    'g', new String('h')
  )
  ->dump();
/**
Map [
	0 : 'a'
	1 : 'b'
	2 : 'c'
	3 : 'd'
	4 : 'e'
	5 : 'f'
	6 : 'g'
	7 : (String) 'h'
]
*/

Экземпляр объекта Map содержит в себе примитивы, или объекты - зависимо от того, что передать объекту, а подменяет примитивы на соответствующие объекты только при надобности (для того, чтобы не делать лишней работы). Кроме маленьких пометок во время Dump'a на работу конечного пользователя никак не влияет данный ньюанс - все выходные данные есть либо объектами, либо типами, которые не предусмотренны данной библиотекой (например, bool). (См. предыдущий пример)

Позволяет реализовать практически полноценный typehinting, что нельзя реализовать при использовании примитивов:

function testTypeHinting (Number $num) {
	return $num->root(5);
}

$num = new Number (15);
$str = new String ('test');

   testTypeHinting($num)->dump(); // (Number) 1.71877192759
// testTypeHinting($str)->dump(); // Catchable fatal error

От данных объектов можно наследовать другие объекты, которые будут реализовывать расширенный функционал, или специальную логику, сохранив при этом функционал родительского класса

Встроенный конвертер величин, поддерживающий группировку:

// Сколько байт в 300 гигабайтах?
echo o(300)->convert('Bytes', 'GiB', 'B'), "\n"; // 322122547200
// Сколько секунд в 3 сутках?
echo o(3)  ->convert('Time', 'Day', 'Second'), "\n";  // 259200
// Сколько метров в одной морской миле?
echo o(1)  ->convert('Length', 'SeaMile', 'Metr'), "\n"; // 1852

Вместе с возможностью наследования позволяет делать очень полезные вещи (в примере видна группировка через точку):

// Смотрите «KurrencyKonverter.php» в «Downloads»
$uah = new KurrencyKonverter (500);
// Сколько долларов у нас будет, если мы купим их в Украине за 500 гривень
echo $uah
	->copy()
	->convert('Currency.Ua.Sell', 'UAH', 'USD')
	->toString(2); // 63,02
// Сколько долларов у нас будет, если мы купим в Украине за 500 гривень рубли, а потом в России за эти же рубли - доллары
echo $uah
	->convert('Currency.Ua.Sell', 'UAH', 'RUR')
	->convert('Currency.Ru'     , 'RUR', 'USD')
	->toString(2); // 44,77

Поддерживает последние актуальные версии php и их особенности, например замыкания (closures). При этом, возможность их использовать совершенно не мешает для более молодых версий этого языка:

$n = new Number(115);
if($n->match(function ($t) {
	return ($t->root(3)->gt(5)); // Если кубический корень числа больше 5 - истина, иначе - ложь
})) {
	echo '$n is greater than 125', "\n";
} else {
	echo '$n is smaller or equal than 125', "\n";
}


$s = new String("Some string with number(e.g. 12345), is here");
echo o($s)->replace(array('string', 'number'), function ($r) {
	return $r->changeCase(Str::ALL, Str::RANDOM); 
}); // Some sTrINg with NuMbEr(e.g. 12345), is here
echo "\n";


o(1, 4, 7, 9, 15)->clear(function ($key, $value) {
	if ($key == 0) {
		return true; // Элемент с ключем равным 0 оставляем независимо от значение
	}
	if ($value > 6 and $value < 13) {
		return true;  // Оставить только значения между 6 и 13
	} else {
		return false; // Все остальное убить
	}
})->dump(); // [7, 9];


// Метод сам определит - здесь лямбдда функция, или обычный параметр (например, строка, или объект String):
echo o($s)->pregReplace("/([0-9]+)/", function ($m) {
	return "!$m[0]!"; // Some string with number(e.g. !12345!), is here
});        
echo "\n";


// Для более старых версий все-еще поддерживается старый синтаксис:
echo o($s)->pregReplaceCallback("/([0-9]+)/", create_function('$m',
	'return "!$m[0]!";' // Some string with number(e.g. !12345!), is here
));

Ну и вспомним Руби :) Конечно, не так изящно, как в оригинале, но, согласитесь, своя романтика в этом есть.

o(5)->times(function ($i) use ($n) {
	echo ($i->isEven()) ? "Even: " : "Odd : ";
	echo $n , "." , $i , ";\n";
});
/*
Even: 5.0;
Odd : 5.1;
Even: 5.2;
Odd : 5.3;
Even: 5.4;
*/

Недостатки

Возможно уменьшение скорости работы методов в ~1-3 раза по сравнению с core-функциями (зависимо от объема данных - чем больше объем - тем меньше увеличение времени), но учитывая, что вызов core-функций обычно(тем более, с малыми переданными объемами) - это лишь крохи в сравнении с временем затраченным на выполнение запросов - общее увеличение времени выполнения работы скрипта будет незначительным (на 1-5%).

Расширенный пример

Данный пример стоит детальнее посмотреть в браузере

Map::found();
$GLOBALS->dump();

class Test {
	public    $beerpub = 123;
	protected $protos  = 234.543;
	private   $vipriv  = array ();
	private   $array = array();

	public function __construct () {
		$this->vipriv['this'] = $this;
		$this->vipriv['str']  = new String ('privStr');
		$this->vipriv['int']  = new Number (13);
	}
}

$map = Map::create(
		new String ('test'),
		new Number (14),
		new Map ('aaa', 'bbb'),
		new Test ()
	)
	->merge(
		array ('value1', 'key'=>'value2'),
		'String',
		123
	)
	->dump()
	->remove(3)
	->join(',', 1) // String
	->split(8) // Map
	->dump();
$map->reset();
$newMap = new Map;
while ($map->each($key, $value)) {
	if (mt_rand(0, 1)) {
		$newMap[] = $value;
	}
}
$newMap
	->join(' ') // String
	->replace(',', 'зпт')
	->changeCase(Str::TITLE, Str::UP_FORCED)
	->insert('[вставлено]', 5)
	->length() // Number
	->multiply(4)
	->add(6, 9, new Number(15))
	->divided(5)
	->sum(Number::EVEN)
	->dump() // (Number) 1062.51
	->root(4)
	->round(3) // Just 3 symbols after dot
	->dump() // (Number) 5.709
	->round(Number::UP) // round to up (ceil)
	->hex('15abbf')
	->toString() // String ('1420223')
	->hash() // 'md5' as default
	->dump(); // (String) '0d1b1558224c8f3b125cd905c378c9f7'

Зависимости

Необязательны интерфейсы (предоставлены в ознакомительных целях). Можете убить, не забыв при этом удалить из объявления классов.

Подключение

Require всех файлов библиотеки

Требования

Желательна последняя версия PHP. Минимум - пятая. При недостаточно высокой версии могут не работать некоторые методы (например, метод hash для php < 5.1.2 может работать некорректно для нестандартных алгоритмов (все, кроме "md5", "sha1", "crc32")

Подробнее

В коде и интерфейсах

Powered by Google Project Hosting