Статьи

Поддержка вашего сервера с помощью командной строки PHP

Нас все больше в области информационных технологий просят надевать различные шляпы и выполнять несколько ролей в нашей повседневной работе. Многим из нас поручено не только создать и поддерживать веб-сайт, но и поддерживать сервер, на котором он размещен. Обычно при обслуживании сервера необходимо уметь писать сценарии и небольшие программы для автоматизации задач. Многие из этих сценариев написаны на Perl, Bash или другом языке сценариев. Теперь я вовсе не против изучения новых языков программирования, но знаете ли вы, что вы можете не только использовать PHP для написания отличных веб-приложений, но и использовать PHP из командной строки? Вы можете использовать PHP, который вы уже знаете и любите, чтобы этот сервер работал отлично из командной строки!

В этой статье мы рассмотрим преимущества использования PHP CLI. Я покажу вам, как тестировать PHP Интерфейс командной строки / Интерпретатор (CLI) на вашем сервере, а затем мы рассмотрим некоторые параметры, доступные для PHP CLI, включая интерактивную оболочку и как создавать исполняемые скрипты. Наконец, я дам вам несколько примеров сценариев, которые будут использоваться для поддержки вашего сервера на PHP.

Одним из самых больших преимуществ использования PHP CLI вместо некоторого другого языка сценариев является возможность многократного использования кода из предыдущих проектов в вашем сценарии. Будь то класс базы данных или созданная вами функция, или, возможно, программа анализа файлов, с PHP CLI вам не нужно переписывать какой-либо код.

Вы также можете автоматизировать многие задачи, написанные с помощью PHP CLI, с помощью CRON. Если вы никогда ранее не использовали CRON, это программа-демон, которая запускает указанные сценарии в определенное время на вашем сервере. Нужно создать отчет для отдела продаж по понедельникам, средам и пятницам? Напишите PHP-скрипт для этого, бросьте его в работу CRON и расслабьтесь, пока PHP и CRON выполняют эту работу за вас.

Запуск PHP CLI-скриптов

Если вы используете последнюю версию PHP, скорее всего, у вас уже установлен PHP CLI в вашей системе. Если примеры, приведенные в этой статье, вам не подходят, вам, вероятно, потребуется перекомпилировать PHP с параметром --enable-cli или переустановить пакет PHP, содержащий этот параметр. Самый простой способ проверить, все ли работает, – это открыть новое окно терминала или сеанс SSH для вашего сервера или компьютера, а из командной строки введите php -v .

  Стивенс-Ноутбук: ~ sthorpe $ php -v
 PHP 5.3.8 (cli) (построено: 5 декабря 2011 21:24:09)
 Copyright (c) 1997-2011 The PHP Group
 Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies 

Давайте попробуем быстрый пример, где мы запустим настоящий PHP-файл из командной строки. Создайте файл с именем test.php со следующим кодом, используя ваш любимый редактор:

 <?php $str = "SitePoint is the best!"; echo $str . "n"; 

Чтобы выполнить скрипт, все, что вам нужно сделать, это ввести php test.php и вы увидите вывод в командной строке.

  Стивенс-Ноутбук: ~ sthorpe $ php test.php
 SitePoint - лучший! 

Более предпочтительный метод запуска PHP-сценариев в командной строке – это изменить режим разрешений сценария и поместить #!/usr/bin/php в начале файла перед открывающим <?php (ваш путь к PHP может отличаться в зависимости от конфигурации вашей системы). Для этого вы будете использовать команду chmod в системах на основе UNIX.

 #!/usr/bin/php <?php $filepath = exec("pwd"); echo "You are in the $filepath directory.n"; 
  Стивенс-Ноутбук: ~ sthorpe $ chmod + x pwd.php
 Стивенс-Ноутбук: ~ sthorpe $ ./pwd.php
 Вы находитесь в каталоге ~. 

Параметры интерфейса командной строки и интерактивная оболочка

Ранее я уже показывал вам один из параметров командной строки PHP -v который дает номер версии PHP, установленного в вашей системе, но есть и другие доступные параметры. Например, если вы хотите поделиться кодом из сценария, который вы написали, с кем-то в качестве веб-страницы и выделить его синтаксис для лучшей читаемости, вы можете использовать опцию -s PHP выведет соответствующий код HTML.

  Стивенс-Ноутбук: ~ sthorpe $ php -s test.php <test.html 

