TGViewer
Channel Public Channel
PHP Academy

PHP Academy

@phpshka

@workakkk - с вопросами
Subscribers
9.25K
Photos
170
Videos
35
Links
321
Recent Posts 20 shown
Post #589 880
🐘 Что нового в PHP 8.6

Релиз запланирован на 19 ноября 2026 года, сейчас версия проходит бета-тестирование.

Из интересного:

* Частичное применение функций — можно заранее передать часть аргументов, оставив остальные на потом:


$makeSlug = str_replace(' ', '-', ?);
echo $makeSlug('Hello World'); // Hello-World


* `clamp()` — ограничивает значение заданным диапазоном. Например, clamp(150, min: 0, max: 100) вернёт 100.
* `Time\Duration` — класс для длительности с наносекундной точностью, арифметикой и сравнением.
* Значения по умолчанию для `readonly`-свойств — без возможности менять их после инициализации.
* Новый Polling API — единый интерфейс к механизмам вроде epoll и kqueue для циклов событий.
* Улучшенная обработка ошибок потоков — можно выбирать предупреждения, исключения или тихий режим.

Разбор с примерами — https://laravel-news.com/php-8-6

RFC частичного применения — https://wiki.php.net/rfc/partial_function_application_v2
Laravel News What's New in PHP 8.6 PHP 8.6 arrives November 19, 2026 with partial function application, a clamp() function, a Duration class, readonly property defaults, and new deprecations.
  • ❤ 6
  • 👍 3
  • 🔥 1
  • 🎉 1
Post #588 1.6K
💡Совет по Laravel

Знаешь ли ты, что можно выбрасывать исключения условно всего в одну строку с помощью throw_if() — идеально для лаконичного кода в контроллерах и сервисах.
  • 🤮 16
  • 👍 6
  • 🔥 1
  • 🤡 1
Post #587 1.39K
Приглашаем на курс для прокачки навыков архитектора и проектировщика, которые важны для профессионального роста программиста.

🌐 С курсом «Системный дизайн высоконагруженных проектов» вы:

▪️изучите ключевые фундаментальные паттерны и получите навыки проектирования проектов с миллионной аудиторией (балансировка, масштабирование апп/кешей/субд, высокая доступность и кластерные решения, шардинг, CAP/PACELS, консистентность, саги, транзакционные очереди и многое другое)
▪️поупражняетесь в проектировании и получите обратную связь на реальных задачах: магазин/маркетплейс, такси/доставка, обьявления, соцсети, дейтинг, игры, википедия, мессенжер, CDN, хранилище файлов, онлайн-кинотеатр, счетчики, удаленный мониторинг, интеграционные вебхуки, рассылки и тд.
▪️ научитесь планировать нагрузку и связывать
бизнес-показатели с нефункциональными требованиями к системе
▪️ попрактикуемся в проведении и прохождения секций системного дизайна на интервью.

Всё в формате живых онлайн-сессий (лекции, брейнштормы, презентации домашних проектов).

🤩 Кто мы: R&D-центр Devhands.ru. Основатель школы и автор курса Алексей Рыбак, ex-СТО Badoo, с 20-летним опытом высоконагруженных проектов и управления глобальными технологическими организациями.

🗓 Старт 7 сентября, изучаем программу, записываемся здесь

Реклама. ИП Рыбак А.А. ИНН 771407709607 Erid: 2VtzqvimBRf
  • 👍 2
Post #586 1.29K
Сегодня хочу рассказать вам про одну ошибку, которую я часто встречаю у начинающих PHP-разработчиков — неправильную работу с датами и временем.

Когда вы используете функции вроде date(), strtotime(), time() напрямую без явной установки временной зоны (timezone), ваш код может начать вести себя непредсказуемо. Особенно если ваш проект запущен на серверах в разных регионах.

Чтобы избежать проблем:
- Всегда задавайте временную зону явно через date_default_timezone_set('Your/Timezone'); в начале вашего приложения.
- Или лучше используйте объекты DateTime и DateTimeZone, они гораздо удобнее для работы с временными зонами и манипуляциями с датами.

