The Fly's PHP - Делаем из Мухи Слона – Telegram
The Fly's PHP - Делаем из Мухи Слона
424 subscribers
29 photos
1 video
64 links
Авторский блог Сергея Мухина

Чат: @fly_php_public

Сайт автора: https://sergeymukhin.com
Download Telegram
Ребята, приветствую всех!

Сегодня хочу рассказать об очередном интересном принятом RFC в PHP 8.4, который вводит две новых функций:

http_get_last_response_header(): ?array
http_clear_last_response_header(): void


которые можно использовать для получения и очистки HTTP-заголовков последнего ответа HTTP-обертки (wrapper), которые могут заменить историческую переменную $http_response_header.

Напоминаю, что когда вы зайдествуете слой stream'ов, в частности использование HTTP-wrappers (оберток) то всякий раз магически создается переменная $http_response_header в локальной области видмости. Одним из таких способов использования является получение содержимого по URL-адресу file_get_contents():

file_get_contents('https://sergeymukhin.com');

var_dump($http_response_header);

array (size=10)
0 => string 'HTTP/1.1 200 OK' (length=15)
1 => string 'Server: nginx' (length=13)
2 => string 'Date: Thu, 07 Mar 2024 07:34:18 GMT' (length=35)
3 => string 'Content-Type: text/html; charset=UTF-8' (length=38)
4 => string 'Connection: close' (length=17)
5 => string 'Vary: Accept-Encoding' (length=21)
6 => string 'Set-Cookie: PHPSESSID=uea9m7qcm0jgq4t2g3kfolm51h; path=/' (length=56)
7 => string 'Expires: Thu, 19 Nov 1981 08:52:00 GMT' (length=38)
8 => string 'Cache-Control: no-store, no-cache, must-revalidate' (length=50)
9 => string 'Pragma: no-cache' (length=16)


Переменная $http_response_header будет содержать все заголовки HTTP, которые были обнаружены во время запроса.
Мотивация введения новых функций обусловлена более предсказуемый и интуитивно понятный код:

file_get_contents('https://sergeymukhin.com/blog/cto-novogo-v-php-84');

//$headers = $http_response_header;

$headers = http_get_last_response_headers(); //запросили заголовки
http_clear_last_response_headers(); //почистили за собой


Кстати, переменная $http_response_header не модифицируется этими новыми функциями. Т.е.

Очистка $http_response_header не влияет на возвращение значений из http_get_last_response_headers() (она продолжает возвращать все, что было доступно), а вызов http_clear_last_response_headers() не сбрасывает значение в переменной $http_response_header.
👍102👌2
Всем доброй пятницы! И хороших выходных!

А пока расскажу про одно из самых значимых RFC в предстоящем PHP 8.4 - RFC1867 для методов HTTP, отличных от POST, которое вводит
новую функцию request_parse_body.

Как вы знаете PHP автоматически анализирует и разбирает HTTP-запросы POST для заполнения глобальных переменных $_POST и $_FILES. Однако другие HTTP-запросы с такими методами, как PUT или PATCH уже не анализируются автоматически, и работа с обработкой данных с данными типами запроса ложится на плечи разработчика/приложения.

Напомню RFC1867 определяет тип контента multipart/form-data. Этот тип контента используется в основном для отправки HTTP-форм, содержащих файлы. PHP изначально поддерживает анализ этого типа контента, но только для запросов POST. В частности, если запрос имеет метод POST и тип содержимого multipart/form-data, тело запроса немедленно используется перед запуском PHP-скрипта и заполняется в суперглобальные переменные $_POST и $_FILES. Эта функция запускается автоматически и не предоставляется непосредственно пользователю.

Учитывая популярность REST API, которые все чаще используют HTTP методы, отличные от POST - такие как PUT, DELETE и PATCH, где использование multipart/form-data полностью допустимо, но не обрабатывается PHP автоматически. Это требует ручного анализа тела запроса нетривиального формата. Обработка больших объемов данных в пользовательской среде также может быть не оптимальной с точки зрения производительности.

Например в Symfony эта часть отвечает за анализ и разбор таких данных, в том же Phalcon мне пришлось в свое время добавить эту возможность и так в любом мало-мальски используемом фреймворке.

