Оба инструмента для
Gate —
// Определяем в AuthServiceProvider
Gate::define('access-admin-panel', function (User $user) {
return $user->is_admin;
});
// Проверяем
if (Gate::allows('access-admin-panel')) { ... }
// или в контроллере
$this->authorize('access-admin-panel');
Policy —
// php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id || $user->is_admin;
}
}
// Использование
$this->authorize('update', $post);
Правило выбора
— Нет модели →
— Есть модель, несколько действий →
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3🔥2
Один доступ вместо вечного выбора между «нужно для работы» и «давно хотелось изучить» 👇
Forwarded from Proglib.academy | IT-курсы
Сегодня хочется разобраться в AI-агентах. Через пару недель появляется задача, где нужны алгоритмы. Потом понимаешь, что неплохо бы освежить Python или математику для Data Science.
В подписку Proglib Academy входят все основные направления — AI, ML, Python, алгоритмы, математика для DS и другие курсы, а ещё закрытый видеохаб с вебинарами практиков.
Начать можно с пробного месяца. Если решите остаться, его стоимость зачтётся при оформлении подписки
Please open Telegram to view this post
VIEW IN TELEGRAM
Какова разница между «cookie» и «session»?
В PHP «cookie» и «session» — это механизмы управления состоянием в веб-приложениях, но они служат немного разным целям:
Cookie:
Куки — это небольшие фрагменты данных, которые отправляются с веб-сервера на веб-браузер пользователя и хранятся локально на компьютере пользователя.
Куки обычно используются для хранения информации, специфичной для пользователя, такой как учетные данные для входа, предпочтения или элементы корзины покупок.
Они часто используются для отслеживания поведения пользователя и персонализации пользовательского опыта.
У куки может быть время истечения, после которого они автоматически удаляются из браузера пользователя.
Session:
Сессия — это способ хранения информации о пользователе на протяжении нескольких страниц или запросов в рамках одного посещения веб-сайта.
В отличие от куки, которые хранятся на компьютере пользователя, данные сессии хранятся на сервере.
Сессии обычно используются для поддержания аутентификации пользователя и для хранения временной информации, связанной с взаимодействием пользователя с веб-сайтом.
Сессии часто реализуются с помощью уникального идентификатора, называемого идентификатором сессии, который передается между сервером и клиентом для ассоциирования последующих запросов с той же сессией.
Cookie:
Куки — это небольшие фрагменты данных, которые отправляются с веб-сервера на веб-браузер пользователя и хранятся локально на компьютере пользователя.
Куки обычно используются для хранения информации, специфичной для пользователя, такой как учетные данные для входа, предпочтения или элементы корзины покупок.
Они часто используются для отслеживания поведения пользователя и персонализации пользовательского опыта.
У куки может быть время истечения, после которого они автоматически удаляются из браузера пользователя.
Session:
Сессия — это способ хранения информации о пользователе на протяжении нескольких страниц или запросов в рамках одного посещения веб-сайта.
В отличие от куки, которые хранятся на компьютере пользователя, данные сессии хранятся на сервере.
Сессии обычно используются для поддержания аутентификации пользователя и для хранения временной информации, связанной с взаимодействием пользователя с веб-сайтом.
Сессии часто реализуются с помощью уникального идентификатора, называемого идентификатором сессии, который передается между сервером и клиентом для ассоциирования последующих запросов с той же сессией.
🌚3🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Разберём на вебинаре, как тратить меньше на AI-агентов — без потери качества кода.
— когда дорогая модель действительно нужна, а когда хватит дешёвой;
— сколько стоит один прогон и куда уходят токены;
— какие задачи можно отдавать субагентам;
— как настроить маршрутизацию моделей;
— что проверять в AI-коде перед merge.
Please open Telegram to view this post
VIEW IN TELEGRAM
Простыми словами: вместо одной толстой иерархии наследования вы разбиваете её на две независимые — «что делать» и «как делать» — и связываете их композицией.
▪️ Когда использовать
— Есть две ортогональные оси изменения (тип × реализация)
— Хотите избежать «взрыва» подклассов
— Нужно переключать реализацию в runtime
▪️ Bridge vs Strategy
— Strategy: меняет один алгоритм внутри объекта
— Bridge: разделяет целые иерархии абстракции и реализации
▪️ Минус
Усложняет код, если оси изменения всего одна — тогда достаточно обычного полиморфизма.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Почему modify не изменил DateTimeImmutable?
Объект хранит
Ответ:
2026-10-15. Метод возвращает новый объект, исходный DateTimeImmutable не меняется. Если сохранить результат вызова, новый объект будет содержать 2026-10-16. Это отличается от изменяемого DateTime: одинаковое название метода не означает одинаковую семантику изменения. Передача исходного объекта в другую функцию сама по себе не заменит ссылку на новый результат.
Контракт DateTimeImmutable
Объект хранит
2026-10-15 в UTC. Вызвали modify('+1 day'), но возвращённое значение не сохранили. Какая дата останется в исходном объекте?Ответ:
Контракт DateTimeImmutable
❤3
Forwarded from Библиотека программиста
Разбираете урок, слушаете интервью фоном или начинаете на телефоне, а продолжаете на большом экране?
Хотим узнать, что делает просмотр удобным для вас. Вспомните последнее видео — ролик, урок, фильм или серию сериала — и расскажите о своём опыте. Если детали не запомнились, можно так и ответить.
В результатах сможете сравнить свои привычки с ответами других участников. А разработчики и инженеры видеоплатформы расскажут, что происходит по ту сторону экрана, пока вы смотрите видео.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
SensitiveParameter скрывает пароль во всех логах?
Параметр функции помечен атрибутом SensitiveParameter. Внутри функция записала его значение в прикладной лог, затем выбросила исключение. Что атрибут скроет?
Ответ:
Значение аргумента в stack trace, но не самостоятельную запись в прикладной лог. В трассировке оно представлено SensitiveParameterValue. В проверенном примере значение demo-secret осталось в файле лога. Атрибут появился в PHP 8.2, он не шифрует переменную и не очищает все места, куда код её передал. Если выводите аргументы исключения, отдельно проверяйте настройку zend.exception_ignore_args.
Назначение SensitiveParameter
Параметр функции помечен атрибутом SensitiveParameter. Внутри функция записала его значение в прикладной лог, затем выбросила исключение. Что атрибут скроет?
Ответ:
Назначение SensitiveParameter
Допустим, функция sum(int $value) объявлена в файле с declare(strict_types=1). Если вызвать sum('42') из другого файла без строгого режима, числовая строка может быть преобразована в int. Одного strict_types рядом с объявлением недостаточно, чтобы сделать все внешние вызовы строгими.
Если же strict_types включён в вызывающем файле, такая строка приведёт к TypeError. При этом int разрешено передавать в параметр float даже в строгом режиме.
Для возвращаемого значения правило другое: режим определяется файлом, где объявлена функция.
Строгая типизация не заменяет проверку входных данных и не меняет правила операторов сравнения. Здесь речь именно о проверке объявленных скалярных типов.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Type declarations - Manual
👍2
До 31 октября в Proglib Academy можно выбрать два курса и заплатить только за один.
Например, можно совместить:
💥 ИИ для разработчиков — применение нейросетей в повседневной разработке: работа с кодом, тестирование и ревью.💥 Разработка ИИ-агентов — архитектура агентов и создание собственных AI-решений.
Вместе курсы стоят 108 000 ₽, но по акции оба обойдутся в 59 000 ₽. Экономия — 49 000 ₽
Интересуют Python и ИИ или алгоритмы и архитектура? Можно выбрать любые два курса из каталога.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱1👾1
Одна из причин ограничения — возможность вызова зависит от контекста доступа. Например, массив с объектом и именем его private-метода может быть вызываемым внутри класса, но недоступным для вызова снаружи.
Поэтому недостаточно однажды проверить значение при записи в свойство и считать, что оно будет вызываемым в любом месте программы.
Для хранения обработчика можно использовать свойство типа Closure. Переданный callable при необходимости преобразуют через Closure::fromCallable(). Полученное замыкание сохраняет возможность вызова с учётом контекста, в котором оно было создано.
С PHP 8.1 доступен и синтаксис создания вызываемого объекта первого класса, например $object->method(...). Правила видимости при его создании всё равно действуют.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Properties - Manual
В PHP 7 и новее Exception и Error образуют две отдельные ветки, которые реализуют общий интерфейс Throwable. Поэтому catch (Exception $e) перехватит исключения из ветки Exception, но пропустит TypeError.
Если обработчику действительно нужно принимать обе категории, используют catch (Throwable $e). Если требуется обработать только ошибку типов, можно явно указать catch (TypeError $e).
Например, строгая проверка аргумента обнаружила несовместимый тип. Обработчик Exception не сработает, а обработчик TypeError или Throwable — сработает.
При этом Throwable не превращает любой сбой процесса в перехватываемое исключение. И перехват ошибки типов не означает, что её стоит скрыть: часто она указывает на дефект программы, который нужно исправить.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Throwable - Manual
❤3
Представьте, что функция содержит проверку файла, затем yield. Вы обернули только получение генератора в try, а foreach разместили после catch. Если проверка файла выбросит исключение при начале обхода, этот catch его уже не перехватит.
Даже код, записанный до первого yield, относится к отложенному выполнению тела генератора. Чтобы обработать его исключения, нужно охватить try и ту часть программы, которая запускает или продолжает обход.
Но не все ошибки откладываются. Вычисление аргументов и проверка их типов происходят при вызове и могут завершиться ошибкой сразу.
Если проверку нужно выполнить именно в момент вызова, можно вынести её в обычную функцию-обёртку, которая после проверки вернёт генератор.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Generators overview - Manual
В Proglib Academy действует акция: покупаешь один курс, а второй получаешь в подарок.
Например, можно совместить два направления по работе с ИИ:
💥 ИИ для разработчиков — применение нейросетей в повседневной разработке: работа с кодом, тестирование и ревью.💥 Разработка ИИ-агентов — архитектура агентов и создание собственных AI-решений.
А если тебе интереснее Python, алгоритмы, backend или DevOps — выбирай другую пару курсов из каталога.
Акция действует до 31 октября включительно
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱1
Допустим, есть функция findUser(int $userId), а клиент вызывает findUser(userId: 42). Если переименовать параметр в $id, позиционный вызов findUser(42) продолжит работать. Но прежний именованный вызов завершится ошибкой Unknown named parameter $userId, если функция не принимает этот аргумент через вариативный параметр.
Порядок и тип параметра при этом могли вообще не измениться. Ломается именно обращение по старому имени.
Это касается и переопределения методов: язык может разрешать другие имена параметров в реализации, но именованный вызов будет зависеть от фактически выбранного метода.
Поэтому имена параметров публичного API стоит учитывать при оценке обратной совместимости, а не считать их исключительно внутренней деталью.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Function parameters and arguments - Manual
Для ключей 1 и '1' получится один и тот же ключ. Поэтому после присваиваний $data[1] = 'first' и $data['1'] = 'second' в массиве останется одна запись со значением 'second'.
Но не любая числовая строка ведёт себя так. Например, '01' останется строковым ключом из-за ведущего нуля, а '+1' — из-за знака плюс. Они могут существовать отдельно от целочисленного ключа 1.
Это важно, когда ключи приходят извне: идентификаторы, которые выглядят разными по типу, после добавления в массив могут совпасть.
Если нужно различать такие значения, можно явно кодировать ключи с префиксом, например 'int:1' и 'string:1'. Обычный PHP-массив сам по себе различие между ключами 1 и '1' не сохранит.
Please open Telegram to view this post
VIEW IN TELEGRAM
www.php.net
PHP: Arrays - Manual
🔥3🌚1
Переименовывает ли as метод трейта или добавляет второе имя?
Ответ: Добавляет второе имя. Исходный метод при этом остаётся доступным. Через as также можно изменить видимость метода, но сам по себе этот оператор не разрешает конфликт двух одноимённых методов из разных трейтов. Для выбора реализации используют insteadof, а для дополнительного имени — as. Эти операции можно сочетать, чтобы сохранить обе реализации под разными именами.
Документация: конфликты и псевдонимы методов трейтов
Основа вопроса: Hennadii Alforov о вопросах, которые он задаёт PHP-разработчикам.
➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии
🐸 Библиотека программиста
Основа вопроса: Hennadii Alforov о вопросах, которые он задаёт PHP-разработчикам.
Please open Telegram to view this post
VIEW IN TELEGRAM
Копируется ли строка на 100 МБ при передаче в функцию по значению?
Ответ: Обычно полная копия сразу не создаётся. PHP использует разделение данных с подсчётом ссылок и механизм copy-on-write. Пока функция только читает строку, несколько переменных могут использовать одни данные. Когда требуется изменить разделяемую строку, создаётся отдельная копия. Поэтому передача по значению не означает немедленного удвоения памяти. Но конкретный расход зависит от операций внутри функции и устройства строки.
Документация: управление памятью и copy-on-write
Источник вопроса: Hennadii Alforov, раздел PHP itself.
➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии
🐸 Библиотека программиста
Источник вопроса: Hennadii Alforov, раздел PHP itself.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Чем static-замыкание отличается от обычного при работе с $this?
Ответ: Обычное замыкание, созданное в контексте объекта, автоматически получает привязку к нему через $this. Пока замыкание живёт, эта привязка может удерживать объект в памяти. У static-замыкания автоматической привязки нет, и использовать $this внутри него нельзя. Это полезно, если функция не должна зависеть от экземпляра. Но захват объекта через use всё равно может создать сильную ссылку — слово static этому не мешает.
Документация: анонимные и статические анонимные функции
Основа вопроса: Вопросы Hennadii Alforov о замыканиях и внешнем контексте.
➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии
🐸 Библиотека программиста
Основа вопроса: Вопросы Hennadii Alforov о замыканиях и внешнем контексте.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Можно ли объявить private-метод в интерфейсе PHP?
Ответ: Нет. Методы интерфейса должны быть публичными. Интерфейс задаёт контракт, доступный вызывающему коду, а приватный метод является внутренней деталью реализации. Если нескольким классам нужна общая закрытая реализация, её можно разместить в подходящем трейте или базовом классе. Но объявить такой метод приватным членом интерфейса нельзя.
Документация: интерфейсы объектов
Источник вопроса: Hennadii Alforov, раздел PHP itself.
➡️ Навигация: База знаний • Задачи • Собеседования • Вакансии
🐸 Библиотека программиста
Источник вопроса: Hennadii Alforov, раздел PHP itself.
Please open Telegram to view this post
VIEW IN TELEGRAM