Как по-быстрому увеличить объём выделяемой памяти для консольного PHP скрипта?

Иногда при обработке с помощью PHP больших и не очень данных, можно словить досадную ошибку посреди выполнения скрипта:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)

Конечно, можно увеличить memory_limit в php.ini или дописать в скрипт:

ini_set('memory_limit','256M');

Читать далее Как по-быстрому увеличить объём выделяемой памяти для консольного PHP скрипта?

Cлучайные числа с плавающей точкой в PHP

Стандартные библиотеки PHP умеют генерировать только целые случайные числа. Однако, возникают задачи где нужно не целое рандомное число с максимально длинным хвостом, например, в диапазоне от 0 до 1. В таком случае можно воспользоваться таким способом:

$rnd = rand(0, getrandmax() ) / getrandmax();

Если же количество знаков после запятой должно быть, например, 2, то:

$rnd = rand(0, 100) / 100;

Отлично! А что, если нужно случайное число в диапазоне от 4 до 10 с тремя знаками после запятой? Пожалуйста:

$rnd = 4 + rand(0, 1000) / (1000 / (10 - 4) );

Или:

$rnd = 4 + rand( 0, (10 - 4) * 1000 ) / 1000;

Что не так с этим скриптом?

Очень крутая задача, в которой не всё так просто, как кажется на первый взгляд. Попробуйте найти в ней 2 логические ошибки. SQL-инъекция здесь служит отвлекающим манёвром.

<?php 
 $dest = $_POST['destination']; 
 $result = $_POST['data']['result']; 
 $output = ""; 
 
 if ($dest == 'file') { 
     $file = fopen('storage.txt', 'a+'); 
     fwrite($file, $result); 
     $output = "stored in file"; 
 } elseif ($dest == 'db') { 
     $db = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'user', 'pass'); 
     $db->exec("INSERT INTO storage (value) VALUES ('{$result}');"); 
     $output = "stored in db"; 
 } 
 
 echo $output;

Читать далее Что не так с этим скриптом?

Чистка логов docker-контейнеров

Весь stdout контейнеров докер бережливо сохраняет в файлики. По-дефолту эти логи никак не ротируются и копятся до тех пор, пока не закончится место на диске. Если неизбежное произошло, можно элегантно освободить место на диске следующей командой:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

Как в Laravel 5.5 и 5.4 получать select в виде массива, а не объекта

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

По-умолчанию все данные получаемые через фасад DB возвращаются в виде объектов, массива объектов или коллекции объектов, что может до 10 раз увеличивать потребление памяти, по сравнению с обычными массивами. И это всё в добавок к тому, что сам PHP хранит данные в памяти самым расточительным образом! Читать далее Как в Laravel 5.5 и 5.4 получать select в виде массива, а не объекта

Как редактировать crontab через nano

Vim не самый юзер-френдли текстовый консольный редактор, например, nano на порядок удобнее и интуитивнее. Однако, именно vim является редактором для крона по-умолчанию в CentOS.

crontab -e

Команда выше открывает крон-файл текущего пользователя для редактирования в редакторе по-умолчанию. Однако, его можно изменить разово перед каждым открытие крона на редактирование.

EDITOR=nano crontab -e

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

export EDITOR=nano

Когда надоест и это, остаются только крайние меры: определение этой константы в конце файла /etc/bashrc.

Вачдог по-быстрому

Бывают ситуации, когда что-то идёт не так и нужно по-быстрому запилить килялку чего либо и как можно скорее вернуться к выполнению основной задачи. Типичная ситуация: плодятся процессы, которые никто не прибивает, что приводит к утечке ресурсов и тормозам на всём сервере. Самым быстрым способом будет мониторинг количества процессов и рестарту ноды/приложения при достижении критического значения.

while true; do pscnt=$(ps aux | grep [your app] | wc -l); echo "$pscnt"; if (( pscnt > 500 )); then [your app restart]; fi; sleep 2; done

Запуск такого скрипта из консоли будет не лучшей идеей, гораздо надёжнее положить его в крон примерно таким образом:

* * * * * pscnt=$(ps aux | grep [your app] | wc -l); echo "$pscnt"; if (( pscnt > 500 )); then [your app restart]; fi; >> /var/log/watcher.log

Ну и конечно при первой возможности разобраться с причинами этой ситуации.

Как использовать команду watch с пайпами

Периодически при работе с консолью Linux нужно пронаблюдать за изменением вывода какой-либо команды с промежутком в несколько секунд. Для этого есть команда:

watch [your commands]

Но если в исходной команде присутствует конвейер (pipe), то его использование в лоб не приведёт к желаемому результату, например:

watch ps aux | wc -l

На выводе вы ничего не получите. Для корректной работы такую последовательность команд нужно заключить в одинарные кавычки:

watch 'ps aux | wc -l'

Возможно, не самое красивое решение, но работает.

Если вы не ищите лёгких путей, то есть такой вариант:

while true; do ps aux | wc -l; sleep 2; done