Итак, в PHP 8.4 была добавлена ​​новая функция request_parse_body, которая предоставляет встроенную в PHP функциональность анализа запросов для других методов HTTP-запросов, отличных от POST:
function request_parse_body(?array $options = null): array {}


// Например, это запрос PUT
var_dump($_POST); // []
var_dump($_FILES); // []

[$_POST, $_FILES] = request_parse_body();

var_dump($_POST); // уже есть данные [...]
var_dump($_FILES); // уже есть данные [...]



При вызове функция request_parse_body считывает все содержимое, которое доступно в потоке php://input и создает значения, которые можно использовать в переменных $_POST и $_FILES.
Можно заполнить значения $_POST и $_FILES непосредственно из возвращаемых значений:
[$_POST, $_FILES] = request_parse_body();

Параметр $options можно использовать для передачи массива значений INI, связанных с анализом запроса. Эти значения не обязательно должны быть меньше, чем глобальная конфигурация. Это дает преимущество выборочной обработки меньших или больших значений, чем ограничения, установленные в файлах INI.
Например, чтобы проанализировать запрос с большим или меньшим пределом директивы post_max_size INI, можно вызвать функцию request_parse_body с нужным значением:
request_parse_body(['post_max_size' => 1024]);


И небольшое предупреждение: Функция request_parse_body имеет не идемпотентное поведение и предназначена для вызова только один раз за запрос, т.к. имеет разрушительное воздействие на php://input. При последующих вызовах функция вернет массив с пустыми данными, а поток php://input будет пуст после первого вызова request_parse_body().


Итак, на выходе мы имеем нативную функцию, которая позволит избавиться от некоторой логики в фреймворках или пользовательских приложений, будет иметь более высокую скорость обработки и безопасность.

Давайте дружно похлопаем и поблагодарим Илью Товило за столь замечательный функционал!

Чуть больше информации с табличками https://sergeymukhin.com/blog/php-84-novaia-funkciia-request-parse-body
👍9👏2🔥1
Ребята, всех с праздником!

Хотел успеть запостить статью к 4.04, но не смог сегодня, поэтому пока просто поздравление с профессиональным, успехов в работе и меньше багов!
🔥9🎉2
Ребята, привет!

Если в PHP взять обычный класс, являются ли его свойства свойствами по определению?) Кто подзабыл, напоминаю что такое свойство.

Я думаю вы уже догадались с какими новостями я к вам пришел сегодня, да-да, все верно RFC Хуки свойств (Property hooks) был принят и ожидается в PHP 8.4 (пока прям вот не 100%, но 99% это точно).
Итак, давайте, пробежимся по тому, что имеем и что нам Илья Товило и Ларри Гарфилд преподнесли:

Получение свойства класса или установка его значения является обычной задачей в объектно-ориентированном программировании. В PHP есть несколько способов сделать это.

Возьмем, к примеру, следующий класс.
class User
{
private string $name;
}

Как вы можете заметить, у нас в классе есть приватное свойство $name. Теперь мы можем определить геттеры и сеттеры для чтения и записи значения свойства соответственно, что до PHP 7.4 можно было считать идиоматическим:
class User
{
private string $name;

public function getName(): string
{
return $this->name;
}

public function setName(string $name): void
{
$this->name = $name;
}
}

$user = new User();
$user->setName('Sergey');

echo $user->getName(); // Sergey

Это обычный традиционный подход, и люди используют его уже давно. Начиная с PHP 8 мы можем сократить код еще больше, используя объявление свойства в конструкторе:
class User
{
public function __construct(public string $name) {}
}

$user = new User('Sergey');

echo $user->name; // Sergey

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

Мы также можем использовать магические методы _ _get и _ _set для достижения того же рез
В PHP 8.4 этот ключевой аспект будет улучшен за счет введения хуков свойств.

Хуки свойств (Propertry Hooks) - это новая функция PHP 8.4, которая позволит вам определять собственную логику для доступа к свойствам и их изменениям. Это может быть полезно для различных случаев использования, таких как мутация, ведение логов, проверка или кэширование.