Пример хорошего подхода:
$date = new DateTime('now', new DateTimeZone('Europe/Moscow'));
echo $date->format('Y-m-d H:i:s');
И еще одна рекомендация — всегда храните даты в базе данных в формате UTC, а уже при выводе преобразовывайте их в нужную временную зону для пользователя.

Небольшая дисциплина в работе с временем сэкономит вам кучу нервов в будущем. Проверено на реальных проектах!
  • 👍 14
  • ❤ 2
  • 👎 1
Post #585 1.19K
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку

Окружение решает больше, чем кажется.

Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.

AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: https://t.me/+90Z5TAyfuNU5YmRi
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/javatg
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: https://t.me/+S4hinvO3QI43ZjNi
Kubernetes: t.me/kubernetc
GameDev: https://t.me/gamedev
Haskell: t.me/haskell_tg

Собеседования и карьера:

DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview

Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.me/addlist/mzMMG3RPZhY2M2Iy

Полезное сверху:

ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: https://t.me/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: https://t.me/addlist/BkskQciUW_FhNjEy

Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg

Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.
Post #584 1.49K
Сегодня я покажу вам, как удобно логировать в Laravel, не засоряя код и не превращая проект в болото из Log::info() на каждом шагу.

💡 Используем каналы логирования правильно

Laravel предоставляет мощную систему логирования на базе Monolog. Но часто мы ограничиваемся дефолтным логом. А зря.

Например, создаём отдельный канал для логов оплаты:


// config/logging.php
'channels' => [
'payment' => [
'driver' => 'single',
'path' => storage_path('logs/payment.log'),
'level' => 'info',
],
],


Теперь в нужном месте можно писать:


Log::channel('payment')->info('Платёж прошёл', ['user_id' => $user->id, 'amount' => $amount]);


И всё — никакой путаницы. В laravel.log остаётся только то, что важно для всего проекта, а логи оплаты — отдельно. Можно и в телеграм скидывать, если настроить webhook.

👀 Бонус: helper-функция

Чтобы писать меньше:


if (!function_exists('payment_log')) {
function payment_log($message, array $context = []) {
\Log::channel('payment')->info($message, $context);
}
}


Теперь вызываем везде просто payment_log('Платёж принят').

Пишите в комментах, какие каналы логирования вы используете и куда пишете — в файл, телегу или Sentry?
  • 👍 8
  • 😁 4
  • 🔥 2
Post #583 1.86K
Сегодня я покажу вам простой, но мощный способ, как ускорить отладку в Laravel при работе с большим количеством логики в контроллерах и сервисах.

🔍 Ловим баги быстрее с помощью ray() от Spatie

Обычно мы используем dd() или dump() в Laravel, чтобы посмотреть, что творится с переменными. Но как только проект становится крупнее — эти методы начинают мешать, особенно когда нужно отслеживать несколько значений в разных местах.

Спасает Ray — инструмент от Spatie, который интегрируется с Laravel и выводит отладочную информацию в отдельное десктопное приложение.

Пример:


ray($user);
ray($order)->blue();
ray()->showQueries();


Ты можешь:
- выводить переменные без прерывания скрипта;
- смотреть SQL-запросы в реальном времени;
- использовать цветовые метки, чтобы различать вывод из разных участков кода.

⚙️ Установка


composer require spatie/laravel-ray --dev


И по желанию установить десктоп-приложение с сайта Spatie.

В config/ray.php можно кастомизировать поведение: включать Ray только на dev-среде, логировать только определённые запросы и т.д.

🧠 Совет от себя

Ray особенно хорошо заходит, когда работаешь в команде — ты можешь добавить временный ray()-лог, не ломая исполнение и не мешая другим.
Post #582 1.66K
Есть возможность поработать на Кипре в одной из самых крупных фантех компаний с говорящим названием — Stripchat 😏

Нанимают senior-инженеров в направлениях: Backend, Frontend и QA.

Как вы понимаете, продукт востребованный, с миллионами активных пользователей.

Задачи: проектирование сервисов, масштабирование платформы, решение ежедневных хайлоад-задач. 200k+ RPS, распределённые системы, event-driven архитектура (PHP, Go).

Обещают полную релокацию на Кипр, EU-контракт, жилье на первое время.

Узнать детали и откликнуться можно тут
stripchat-offer.work Build the platform behind a Top-50 global website Build products for millions, solve complex engineering challenges, and grow with a team that ships fast.
  • 👍 2
