Отправляем почту в PHP в 2019 опубликовал Shuchkin\SimpleMail
$mail = new Shuchkin\SimpleMail();
$mail->setFrom('example@example.com')
->setTo('sergey.shuchkin@gmail.com')
->setSubject('Test SimpleMail')
->setText('Hi, Sergey!')
->send();
Возможности
- Сборка письма цепочкой вызовов
- Расширенная поддержка встроенной функции mail
- Встроенный SMTP клиент (TLS)
- Фабричные методы, один раз указали метод отправки и почту отправителя, а дальше отправляем через копию этого базового объекта
- Передача файлов
- UTF-8
- Свои заголовки
- Свой метод отправки
- Экспорт в массив или JSON
- Импорт из массива или JSON
Установка
Залит на GitHub, см. больше примеров
https://github.com/shuchkin/simplemail
И, конечно, на Packagist:
$ composer require shuchkin/simplemail
Асинхронная отправка почты PHP — react-smtp-client
Мне не хватало в ReactPHP простого инструмента для асинхронной отправки почты, так появился react-smtp-client
$loop = \React\EventLoop\Factory::create();
// у меня установлен postfix, в котором есть локальный smtp сервер
$smtp = new \Shuchkin\ReactSMTP\Client( $loop ); // localhost:25
$smtp->send('info@example.org', 'sergey.shuchkin@gmail.com', 'Test ReactPHP mailer', 'Hello, Sergey!')->then(
function() {
echo 'Message sent'.PHP_EOL;
},
function ( \Exception $ex ) {
echo 'SMTP error '.$ex->getCode().' '.$ex->getMessage().PHP_EOL;
}
);
$loop->run();
Получился аналог mail() для фреймворка ReactPHP. Можно подключаться хоть к GMail:
$smtp = new \Shuchkin\ReactSMTP\Client( $loop, 'tls://smtp.google.com:465', 'username@gmail.com','password' );
хоть к серверу Яндекс.Почты:
$smtp = new \Shuchkin\ReactSMTP\Client( $loop, 'tls://smtp.yandex.ru:465', 'username@yandex.ru', '**password**' );
Устанавливается через composer
composer require shuchkin/react-smtp-client

mysql segmentation fault (core dumped)
Отвалился mysql клиент с такой ошибкой.
$ mysql -u root
Segmentation fault (core dumped)
Оказалось клиент конфликтует с библиотекой libmysqlclient
из пакета Percona-Server-shared-51.
Поэтому сносим percona-server-shared и ставим обычные mysq-libs:
rpm -e --nodeps Percona-Server-shared-51
yum install mysql-libs
ОСТОРОЖНО! В процессе удаления percona-server-shared оригинальный my.cnf переименовался в my.cnf.rpmsave, поэтому:
yes | cp /etc/my.cnf.rpmsave /etc/my.cnf
Добавление индекса на мастер MySQL без блокировки
Решение подсмотрел в статье на хайлоаде
pt-online-schema-change
Инструмент pt-online-schema-change решает проблему блокировок таким образом:
- Создает таблицу с такой же структурой, как и у рабочей.
- Создает индексы на новой таблице (а она пустая, значит все быстро).
- Копирует данные из рабочей таблицы в новую (это долго, однако никаких блокировок).
- Создает триггеры для синхронизации данных между рабочей и новой таблицами.
- Заменяет рабочую таблицу на новую и удаляет старую.
Установить репозиторий Percona и percona-tools
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y
yum install percona-tools -y
Сначала запустить тест
pt-online-schema-change --alter "add index some_idx (some_field)" D=test_db,t=test_tbl,h=127.0.0.1 --user root --password pwd
ОСТОРОЖНО *ЛЯ! ДЕЛАЙ БЭКАПЫ!
А теперь стартуем по-настоящему:
pt-online-schema-change --alter "add index some_idx (some_field)" D=test_db,t=test_tbl,h=127.0.0.1 --user root --password pwd --execute
Я не трогал slave на время шаманства с мастером, но если критично отставание то есть опция --max-lag
, которая заставляет присматривать за slave-ом чтобы он сильно не отстал.
1> Cannot connect to h=5.123.456.78,p=...,u=root
No slaves found. See --recursion-method if host mydb.ru has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
analyze_table, 10, 1
copy_rows, 10, 0.25
create_triggers, 10, 1
drop_triggers, 10, 1
swap_tables, 10, 1
update_foreign_keys, 10, 1
Altering `mydb`.`user`...
Creating new table...
Created new table mydb._user_new OK.
Altering new table...
Altered `mydb`.`_user_new` OK.
2019-01-12T16:32:51 Creating triggers...
2019-01-12T16:32:51 Created triggers OK.
2019-01-12T16:32:51 Copying approximately 3648600 rows...
Copying `mydb`.`user`: 4% 10:29 remain
Copying `mydb`.`user`: 10% 08:35 remain
Copying `mydb`.`user`: 15% 08:23 remain
...
Copying `mydb`.`user`: 90% 01:21 remain
Copying `mydb`.`user`: 93% 00:59 remain
Copying `mydb`.`user`: 95% 00:35 remain
Copying `mydb`.`user`: 98% 00:13 remain
2019-01-12T16:49:27 Copied rows OK.
2019-01-12T16:49:28 Swapping tables...
2019-01-12T16:50:09 Swapped original and new tables OK.
2019-01-12T16:50:09 Dropping old table...
2019-01-12T16:50:14 Dropped old table `mydb`.`_user_old` OK.
2019-01-12T16:50:15 Dropping triggers...
2019-01-12T16:50:15 Dropped triggers OK.
Successfully altered `mydb`.`user`.
PS: Тулза руганулась что innodb_lock_wait_timeout только для чтения
Error setting innodb_lock_wait_timeout: DBD::mysql::db do failed: Variable 'innodb_lock_wait_timeout' is a read only variable [for Statement "SET SESSION innodb_lock_wait_timeout=1"]. The current value for innodb_lock_wait_timeout is 50. If the variable is read only (not dynamic), specify --set-vars innodb_lock_wait_timeout=50 to avoid this warning, else manually set the variable and restart MySQL.
Добавил в параметры вызова —set-vars innodb_lock_wait_timeout=50 и всё поехало.
SimpleCSV читаем, пишем CSV
Продолжаю вносить посильный вклад в опенсорс.
Исходники PHP-библиотеки для чтения/записи CSV можно забрать на GitHub