При просмотре в веб-браузере результирующий test.html представляет выделенный код:

Другой полезный параметр – -l чтобы проверить ваши скрипты на наличие синтаксических ошибок. Если в файле не найдено ошибок, PHP сообщит, что синтаксических ошибок не было. В противном случае PHP сообщит об обнаруженной ошибке и о том, в какой строке она произошла.

  Стивенс-Ноутбук: ~ sthorpe $ php -l broken.php
 Ошибка синтаксического анализа PHP: синтаксическая ошибка, неожиданный T_VARIABLE в broken.php в строке 3
 Ошибки разбора broken.php 

В дополнение к многочисленным доступным опциям, с помощью PHP CLI вы можете проверить идеи в PHP-коде прямо из оболочки без необходимости создавать какие-либо файлы! Это полезно, когда вы хотите увидеть, какими могут быть результаты функции. Для запуска интерактивной оболочки PHP используйте -a . PHP сообщит «Интерактивная оболочка», и приглашение изменится на php > . С этого момента вы можете просто ввести свой код, и PHP выполнит его немедленно. Чтобы выйти из оболочки, вы можете либо нажать CTRL + D, либо вызвать exit .

  Стивенс-Ноутбук: ~ sthorpe $ php -a
 Интерактивная оболочка

 php> echo 2 + 2;
 4
 php> выход; 

Получение информации

С программированием CLI у вас есть два варианта ввода. Первый вариант – передать аргументы в ваш скрипт прямо из командной строки. Второй вариант – чтение ввода с клавиатуры (стандартный ввод) от пользователя, выполняющего скрипт.

Чтобы принимать аргументы в ваш скрипт, вы будете использовать предопределенные суперглобальные переменные $_SERVER["argc"] и $_SERVER["arvc"] . Создайте файл arguments.php содержащий следующий код:

 #!/usr/bin/php <?php echo "There are " . $_SERVER["argc"] . " arguments:n"; foreach($_SERVER["argv"] $arv) { echo "t" . $arv . "n"; } 

$_SERVER["argc"] содержит количество аргументов, которые были переданы скрипту, а $_SERVER["argv"] – это массив, содержащий все значения этих аргументов. У вас всегда будет хотя бы один аргумент, так как само имя файла считается первым аргументом.

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

  Стивенс-Ноутбук: ~ sthorpe $ php arguments.php SitePoint Rocks
 Есть 3 аргумента
    arguments.php
    SitePoint
    Горные породы 

Принятие ввода из стандартного ввода позволяет создавать интерактивные сценарии, которые могут запрашивать конкретную информацию. Создайте файл с именем keyboard.php со следующим кодом:

 #!/usr/bin/php <?php echo "Hi There! what is your favorite web site?n"; $site = fread(STDIN, 80); $site = trim($site); if ($site != "SitePoint") { echo "Are you sure that one is your favorite?n"; } else { echo "I knew it! Me too!n"; } 

В этом примере мы используем функцию fread() же, как и для чтения в файле, но в этом случае дескриптор – предопределенная константа PHP STDIN . Еще раз сделайте файл исполняемым и запустите файл; надеюсь, ваш вывод будет таким же, как мой.

 Стивенс-Ноутбук: ~ sthorpe $ php keyboard.php
 Всем привет!  какой твой любимый сайт?
 SitePoint
 Я знал это!  Я тоже! 

Некоторые примеры PHP CLI

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

 #!/usr/bin/php <?php // config options $disk = "/dev/disk0s2"; $threshold = 90; $emailAddr = "you@example.com"; $emailName = "Your Name Here"; exec("df -h " . $disk, $output); foreach($output as $line){ $info = strstr($line, $disk); if ($info != "") { break; } } $pos = stripos($info, "%"); $pos = $pos - 3; $used = substr($info, $pos, 3); if ($used >= $threshold) { mail($emailAddr, "System HD Notification", "Main disk is at " . $used . "%" , "From: $emailName"); } 

Функция exec() выполняет команду в командной строке и принимает два параметра: первый – это фактическая команда (в данном случае df которая отображает информацию о дисковом пространстве), а второй – ссылка на массив, которая заполняется выходными данными команды. Переменная $disk содержит путь к диску, который вы хотите отслеживать (в моем случае это /dev/disk0s2 ). Команда df выводит другие данные, отличные от используемого дискового пространства, поэтому мы будем искать только конкретную информацию из массива $output .