Post #581 1.55K
Сегодня покажу вам простой, но очень удобный приём, который помогает наводить порядок в больших PHP-проектах — использование кастомных коллекций вместо массивов.

Если вы когда-нибудь передавали в методы или возвращали из них массивы с объектами, то наверняка сталкивались с ситуацией, когда непонятно, что в массиве лежит. А потом кто-нибудь передал туда строку или null — и привет, баги.

Я стал использовать свои классы коллекций. Простой пример:


class UserCollection
{
/** @var User[] */
private array $users = [];

public function __construct(array $users = [])
{
foreach ($users as $user) {
$this->add($user);
}
}

public function add(User $user): void
{
$this->users[] = $user;
}

public function all(): array
{
return $this->users;
}

public function filterByActive(): self
{
return new self(array_filter($this->users, fn(User $u) => $u->isActive()));
}

// и так далее
}


Теперь везде, где раньше был User[], я работаю с UserCollection. Это сразу даёт:

- типизацию (и защиту от мусора),
- автодополнение в IDE,
- методы прямо в коллекции (например, filterByActive, sortByName, first() и т.д.),
- чище и понятнее сигнатуры методов.

Это похоже на коллекции из Laravel, но я использую это везде, даже в маленьких проектах без фреймворков. Такие объекты делают код чище, устойчивее и легче читаемым.

Попробуйте в одном из ваших проектов заменить массивы объектов на такие коллекции — и вы удивитесь, как стало лучше.
  • 👍 14
  • ❤ 3
Post #580 1.85K
Сегодня покажу вам простую, но мощную технику, которая может прокачать ваш PHP-код — Value Object вместо простых типов.

Мы часто передаём параметры как string, int, array. Всё просто и понятно. Но как только бизнес-логика усложняется — типы начинают нас подводить.

Допустим, у вас есть метод:


function sendSms(string $phoneNumber, string $message): void


А теперь скажите честно — сколько раз вы ловили себя на том, что phoneNumber передаётся в неправильном формате? Или вовсе пустым? Или из другой страны, а вы это не предусмотрели?

Вот тут и приходят на помощь Value Object'ы:


final class PhoneNumber
{
public function __construct(private string $number)
{
if (!preg_match('/^\+7\d{10}$/', $number)) {
throw new InvalidArgumentException('Invalid phone number');
}
}

public function value(): string
{
return $this->number;
}
}


Теперь ваш метод будет выглядеть так:


function sendSms(PhoneNumber $phoneNumber, Message $message): void


Что мы получаем:
- Валидность данных гарантируется на этапе создания объекта.
- Код становится самодокументируемым — не нужно читать описание, чтобы понять, что именно сюда передаётся.
- IDE и статическая проверка типа не дадут случайно передать email вместо phone.

Да, это чуть больше кода. Но это тот случай, когда "больше" — значит надёжнее.
  • 👍 17
  • 🔥 1
Post #579 1.35K
🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку

В IT прокачивается тот, кто каждый день видит сильные идеи, новые инструменты, реальные задачи, вакансии и разборы.

Окружение решает больше, чем кажется.

Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.

AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: t.me/DevopsDocker
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/java_library
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: https://t.me/gamedev
Haskell: t.me/haskell_tg

Собеседования и карьера:

DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview

Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: https://t.me/addlist/2Ls-snqEeytkMDgy
Папка Frontend: https://t.me/addlist/mzMMG3RPZhY2M2Iy

Полезное сверху:

ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: @courses
ИТ-книги бесплатно: https://t.me/addlist/BkskQciUW_FhNjEy

Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg

Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.

Пока кто-то листает шум, ты будешь видеть инструменты, задачи и идеи, которые помогают расти в профессии.
  • 🤮 3
  • ❤ 1
  • 👍 1
  • 🔥 1
Post #578 1.92K
🔥 Как избежать проблем с isset() и empty() в PHP?

Сегодня разберём две часто используемые функции в PHP — isset() и empty(), которые могут вести себя не так, как вы ожидаете.

📌 isset()
Функция isset($var) проверяет, была ли переменная установлена и не равна ли она null.
❗ Пример подвоха:

$var = null;
var_dump(isset($var)); // false

Если переменной вообще нет в коде — тоже будет false.

📌 empty()
Функция empty($var) проверяет, считается ли переменная "пустой".
❗ Пустыми считаются:
- "" (пустая строка)
- 0 (число)
- "0" (строка с нулём)
- null
- false
- [] (пустой массив)

Пример:

$var = "0";
var_dump(empty($var)); // true, хотя строка не null

⚠️ Ошибка: проверка if (!isset($var) || empty($var)) может привести к неожиданному результату.

🔥 Лучший подход?
Используйте строгие проверки:

if ($var === null) { /* Переменная null */ }
if ($var === '') { /* Пустая строка */ }
if ($var === 0) { /* Число 0 */ }

Если проверяете массивы, то:

if (count($var) === 0) { /* Массив пуст */ }


Вывод: не злоупотребляйте isset() и empty(), а проверяйте переменные строго!
  • ❤ 6
  • 👍 6
  • 👎 4
  • 🔥 1
  • 🥰 1
Post #576 2.4K
⚙️ Phiki

Phiki помогает подсветить синтаксис. Написан на PHP. Он использует файлы грамматики TextMate и темы Visual Studio Code для генерации кода с подсветкой синтаксиса для веба.

Название и публичный API Phiki во многом вдохновлены Shiki — пакетом, который делает примерно то же самое в экосистеме JavaScript. Реализация пакета также во многом вдохновлена vscode-textmate — мощным пакетом, лежащим в основе Visual Studio Code, Shiki и других инструментов.

🔗 Github
  • ❤ 3
Post #574 2.63K
  • ❤ 7
  • 👍 2
  • 😁 2
  • 🤷‍♂ 1
Post #573 3.14K
Оптимизация скорости работы PHP кода 🏎️

Сегодня я покажу вам несколько простых, но эффективных способов ускорить выполнение PHP-скриптов. Оптимизация кода – важная часть работы разработчика, ведь никто не любит медленные сайты. 🚀

🔥 1. Избегайте лишних запросов к БД
Частая ошибка – несколько одинаковых запросов к базе данных в одном запросе. Используйте кэширование (Redis, Memcached), а если данные редко меняются – сохраняйте их в файл.

🔥 2. Используйте isset() вместо array_key_exists()
Функция isset() работает быстрее, чем array_key_exists(), потому что она не только проверяет наличие ключа, но и сразу его значение.


// Медленный вариант
if (array_key_exists('key', $array)) { }

// Быстрый вариант
if (isset($array['key'])) { }


🔥 3. Не злоупотребляйте foreach при больших объемах данных
Если у вас массив с десятками тысяч элементов, попробуйте array_map() или array_walk() – они работают быстрее за счет встроенной оптимизации в C.

🔥 4. Подключайте файлы правильно
Разница между require, include, require_once и include_once может сильно повлиять на производительность. require_once проверяет, был ли уже подключен файл, что замедляет выполнение. Если точно знаете, что файл не дублируется – используйте require.

🔥 5. Включите OPCache
OPCache кэширует байт-код PHP и ускоряет его выполнение в разы. Включите его в php.ini:


opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1


🔥 6. Используйте json_encode() вместо serialize()
Функция json_encode() работает быстрее, чем serialize(), и при этом генерирует более компактные данные.


$data = ['name' => 'John', 'age' => 25];

// Медленный вариант
$serialized = serialize($data);

// Быстрый вариант
$json = json_encode($data);


✅ Оптимизация PHP кода — это не магия, а грамотный подход к написанию скриптов. Используйте эти советы, и ваши проекты станут быстрее!
  • 👍 17
  • ❤ 11
  • 👎 4
  • 🔥 4
  • 🌚 1
Post #571 2.25K
Совет по Laravel 💡

Знаете ли вы, что... вы можете временно отключить timestamps при сохранении модели?
  • 👍 7
  • ❤ 2
Post #570 2.9K
✔️ Machine Learning Roadmap: нормальная карта входа в ML без сказок про «выучить нейросети за месяц»

Большой русскоязычный roadmap по машинному обучению: от первого import numpy до LLM, RAG, fine-tuning, AI-агентов и MLOps.