if ( $csv = SimpleCSV::import('book.csv') ) {
print_r( $csv );
}
Можно установить через Composer
$ composer require shuchkin/simplecsv
react-http-client
Штатный HTTP-клиент для ReactPHP мне показался жутко неудобным написал свой и выложил на GitHub https://github.com/shuchkin/react-http-client

Добавил пакет в packagist https://packagist.org/packages/shuchkin/react-http-client
$ composer require shuchkin/react-http-client
SimpleXLS — библиотека для чтения MS Excel 97 файлов в PHP
Выложил PHP reader для MS Excel 97 файлов https://github.com/shuchkin/simplexls

Собрал пакет composer
composer require shuchkin/simplexls
Собрал SimpleXLSX в пакет packagist/composer
Давно просили собрать нормальный пакет чтобы можно было ставить через composer. SimpleXLSX это php класс для извлечения данных из файлов нового формата (Excel 2007+)
Как это выглядит на packagist https://packagist.org/packages/shuchkin/simplexlsx

Банк для РКО
сделал выборку по своим клиентам, интересовало в каком банке обслуживается большинство моих контрагентов:
SELECT COUNT(id) AS cnt, org_bank_bik FROM user WHERE org_bank_bik>0 GROUP BY org_bank_bik ORDER BY cnt DESC LIMIT 10
N | Кол-во | БИК | Банк |
---|---|---|---|
1 | 113 | 044525225 | ПАО СБЕРБАНК |
2 | 64 | 044525593 | АО «АЛЬФА-БАНК» |
3 | 57 | 044525201 | ПАО АКБ «АВАНГАРД» |
4 | 46 | 044525974 | АО «ТИНЬКОФФ БАНК» |
5 | 27 | 040813608 | Дальневосточный Банк ПАО СБЕРБАНК |
6 | 26 | 045004774 | Новосибирский АО «АЛЬФА-БАНК» |
7 | 25 | 044525716 | ПАО «ВТБ 24» |
8 | 24 | 044030786 | Санкт-Петербургский АО «АЛЬФА-БАНК» |
9 | 21 | 044525555 | ПАО «ПРОМСВЯЗЬБАНК» |
10 | 20 | 047102651 | Западно-сибирский банк ПАО СБЕРБАНК |
В целом в Сбербанке — 160, в Альфе 114. Сбер настойчиво предлагает перейти к ним на РКО (сейчас в Авангарде), нужно подумать над этим.