По сути, Propertry Hooks позволяют вам определять дополнительное поведение свойств класса, используя в основном два хука: get и set. И это будет индивидуально для определенных свойств.

Приведенный ниже дизайн и синтаксис больше всего похож на Kotlin, хотя он также опирается на влияние C# и Swift. Python и JavaScript имеют схожие функции благодаря разному синтаксису, хотя этот синтаксис и непригоден для PHP. Ruby рассматривает свойства и методы почти одинаково, поэтому эта функциональность достигается как побочный эффект. Короче говоря, "средства доступа к свойствам" - очень распространенная функция в основных популярных языках программирования.

Что интересно, авторы просят не пугаться длинному тексту RFC, а предлагают отнестись к этому как глубоко проработанному материалу, отвечающему на все вопросы) Мы конечно пробежимся по самому главному, но если вы хотите узнать детали разработки, то можете почитать оригинальный RFC.

Вот как мы можем написать set для $name свойства в предыдущем примере:

class User
{
public string $name {
set (string $value) {
// валидация имени
if (mb_strlen(value) < 4)) {
throw new InvalidArgumentException(
'Invalid Name'
);
}

// Установка значения
$this->name = $value;
}
}
}

Как вы можете заметить, хуки заключаются в фигурные скобки, которые идут сразу после имени свойства. Затем мы можем определить хуки внутри этого блока кода.
👍10
Тело хука set - это тело метода произвольной сложности, принимающее один аргумент. Если указано, оно должно включать как тип, так и имя параметра. Здесь мы можем проверить или изменить значение свойства до его установки.

Таким образом, когда свойству присвоено значение $name, будет вызван хук set, и значение будет проверено перед его установкой.

$user = new User();
$user->name = 'Ser'; // Должно вывести исключение InvalidArgumentException

$user = new User();
$user->name = 'Sergey';

echo $user->name; // Sergey

Существует также сокращенный синтаксис для определения хука set с помощью оператора =>, похожий на замыкания:
class User
{
public string $name {
set => strtoupper($value);
}
}


Хук get позволяет вам определить собственную логику для доступа к свойствам. Это может быть полезно для свойств, которые необходимо изменить, прежде чем они будут возвращены пользователю.

Например, если в классе User есть два свойства $name и $lastName, мы можем определить get для свойства $fullName следующим образом:
class User
{
public function __construct(
public string $name, public string $lastName
) {}

public string $fullName {
get {
return $this->name . " " . $this->lastName;
}
}
}

$user = new User('Sergey', 'Mukhin');

echo $user->fullName; // Sergey Mukhin


Как вы можете заметить, хук get не принимает никаких аргументов. Он просто возвращает значение свойства. Как и обычный геттер.

Таким образом, при доступе к значению $fullName будет вызван хук get, и значение будет возвращено на основе логики, определенной в хуке.

Так же существует сокращенный синтаксис для хука get с помощью оператора =>

class User
{
public function __construct(
public string $name,
public string $lastName
) {}

public string $fullName {
get => string $this->name . " " . $this->lastName;
}
}


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

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

Можно только поблагодарить Илью Товило и Ларри Гарфилда, в очередной раз создавших столь прекрасный функционал!

https://sergeymukhin.com/blog/php-84-property-hooks
🔥12👏4👍2
Как отлично заметил Кирилл в комментариях к предыдущим постам, что:

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

Рассмотрим сначала за пример код указанный в RFC:
interface I
{
// Класс, реализующий интерфейс ДОЛЖЕН иметь публичное свойство,
// но независимо от того, является ли оно публичным или нет - ограничений нет.
public string $readable { get; }

// Класс реализации ДОЛЖЕН иметь публичное свойство для записи,
// но независимо от того, доступно ли оно публичному чтению или нет - ограничений нет.
public string $writeable { set; }

// Класс реализации ДОЛЖЕН иметь свойство, которое является публичным и
// доступно для чтения и записи.
public string $both { get; set; }
}

ну и что-нибудь такое из примеров предыдущих постов:
interface User
{
// Объекты, реализующие этот интерфейс, ДОЛЖНЫ иметь возможность
// получить свойство $fullName. Этого можно добиться обычным
// свойством или свойство с хуком get.
public string $fullName { get; }
}