Код продолжается, просматривая массив и используя strstr() чтобы найти нужный диск и выйти из цикла, как только он будет найден. Я убираю часть строки, которая содержит процент дискового пространства, оставшегося с помощью substr() и сравниваю его с заранее заданным значением, в этом случае, если использование жесткого диска достигает 90% или более. Если это так, сценарий отправляет электронное письмо с уведомлением об этом.

Вы можете запускать этот быстрый сценарий как задание cron каждые 30 минут или около того, и это даст вам некоторое спокойствие.

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

 #!/usr/bin/php <?php // remote SFTP connection credentials $sftpServerIP = "10.0.0.1"; $sftpUsername = "sftpuser"; $sftpPassword = "hushhush"; $sftpTarget = "/home/sftpuser"; // mail notification config $emailAddr = "you@example.com"; $emailName = "Your Name Here"; // MySQL database connection credentials $mysqlUsername = "dbuser"; $mysqlPassword = "secret"; $mysqlDatabase = "myDatabase"; // list of directories and files to back up $files = array( "/home/username/important-file.txt", "/home/username/special-folder", "/var/spool/another-folder"); // create temporary directory and copy files/directories to it $tmpFolder = "/tmp/" . uniqid(); mkdir($tmpFolder, 0700); foreach ($files as $f) { exec("cp -r $f $tmpFolder/"); } // dump the database content exec("mysqldump -u $mysqlUsername -p$mysqlPassword $mysqlDatabase > $tmpFolder/backup.sql"); // compress the backup exec("tar -czf $tmpFolder.tgz $tmpFolder/*"); // establish the sftp connection $session = ssh2_connect($sftpServerIP, 22); if ($session === false) { mail($emailAddr, "System Backup", "Could not connect to SFTP server", "From: $emailName"); exit; } $result = ssh2_auth_password($session, $sftpUsername, $sftpPassword); if ($result === false) { mail($emailAddr, "System Backup", "Could not authenticate to SFTP server", "From: $emailName"); exit; } $sftp = ssh2_sftp($session); if ($sftp === false) { mail($emailAddr, "System Backup", "Could not initialize SFTP subsystem", "From: $emailName"); exit; } // transfer the backup file $date = date("D"); $upload = file_put_contents( "ssh2.sftp://" . $sftp . $sftpTargetDir . "/backup-$date.tgz", file_get_contents("$tmpFolder.tgz")); if ($upload) { mail($emailAddr, "System Backup", "Your files has been backed up successfully", "From: $emailName"); } else { mail($emailAddr, "System Backup", "Something went wrong with the upload of the backup", "From: $emailName"); } // clean up the local temp backups exec("rm -r $tmpFolder $tmpFolder.tgz"); 

Мы снова используем функцию exec() для выполнения других программ и команд из нашего скрипта PHP, таких как mysqldump для выгрузки содержимого базы данных и tar для сжатия папки резервной копии в архив. в переменную, которую мы определили ранее. Подключение к SFTP-серверу использует расширение PHP SSH2 , поэтому вам нужно установить это расширение. Хорошую статью можно найти в блоге Кевина ван Зонневельда . Код не должен быть слишком сложным для изменения, если вы хотите использовать чистое решение, такое как phpseclib, или даже более старый (и небезопасный) протокол, такой как FTP. Независимо от вашего подхода, в этом примере показаны некоторые преимущества сценариев таких задач с помощью PHP.

Резюме

В этой статье мы рассмотрели использование PHP из командной строки для написания сценариев обслуживания сервера. Я говорил о преимуществах использования PHP CLI, включая возможность автоматизации ваших скриптов. Мы рассмотрели несколько доступных опций, таких как возможность проверки ваших скриптов на наличие синтаксических ошибок и использование интерактивного режима. Мы также узнали о различных доступных функциях ввода, включая прием ввода прямо с клавиатуры. Затем я дал вам два реальных примера сценариев, которые можно использовать для поддержки своих собственных серверов, включая сценарий мониторинга жесткого диска и сценарий резервного копирования.

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

Изображение через Chengyuan Yang / Shutterstock