Этот канал был создан и назван в честь двух моих главных хобби, а что может быть круче их симбиоза? ;)
К сожалению этот канал никак не относится к https://github.com/beerphp. Во время создания канала я просто проверил имя в телеге, но не серчил в гугле. В любом случае я готов поддержать движуху организаторов и даже помогать им с рекламой сходок, если таковые будут (корона всё таки еще не прошла).
Здесь будет не только полезный, но и развлекательный, холиварный, может быть вообще не по теме контент. Всё будет зависеть от того, сколько пива у автора внутри на данный момент =)
Welcome, запасайтесь пенным и погнали кодить
К сожалению этот канал никак не относится к https://github.com/beerphp. Во время создания канала я просто проверил имя в телеге, но не серчил в гугле. В любом случае я готов поддержать движуху организаторов и даже помогать им с рекламой сходок, если таковые будут (корона всё таки еще не прошла).
Здесь будет не только полезный, но и развлекательный, холиварный, может быть вообще не по теме контент. Всё будет зависеть от того, сколько пива у автора внутри на данный момент =)
Welcome, запасайтесь пенным и погнали кодить
GitHub
BeerPHP
visit the "meta" repo for info. BeerPHP has 15 repositories available. Follow their code on GitHub.
🗿1
Небольшая, но поучительная статья о том, что сначала стоит думать, а потом делать. Тема конечно не пыховская, а скорее касается веб оптимизации, но вполне возможно пригодится.
Medium
Как не сделать хуже своими “улучшениями”?
Сегодня стал свидетелем одного интересного кейса, которым и решил поделиться. Есть несколько региональных сайтов: test.ua, test.ru…
🔥1🗿1
Вдогонку еще одна полезная опция, о которой почему-то ничего не написано в документации.
❗️В одном из своих докладов, Себастиан Бергман признался, что создал эту команду только потому, что он ленивый и данные настройки сконфигурированы сугубо под его предпочтения. Именно поэтому, в случае генерации файла через команду, рекомендую вам обратить внимание на такие настройки:
✔️ forceCoversAnnotation — Покрытие кода будет записываться только для тестов, в которых используется аннотация
✔️ beStrictAboutCoversAnnotation — Тест с аннотацией
❕ Если по-русски, то эта функция пометит код, как рискованный, если в рамках своего теста вы будете проверять код, который не относится к указанному коду в аннотации
✔️ beStrictAboutOutputDuringTests — Тест, который производит вывод, например, через вызов функции
✔️ beStrictAboutTodoAnnotatedTests — Пометит тест, как рискованный, если в аннотации метода будет содержаться
Странно, что об этой опции подробно не написано в документации.
./vendor/bin/phpunit --generate-configuration
После запуска достаточно в интерактивном режиме указать путь к файлу автозагрузчика, директорию тестов и директорию приложения, команда сформирует вам тот самый phpunit.xml и заботливо положит в корень проекта.❗️В одном из своих докладов, Себастиан Бергман признался, что создал эту команду только потому, что он ленивый и данные настройки сконфигурированы сугубо под его предпочтения. Именно поэтому, в случае генерации файла через команду, рекомендую вам обратить внимание на такие настройки:
beStrictAboutCoversAnnotation="true"которые, вероятно, могут расходиться с вашими предпочтениями.
beStrictAboutOutputDuringTests="true"
beStrictAboutTodoAnnotatedTests="true"
✔️ forceCoversAnnotation — Покрытие кода будет записываться только для тестов, в которых используется аннотация
@covers, задокументированная в @covers.✔️ beStrictAboutCoversAnnotation — Тест с аннотацией
@covers, проверяющий код, который не указан при помощи @covers или @uses, будет отмечен как рискованный, если эта проверка включена. ❕ Если по-русски, то эта функция пометит код, как рискованный, если в рамках своего теста вы будете проверять код, который не относится к указанному коду в аннотации
@covers. Хз стало ли понятнее :)✔️ beStrictAboutOutputDuringTests — Тест, который производит вывод, например, через вызов функции
print либо в тестовом коде, либо в тестируемом, будет отмечен как рискованный, если эта проверка включена.✔️ beStrictAboutTodoAnnotatedTests — Пометит тест, как рискованный, если в аннотации метода будет содержаться
@todo.Странно, что об этой опции подробно не написано в документации.
👍1
#Linux #Lifehack
Вот так жил и не знал, что существует
1. Выбрать предыдущую команду
2. Перевести курсора в начало строки
3. Ручками писать
Достаточно просто ввести
Вот так жил и не знал, что существует
sudo !!
В случае, если у вас нет прав на операцию, вместо того чтобы: 1. Выбрать предыдущую команду
2. Перевести курсора в начало строки
3. Ручками писать
sudo Достаточно просто ввести
sudo !! и терминал выполнит предыдущую команду, самостоятельно сделав все эти операции за вас.#PHP #BestPractices
Вместе с вызовами функций
Работает начиная с PHP 7.3.
Вместе с вызовами функций
json_encode и json_decode используйте флаг JSON_THROW_ON_ERROR, вместо json_last_error(), который выкинет исключение типа JsonException.Работает начиная с PHP 7.3.
#PHP #advice
Обратите внимание на оператор сравнения "космический корабль" (spaceship)
Обратите внимание на оператор сравнения "космический корабль" (spaceship)
<=>
echo 1 <=> 1; // 0В отдельных случаях может упростить код и его читаемость.
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
function($first, $second) {
return $first <=> $second;
};
Вместоfunction($first, $second) {
if ($first === $second) {
return 0;
}
return ($first < $second) ? -1 : 1;
};👍1
#PHP #advice
Вы можете использовать
Это также может вам помочь, если данные для провайдера вы берете из файла.
Вы можете использовать
yield в PHPUnit dataProviders. Это может немного повысить их читабельность.Это также может вам помочь, если данные для провайдера вы берете из файла.
🔥1
#PHP #advice
Говорить, что объекты в PHP передаются по ссылке не совсем правильно.
В действительности, если объект передать в функцию и там изменить его состояние, то во внешней области видимости мы действительно получим измененный объект. Но если (без &) попытаться его обнулить (= null), то он не удалится и не изменится во внешней области видимости.
Всё дело в том, что при передаче объекта, как аргумента функции, он не является ссылкой(!). Объект внутри содержит копию идентификатора, который указывает на один и тот же объект.
В то же время, если указать амперсанд (&), то при изменении переменной внутри (присвоив тот же null), изменится переменная и снаружи.
Подробную инфу, с примерами, можно прочесть в документации.
Говорить, что объекты в PHP передаются по ссылке не совсем правильно.
В действительности, если объект передать в функцию и там изменить его состояние, то во внешней области видимости мы действительно получим измененный объект. Но если (без &) попытаться его обнулить (= null), то он не удалится и не изменится во внешней области видимости.
Всё дело в том, что при передаче объекта, как аргумента функции, он не является ссылкой(!). Объект внутри содержит копию идентификатора, который указывает на один и тот же объект.
В то же время, если указать амперсанд (&), то при изменении переменной внутри (присвоив тот же null), изменится переменная и снаружи.
Подробную инфу, с примерами, можно прочесть в документации.
🔥1
В сознании PHPшников почему-то никак не может умереть md5.
Да, было много статей на тему «Все пароли нужно хранить, предварительно захэшировав их в MD5», но примерно в 2016 году это утверждение потеряло свою актуальность. Использование его для токенов и паролей, да еще и без "соли", это преступление.
Что же делать?
Для этого давно придумали две достаточно удобных функции password_hash() и password_verify(). Да, больше не надо самостоятельно писать функции для создания хешей, добавления соли, и проверки всего этого дела.
Также, для генерирования случайного токена можно использовать конструкцию
bin2hex() — Преобразует бинарные данные в шестнадцатеричное представление.
То есть выражение выше сгенерирует вам случайную строку длинной 32 символа.
Конечно, есть огромная куча сторонних библиотек, позволяющих решить подобные задачи. Но если вы не хотите париться, при этом хоть как-то заботитесь о безопасности приложения, то используйте готовые функции из коробки.
Ставь 🍺, если готов дать md5 умереть :)
Да, было много статей на тему «Все пароли нужно хранить, предварительно захэшировав их в MD5», но примерно в 2016 году это утверждение потеряло свою актуальность. Использование его для токенов и паролей, да еще и без "соли", это преступление.
Что же делать?
Для этого давно придумали две достаточно удобных функции password_hash() и password_verify(). Да, больше не надо самостоятельно писать функции для создания хешей, добавления соли, и проверки всего этого дела.
Также, для генерирования случайного токена можно использовать конструкцию
$token = bin2hex(random_bytes(16));radnom_bytes() — была добавлена в 7 версии PHP, умеет генерировать криптографически безопасные псевдослучайные байты.
bin2hex() — Преобразует бинарные данные в шестнадцатеричное представление.
То есть выражение выше сгенерирует вам случайную строку длинной 32 символа.
Конечно, есть огромная куча сторонних библиотек, позволяющих решить подобные задачи. Но если вы не хотите париться, при этом хоть как-то заботитесь о безопасности приложения, то используйте готовые функции из коробки.
Ставь 🍺, если готов дать md5 умереть :)
👍2
Маленький лайфхак о том, как получить кучу данных по API и не переживать о своём коде ;)
👉 Представим себе достаточно стандартную ситуацию, в которой вам нужно получить из внешнего API кучу однотипных сущностей. Например вам нужно получить из сервиса рассылок всех ваших подписчиков (это не реклама, а пример приближенный к реальности ;)).
Какое решение чаще всего приходит на ум? Что-то вроде этого.
❓ И вроде всё выглядит неплохо, но какие у этого кода минусы?
❌ Тут мы пытаемся получить все данные и сохранить их в один массив. К сожалению не можем угадать, сколько там в реальности может быть данных (например разница тестового и прода) и не знаем с какой скоростью их количество может увеличиваться. В свою очередь мы рискуем получить переполнение памяти, которое мы никак не контролируем. Да и код выглядит как-то не идеально.
👌 Но выход есть! Используем генераторы.
Генератор позволяет вам писать код, использующий foreach для перебора набора данных без необходимости создания массива в памяти, что может привести к превышению лимита памяти, либо потребует довольно много времени для его создания. И наш конечный код будет выглядеть примерно следующим образом.
Конструкция
Ставь 🍺 если было полезно или 🐒 если не используешь генераторы в коде.
#PHP #advice
👉 Представим себе достаточно стандартную ситуацию, в которой вам нужно получить из внешнего API кучу однотипных сущностей. Например вам нужно получить из сервиса рассылок всех ваших подписчиков (это не реклама, а пример приближенный к реальности ;)).
Какое решение чаще всего приходит на ум? Что-то вроде этого.
❓ И вроде всё выглядит неплохо, но какие у этого кода минусы?
❌ Тут мы пытаемся получить все данные и сохранить их в один массив. К сожалению не можем угадать, сколько там в реальности может быть данных (например разница тестового и прода) и не знаем с какой скоростью их количество может увеличиваться. В свою очередь мы рискуем получить переполнение памяти, которое мы никак не контролируем. Да и код выглядит как-то не идеально.
👌 Но выход есть! Используем генераторы.
Генератор позволяет вам писать код, использующий foreach для перебора набора данных без необходимости создания массива в памяти, что может привести к превышению лимита памяти, либо потребует довольно много времени для его создания. И наш конечный код будет выглядеть примерно следующим образом.
Конструкция
yield from позволяет вам развернуть полученный массив данных и вернуть каждый его элемент. Ставь 🍺 если было полезно или 🐒 если не используешь генераторы в коде.
#PHP #advice
👍1
#PHP #advice
Еще один вариант использования статического анализатора
Довольно распространенная ситуация, когда при рефакторинге, вам нужно поменять сигнатуру метода (например добавить или убрать один из параметров). После этого нужно найти все места, в которых этот метод вызывается и поправить вызов. На сегодняшний день IDE отлично справляется, но бывают моменты, когда вызовов очень много, название метода не уникально, при поиске результаты постоянно перемешиваются т.д.
Как же получить список мест, в котором нужно поправить измененный метод?
Если вы постоянно используете PHP Stan или Psalm, то после изменения существующей сигнатуры просто запустите свой статический анализатор и он с радостью вам предоставит этот список.
Безусловно, всё зависит от ситуации, но о таком варианте не стоит забывать ;)
Еще один вариант использования статического анализатора
Довольно распространенная ситуация, когда при рефакторинге, вам нужно поменять сигнатуру метода (например добавить или убрать один из параметров). После этого нужно найти все места, в которых этот метод вызывается и поправить вызов. На сегодняшний день IDE отлично справляется, но бывают моменты, когда вызовов очень много, название метода не уникально, при поиске результаты постоянно перемешиваются т.д.
Как же получить список мест, в котором нужно поправить измененный метод?
Если вы постоянно используете PHP Stan или Psalm, то после изменения существующей сигнатуры просто запустите свой статический анализатор и он с радостью вам предоставит этот список.
Безусловно, всё зависит от ситуации, но о таком варианте не стоит забывать ;)
👍1🗿1
Внедрение зависимостей (Dependency injection) и передача контекста (Context passing).
Для лучшего понимания и синхронизации предлагаю коротко рассмотреть эту тему. Не будем пока обсуждать плюсы и минусы, а просто проясним разницу между этими понятиями.
В качестве примера возьмём один из частых UseCase'ов - подтверждение почты пользователя.
Cценарий выглядит следующим образом:
1. Пользователь передает нам email.
2. Мы должны убедиться, что такой почты еще нет в нашей базе.
3. Генерируем токен для одноразовой ссылки.
4. Отправляем пользователю письмо на почту с ссылкой для подтверждения.
Чтобы сконструировать use case, нам понадобится repository (для проверки почты), генератор токенов и объект mailer для отправки письма. Завернём всё это в Dependency injection и теперь наш код выглядит следующим образом.
Что такое передача контекста (Context passing)?
Представьте, что все объекты в вашем приложении "вечные". Например,
Теперь рассмотрим приходящий
В идеале:
1. Отделяйте зависимости от контекста.
2. В метод передавайте только те значения контекста, которые использует данный метод.
#PHP #advice #middle #source
Для лучшего понимания и синхронизации предлагаю коротко рассмотреть эту тему. Не будем пока обсуждать плюсы и минусы, а просто проясним разницу между этими понятиями.
В качестве примера возьмём один из частых UseCase'ов - подтверждение почты пользователя.
Cценарий выглядит следующим образом:
1. Пользователь передает нам email.
2. Мы должны убедиться, что такой почты еще нет в нашей базе.
3. Генерируем токен для одноразовой ссылки.
4. Отправляем пользователю письмо на почту с ссылкой для подтверждения.
Чтобы сконструировать use case, нам понадобится repository (для проверки почты), генератор токенов и объект mailer для отправки письма. Завернём всё это в Dependency injection и теперь наш код выглядит следующим образом.
Что такое передача контекста (Context passing)?
Представьте, что все объекты в вашем приложении "вечные". Например,
mailer: мы можем отправить любое количество писем, вызывая метод send() и подставляя разные аргументы. Теперь рассмотрим приходящий
Request (откуда мы будем получать email). Его нельзя назвать "вечным" или "постоянным", он приходит и уходит, и всегда будет отдавать нам разные данные. Если нужен подобный объект, будь то Request, DTO (command), session и т.д., не вставляйте его в конструктор, а передайте его в качестве аргумента метода.В идеале:
1. Отделяйте зависимости от контекста.
2. В метод передавайте только те значения контекста, которые использует данный метод.
#PHP #advice #middle #source
🔥1