class Customer implements User
{
// Хук get необязателен,
// свойство будет доступно для чтения даже без хука get.
public function __construct(public string $fullName) {}
}

свойство $fullName будет прекрасно читаться и без хука get. Но если мы определим хук get для свойства, оно будет доступно для чтения именно с помощью хука get.

Интерфейсы могут быть связаны только с публичным доступом, поэтому наличие приватных свойств не зависит от интерфейса и не может удовлетворить интерфейс. Это та же самая логика, что и для методов. Ключевое слово public свойства необходимо для обеспечения согласованности синтаксиса (или его редко используемый псевдоним var).

Следует отметить, что свойство интерфейса, которое требует только хук get может удовлетворяться общедоступным readonly свойством, поскольку ограничения readonly применяются только при записи. Однако свойство интерфейса, которое требует хук set несовместимо с readonly свойством, поскольку публичная запись будет запрещена.
2👍2
Привет, добрых майских,

продолжая тему RFC с Property Hooks, Brent Roose (автор сайта https://stitcher.io и канала PHP Annotated) провел трансляцию с одним из авторов RFC Ларри Гарфилдом, видео очень интересное, помимо основной темы затрагивались так же около externals/internals вопросы.

Если английский не помеха, советую посмотреть

https://www.youtube.com/watch?v=ULUrhIrjyAg
👍7
Всем, привет!

С наступающим праздником и небольшая заметка о возможной грядущей проблеме для кого-нибудь,

Как вы знаете (а может еще не в курсе), но недавно был релиз Mysql 8.4 и среди списка обновлений есть такой пункт как:

default_authentication_plugin: Deprecated in MySQL 8.0.27, and now removed. Use authentication_policy instead


Что логично ведет к отключению устаревшего плагина аутентификации mysql_native_password по умолчанию и полному отказу сервиса MySQL в принципе после обновления, если он у вас используется, а это может произойти как после запуска update и upgrade системы, так и запуск контейнера докера с mysql:latest.

В логах mysql /var/log/mysql/error.log можно увидеть ошибку, валящую СУБД:

2024-05-08T07:15:11.474311Z 0 [ERROR] [MY-000067] [Server] unknown variable 'default-authentication-plugin=mysql_native_password'.
2024-05-08T07:15:11.475302Z 0 [ERROR] [MY-010119] [Server] Aborting


Либо при попытке подключиться к MySQL:

mysql -u root -p

выдается:

ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded


Решить данную проблему можно, запустив MySQL с новой опцией сервера --mysql-native-password=ON или добавив директиву mysql-native-password=ON в раздел [mysqld] вашего конфигурационного файла MySQL:

#может быть здесь
nano /etc/mysql/mysql.conf.d/default-auth-override.cnf

#или здесь
nano /etc/mysql/mysql.conf.d/mysqld.cnf


открыв файл вы увидите что-то типа:

# This file is automatically generated by MySQL Maintainer Scripts
[mysqld]
default-authentication-plugin = mysql_native_password

приводим его к виду:

# This file is automatically generated by MySQL Maintainer Scripts
[mysqld]
mysql-native-password=ON

и перегружаем или стартуем mysql: service mysql start или service mysql restart

в докере меняем соотвественно команду c :

command: ["mysqld", "--default-authentication-plugin=mysql_native_password"]

на

command: ["mysqld", "--mysql-native-password=ON"]

ну или в любом другом месте где используется default-authentication-plugin=mysql_native_password на mysql-native-password=ON.

Должно все заработать, а вот что делать потом, дело каждого) главное все работает в данный момент и можно спокойно заниматься делами дальше.
👍12
Всем доброго дня!

В предыдущем посте с ошибкой unknown variable default-authentication-plugin=mysql_native_password мы смягчили последствия обновления до последней версии MySQL 8.4.

Но разработчики MySQL не просто так же удалили устаревший плагин mysql_native_password, значит нужно не просто сделать фикс системы, но сделать все правильно с точки зрения безопасности.