И это не просто очередной список ссылок в стиле «посмотри 40 курсов и станешь ML engineer». Внутри нормальная структура: что учить, в каком порядке, зачем это нужно и какой практический артефакт должен появиться после каждого этапа.

Roadmap разбит на 7 треков:

- фундамент: Python, математика, статистика, инструменты
- классический ML: scikit-learn, табличные данные, метрики, валидация
- Deep Learning: PyTorch, CNN, RNN, training loop
- LLM и трансформеры: attention, KV-cache, RAG, LoRA, агенты
- Generative AI: изображения, видео, аудио, мультимодальность
- MLOps и прод: Docker, Kubernetes, CI/CD, мониторинг, serving
- специализация: CV, NLP, RecSys, RL, Safety

Самое полезное - там честно написано, что ML это не только «обучить модель». В реальности большая часть работы живёт вокруг данных, метрик, деплоя, мониторинга, воспроизводимости и понимания, почему модель вообще ошибается.

Хорошая мысль из roadmap: LLM не делает джуна сениором. Она ускоряет того, кто понимает базу. Без базы человек просто превращается в оператора Copilot, который не может объяснить, почему модель сломалась.

По времени тоже без инфоцыганства:

- 0-3 месяца: кодинг, математика, классический ML
- 3-6 месяцев: Deep Learning и PyTorch
- 6-12 месяцев: LLM, RAG, fine-tuning, AI-агенты
- 12+ месяцев: MLOps, прод, масштабирование, специализация

Короче, если давно хотели системно зайти в ML, а не прыгать между роликами про ChatGPT, Stable Diffusion и «топ-10 библиотек», это хороший ориентир.

https://github.com/justxor/MachineLearningRoadmap/tree/main
  • 👍 5
  • ❤ 4
  • 🔥 2
  • 🥰 1
Post #569 2.62K
Один человек написал код, который сегодня работает на 20+ млрд устройств

Даниэль Стенберг начал cURL в 1996 году как маленькую утилиту для скачивания файлов из интернета.

Без большой команды. Без венчурных денег. Без хайпа. Просто писал open-source инструмент в свободное время.

Почти 30 лет спустя cURL стал тихим фундаментом интернета.

Он есть в iPhone, Android, PlayStation, Tesla, серверах, приложениях, сайтах и куче устройств, о которых мы даже не думаем. Его используют Spotify, YouTube, Netflix, Instagram и тысячи других сервисов.

NASA даже использовала cURL на марсианском вертолёте Ingenuity.

То есть код Стенберга буквально летал на другой планете.

Самое безумное - первые 23 года он не зарабатывал на cURL ничего. Триллионные компании строили продукты на его коде, а он продолжал бесплатно поддерживать проект и отвечать на баг-репорты.

В 2017 году король Швеции вручил ему премию Полхема - впервые в истории эту награду получил open-source проект.

В 2019 году Стенберг наконец начал работать над cURL фултайм в wolfSSL. В 2025 году получил золотую медаль IVA от Королевской шведской академии инженерных наук.

Но по сути ничего не изменилось: он всё ещё пишет код из домашнего офиса в Стокгольме и сам отвечает на GitHub issues.

Почти 30 лет человек делал инструмент, который работает в фоне и держит огромную часть интернета.

Без громких презентаций.

Без миллиардных раундов.

Просто хороший код, который пережил почти всё.
  • 🔥 47
  • 👍 13
  • ❤ 8
  • 👏 3
  • 😐 1
Post #568 2.38K
  • 😁 29
  • 👍 7
  • 🔥 5
  • ❤ 3
  • 🤣 2
  • 😱 1
Post #567 2.87K
Совет по PHP/Laravel 💡

Вместо того чтобы выполнять цикл `foreach` по массиву для поиска значения записи, вы можете использовать метод Laravel Collection `contains()`.
  • ❤ 10
  • 👍 10
  • 🔥 1
  • 💩 1
Older posts →

About this channel

How can I read @phpshka without a Telegram account?
TGViewer shows the public web preview Telegram publishes for PHP Academy: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does PHP Academy have?
PHP Academy (@phpshka) has 9.25K subscribers on Telegram, refreshed roughly every 30 minutes.
Does PHP Academy know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →