Нове розширення PHP дозволяє додавати довільні методи до скалярів

На Github з'явилося нове експериментальне розширення PHP "scalar_objects", за допомогою якого можна додавати будь-які методи до чисел, рядків, масивів.
Виглядає це приблизно так:

$result = $string->replace('shit', 'candy')->remove(',')->toUpper()->split(" ")->sort();


Симпатично, чи не так?
Інструкції з установки можна знайти за посиланням вище, потрібно PHP 5.4.
Майте на увазі, що розширення перебуває в дуже ранній альфа-версії, перший Комміт датований 24 січня.
Радує, що автор розширення — контриб'ютор PHP Микита Попов: є ймовірність, що подібне API небудь додадуть в ядро інтерпретатора.
Далі я просто покажу як можна використовувати ці нові можливості в розробці.

Припустимо, у нас є ось такий рядок:

$string = 'lemon, orange, shit, banana, apple';


Завдання:
  • замінити shit на candy;
  • прибрати коми;
  • перевести рядок у верхній регістр;
  • розділити слова і помістити їх в масив;
  • відсортувати цей масив за алфавітом.

Зазвичай це робиться так:

$string = str_replace('shit', 'candy', $string); 
$string = str_replace(',', '', $string); 
$string = strtoupper($string); 
$array = explode(' ', $string); sort($array);


За допомогою даного розширення задача вирішується в один рядок:

$result = $string->replace('shit', 'candy')->remove(',')->toUpper()->split(" ")->sort();


Все зрозуміло і красиво, тільки як таке провернути?

1. Встановлюємо розширення scalar_objects;
2. Створимо класи-Хендлер для рядків і масивів з потрібними нам публічними методами:


class StringHandler {
  public function replace($from, $to) { 
    return str_replace($from, $to, $this); 
  } 
  public function split($separator, $limit = PHP_INT_MAX) { 
    return explode($separator, $this, $limit); 
  } 
  public function toUpper() { 
    return strtoupper($this); 
  } 
  public function remove($what) { 
    return $this->replace($what, ''); 
  } 
} 
class ArrayHandler { 
  public function sort($flags = SORT_REGULAR) { 
    sort($this, $flags); return $this; 
  } 
  public function count() { 
    return count($this); 
  } 
}


3. Прив'яжемо методи для рядків і масивів до відповідних класів:

register_primitive_type_handler('string', 'StringHandler');
register_primitive_type_handler('array', 'ArrayHandler');


Після цього у строкових змінних з'явилися методи replace, split, remove і так далі, у масивів — метод count (). Природно, таких корисних методів можна додати скільки завгодно. Зверніть увагу, що всі вони — публічні, а в якості оброблюваного рядка (масиву, числа) виступає $ this. Подібним чином обробники можна привласнити будь-якого скалярному типу.
Також слід зазначити, що конструкції виду:

"foobar"->trim();


викликають Parse error, тобто методи можна викликати поки тільки у змінних.
Також в репозиторії є приклад реалізації зручного API «запитів до рядків»:

// Містить рядок будь-яку із зазначених підрядків?
$str->contains(str\anyOf(['foo', 'bar', 'hello', 'world'])); // не закінчується чи рядок будь-яким з цих значень? 
$str->endsWith(str\noneOf(['.c', '.ho', '.lo']));


Дуже наочно і набагато простіше для запам'ятовування, на відміну від strspn, strcspn, strpbrk.

Хочеться вірити, що розробники PHP включать подібний функціонал в наступні версії. Трішки такого синтаксичного цукру зробить розробку набагато приємніше, а розробників — щасливішими.

Посилання на проект: https://github.com/nikic/scalar_objects/

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.