Например здесь можно узнать что теперь по-умолчанию в MySQL плагин аутентификации является caching_sha2_password. MySQL предоставляет два плагина аутентификации, которые реализуют хеширование SHA-256 для паролей учетных записей пользователей:

* sha256_password(устарело): реализует базовую аутентификацию SHA-256. Устарел и может быть удален. Не используйте этот плагин аутентификации.

* caching_sha2_password: реализует аутентификацию SHA-256 (как и sha256_password), но использует кэширование на стороне сервера для повышения производительности и имеет дополнительные функции для более широкого применения.

Решение - обновить старые пароли с помощью caching_sha2_password

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


Итак, первым делом надо вывести список пользователей, использующих плагин mysql_native_password, делаем запрос в MySQL (не важно какой клиент для подключения к MySQL вы используете):

mysql> SELECT user, host, plugin from mysql.user WHERE plugin="mysql_native_password";

Результат будет примерно такой:
+------------------+-----------+-----------------------+
| user | host | plugin |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session | localhost | mysql_native_password |
| mysql.sys | localhost | mysql_native_password |
| root | localhost | caching_sha2_password |
| mukhin | localhost | mysql_native_password |
+------------------+-----------+-----------------------+
5 rows in set (0.00 sec)


Поскольку caching_sha2_password это новый плагин аутентификации по умолчанию в MySQL 8.x, нам не нужно переопределять метод шифрования пароля дополнительной директивой или флагом. Единственное требование - заново создать/обновить пользователей базы данных с паролем.

Для этого надо будет сделать запрос по шаблону, для каждого пользователя, использующего старый mysql_native_password:

ALTER USER "%user%"@"%host%" IDENTIFIED WITH caching_sha2_password BY "%password%";

Например, чтобы обновить пользователя mukhin на хосту localhost:

ALTER USER "mukhin"@"localhost" IDENTIFIED WITH caching_sha2_password BY "its_not_my_really_password";

После обновления можно проверить, что ваше приложение нормально подключается к MySQL, и после повторного запроса на получение списка пользователей, использующих плагин mysql_native_password уже не выводится.

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

sudo nano /etc/mysql/mysql.conf.d/default-auth-override.cnf

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

# This file is automatically generated by MySQL Maintainer Scripts
[mysqld]
#mysql-native-password=ON

а в докере поубирать упоминание с установкой дефолтного плагина аутентификации:
"--default-authentication-plugin=mysql_native_password"

Делаем рестарт сервиса MySQL:
sudo service mysql restart

и не должны получить ошибок :)

Если вдруг вы удалите или закомментируете директиву #mysql-native-password=ON, а пароль забудете обновить с помощью caching_sha2_password и приложение перестанет работать, вы всегда можете вернуть или расскомментировать конфиг назад и попытаться сделать это снова.
👍7🐳1
Ребята, привет!

Сегодня пятница, 24 мая и возможность поделиться новостью об успешном #RFC - Создание экземпляров класса без дополнительных круглых скобок от Валентина Удальцова, которого вы знаете как автора канала Пых, а так же активного участника русскоязычного PHP-комьюнити.

Данная статья у меня висела в черновиках пару недель еще с 10 мая наверное, голосование шло оптимистично бодро, но конечно все что угодно можно было ожидать от голосующих, и на текущий момент "25 - за" и "4 - против" - я думаю результат понятен)

Итак, кто упустил этот момент напоминаю, что доступ к членам класса при создании экземпляра была представлен еще в PHP 5.4. С тех пор константы, свойства и методы могут быть доступны во вновь созданном экземпляре без промежуточной переменной, но только если выражение new заключено в круглые скобки:
$request = (new Request())->withMethod('GET')

в противном же случае мы получим синтаксическую ошибку:
// PHP Parse error: syntax error, unexpected token "->"
$request = new Request()->withMethod('GET');


Теперь же в PHP 8.4 мы сможем писать именно так, без дополнительных скобок вокруг new выражения:

new MyClass()->method()

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

Например, если использовать метод AAAS (Actions as a Service), т.е. вместо одного большого класса как сервис, много классов, каждый из которых может быть независимой, самостоятельной единицей (привет маниакальное использование SOLID), написание кода может вылиться в такой вид:

$user = (new UserFind())(new UserFindRequest($request))

Много скобочек, не правда ли,
тут конечно можно пенять сам себе Буратино, потому что в классах вместо _ _invoke(), можно использовать что-то более человекочитаемое, типа handle, run и другие методы, несущие смысл чего-то там запуска, типа:
$user = (new UserFind)->handle(new UserFindRequest($request))
Но опять же, дело вкуса, в любом случае уменьшение скобок в синтаксисе, по-моему мнению принесет пользу. Кто-то возможно будет не согласен, как люди, которые высказываются о возможных проблемах в externals и PR, но опять же это только начало, и в будущем возможны другие RFC, исправляющие их,

кстати, по-поводу упразднения оператора new - пока это невозможно в рамках этого RFC, Валентин упомянул это:

Некоторые языки, такие как Котлин, позволяют создавать экземпляры классов с помощью выражения MyClass(). Опустить ключевое слово new в PHP на данный момент невозможно, поскольку классы и функции могут иметь одно и то же имя (в Котлине это невозможно ). И чтобы добиться этого в PHP, нам следует сначала отказаться от объявления функций и классов с одинаковыми именами.


Можно порадоваться и поздравить @vudaltsov за первый и успешный RFC!
👍11🔥6
Доброе утро!

Или не доброе, учитывая последние новости, пока мы спали, Докер заблокировал доступ странам, попавшим под санкции.
В статье на Хабре уже идет активное обсуждение решения проблемы, логичным выходом из ситуации - указание проксей/зеркал:

Создайте или добавьте в конфиг демона докера /etc/docker/daemon.json директиву registry-mirrors:

{
"registry-mirrors": ["https://mirror.gcr.io"]
}

или любое другое зеркало из списка:

- https://huecker.io
- https://daocloud.io
- https://registry.docker-cn.com

Перегрузите докер и проверьте зеркала:

service docker restart
docker info


Вывод, что-то типа:
...
Registry Mirrors:
https://mirror.gcr.io/
Live Restore Enabled: false
👍9🤬32🐳2🤪2
Добрый вечер!

Теперь уж вправду добрый,

Вcе успели настроить зеркала и прокси в #докере?
Наверное даже не все успели обойти запрет, как внезапно https://hub.docker.com стал вновь доступен из России
3
Всем доброго дня!

Незаметно вышел очередной инновационный релиз MySQL 9.0, по уже устоявшейся стратегии изменений не так уж и много, итак что имеем в итоге:

1. Сохранение вывода JSON из EXPLAIN ANALYZE INTO. Теперь поддерживается сохранение выходных данных JSON из EXPLAIN ANALYZE в пользовательскую переменную с использованием синтаксиса:

EXPLAIN ANALYZE FORMAT=JSON INTO @variable select_stmt

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

2. Начиная с MySQL 9.0.0, можно подготовить следующие операторы:
- CREATE EVENT
- ALTER EVENT
- DROP EVENT
в виде параметризованных запросов внутри хранимых процедур с помощью PREPARE и EXECUTE, пример:

delimiter |

CREATE PROCEDURE sp(n INT)
BEGIN
SET @s1 = "CREATE EVENT e ON SCHEDULE EVERY ";
SET @s2 = " SECOND
STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND
ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
ON COMPLETION PRESERVE
DO
INSERT INTO d.t VALUES ROW(NULL, NOW(), FLOOR(RAND()*100))";

SET @s = CONCAT(@s1, n, @s2);
PREPARE ps FROM @s;
EXECUTE ps;
DEALLOCATE PREPARE ps;
END |

delimiter ;

3. MySQL 9.0 добавляет две новые таблицы, которые предоставляют информацию о системных переменных сервера:

Таблица variables_metadata содержит общую информацию о системных переменных. Эта информация включает имя, область действия, тип, диапазон (где применимо) и описание каждой системной переменной, распознаваемой сервером MySQL. Два столбца в этой таблице ( MIN_VALUE и MAX_VALUE) предназначены для замены устаревших столбцов таблицы variables_info.

В таблице global_variable_attributes представлена ​​информация о парах атрибут-значение, назначенных сервером глобальным системным переменным, таких как например offline_mode или read_only.

Атрибуты и их значения не могут быть установлены пользователями, так же они могут быть прочитаны только пользователями, запрашивающими эту таблицу. Атрибуты и их значения могут быть установлены, изменены или удалены только сервером.

4. Столбцы таблицы variables_info MIN_VALUE и MAX_VALUE теперь устарели и могут быть удалены в будущем. Вместо этого используйте столбцы таблицы variables_metadata которые имеют те же названия.

5. Ну и самое главное, что скорее всего повлекло за собой увеличение мажорной версии:

Плагин аутентификации mysql_native_password, ранее устаревший в MySQL 8.x, был удален. Теперь сервер отклоняет запросы аутентификации mysql_native от старых клиентов, которые не имеют функции CLIENT_PLUGIN_AUTH.

В связи с этим изменением также были удалены следующие параметры и переменные сервера:

- Серверный параметр --mysql-native-password
- Серверный параметр --mysql-native-password-proxy-users
- Системная переменная сервера default_authentication_plugin
👍5🔥2👌1
Привет!

Кстати, не успели мы оправиться после блокировки докер хаба, как подъехала новая в виде блокировки репозитория ondrej/php на packages.sury.org от самого автора:
Тут можно почитать его точку зрения https://github.com/oerdnj/deb.sury.org/issues/2155 по геоблокировке.

Вкратце, он заблокировал доступ пользователем из РФ, пока только к тем репозиториям, к которым у него есть доступ.

Не сказать что это блокировка вызовет большую проблему нежели блокировка докер хаба, но все же некоторые неудобства несет, те же мануалы по установке PHP на Debian/Ubuntu будут немного "барахлить" в случае установки на Debian, так то все же репозитории Ondrej'а были удобны и своевременно обновляемые.

Пока остаётся использовать стандартные пакеты php в ОС, хоть, конечно с небольшим отставанием.

Так же остаётся вариант контейнера докера с нужной версией php.

Ну и опять же зеркала того же https://mirror.yandex.ru скорее всего помогут обойти блокировку,

Кстати на Ubuntu пока проблему блокировки не наблюдаю, благо что заблокировать launchpad.net у него не получится.

Никто пока не столкнулся с этим?
🤬6💩3😁1
Всем, доброй пятницы!

Так ну "лед тронулся", график релизов PHP 8.4 немного сместился, Альфу 1 должны были выкатить только вчера 4 июля (хотя на самом деле 2 июля уже был ее релиз):

Запустил Альфу,

- "пощупал" функции array_find, array_find_key, array_any, array_all - достаточно удобно, про них кстати надо будет написать еще
- хуки пока не работают
- не получилось сходу запустить request_parse_body,
- зато Создание без скобочек от @vudaltsov работает без нареканий)

ждем остальные релизы!
👍19🎉6🔥4
Forwarded from Пых (Валентин Удальцов)
Пыхап 8 ноября!

Друзья, ровно через 2 недели пройдёт первый в истории митап от канала Пых! В программе у нас 3 хардкорных доклада:

🤯 (НЕ) используйте функциональное программирование в PHP
Андрей Клименко поломает вам голову основами ФП и примерами на Scala, из которых станет понятно, что из функционального мира уже доступно в PHP, а что ещё нужно законтрибьютить.

🐇 Вы не знаете RabbitMQ!
Вадим Занфир расскажет, почему все современные фреймворки теряют сообщения и как на самом деле надо работать с кроликом.

🤑 Как считать деньги и не терять их
В аду есть специальный котёл для тех, кто использует float для хранения денег. Сергей Жук подскажет, как в него не угодить.

Спонсор первого Пыхапа — моя любимая компания Happy Job 💚, где я проработал 4 года! Обращайтесь в Happy Job за исследованиями вовлечённости и оценкой 360, ребята делают лучшую платформу для развития сотрудников.

Пыхап пройдёт в уютном лофте «Событие» на Таганке, начало в 18:30. Вход бесплатный, но по билетам. Регистрация откроется на канале Пых в ближайший понедельник в 15:00, не пропустите. Ну и конечно же митап будет транслироваться на канале PHP Point с записью.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83