Недавно на одном из форумов наткнулся на запись о том, что php — это язык для веб-разработки. Да, большинство сайтов (включая даже википедию) написаны именно на php, но этот язык можно использовать не только для веба.
Статья рассчитана на новичков php, на людей которые не знают, как писать консольные программы, поэтому, если вы гуру-программист, можете листать дальше. Под катом рассматривается пример простой консольной программы на php.
Что бы в unix системах в командной строке выполнить php скрипт, его нужно запустить следующей командой
php app.php [param] [param]

С помощью параметров можно передавать нашему скрипту какие либо данные. Они будут хранится в массиве
$argv

Нулевой элемент этого массива — название php файла.

В качестве примера консольной php программы мы рассмотрим хранилище контактов, которое будет выдавать нам следующую информацию:
==============================================
Идентификатор: 1
ФИО:           Вася
Телефон:       8-920-000-00-00
Email:         vasya@mail.ru
Комментарий:   Знакомый из садика
==============================================
==============================================
Идентификатор: 2
ФИО:           Коля
Телефон:       234543
Email:         kolya@ya.ru
Комментарий:   Заметка о контакте
==============================================


Данные будут хранится в MySQL базе данных. Создадим таблицу
CREATE TABLE `contacts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` text,
  `email` text,
  `tel` text,
  `comment` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8


Для работы с базой данных мы будем использовать класс SafeMySQL (GitHub)

Подключаем класс базы данных и описываем класс настроек
    include "safemysql.class.php";
    // Настройка программы
    class set {
        public $bdset = array(
            'host' => 'localhost', // Хост сервера базы данных
		    'user' => 'root',       // Логин для доступа к БД
		    'pass' => 'root',// Пароль для доступа к БД
		    'db'   => 'cont',       // Название базы данных
         );
        public $q = "hello";
    }

Не забываем поменять данные на свои.

В зависимости от параметра будем выполнять разные функции
system("clear"); //Очищаем экран перед выводом
    // Шапка программы (там написано contacts)
    echo "             _           _\n";
    echo " ___ ___ ___| |_ ___ ___| |_ ___\n";
    echo "|  _| . |   |  _| .'|  _|  _|_ -|\n";
    echo "|___|___|_|_|_| |__,|___|_| |___|\n";
    echo "Надёжное хранение ваших контактов\n";
    // Выполнение действия, в зависимости от параметра
    switch ($argv[1]) {
        case 'view':
            $do = new action();
            $do->view();
            break;
        case 'edit':
            if (isset($argv[2])) {
                $do = new action();
                $do ->edit($argv[2]);
            }
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
        case 'add':
            $do = new action();
            $do ->add();
            break;
        case 'delete':
            if (isset($argv[2])) {
                $do = new action();
                $do ->delete($argv[2]);
            }
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
        case 'help':
            $do = new action();
            $do ->help();
            break;

        default:
            // Если параметр нам не подходит, или его нет, говорим об ошибке
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
    }
    echo "\n"; // Делаем ещё один перевод строки, что бы отделить вывод программы


Осталось описать класс action и все его функции.
Функция просмотра
public function view(){
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            $data = $db->getAll("SELECT * FROM contacts");
            foreach ($data as $key) {
                echo "==============================================\n";
                echo "Идентификатор: ".$key["id"]."\n";
                echo "ФИО:           ".$key["name"]."\n";
                echo "Телефон:       ".$key["tel"]."\n";
                echo "Email:         ".$key["email"]."\n";
                echo "Комментарий:   ".$key["comment"]."\n";
                echo "==============================================\n";
            }
}

Функция добавления
public function add() {
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            // Задаём вопросы и записываем данные в переменные
            echo "Введите имя контакта: \n";
            $addname = readline();
            echo "Введите телефон контакта: \n";
            $addtel = readline();
            echo "Введите email контакта: \n";
            $addemail = readline();
            echo "Введите комментарий к контакту: \n";
            $addcomment = readline();

            // Добавляем в базу
            $db->query("INSERT INTO contacts (name, tel, email, comment) VALUES (?s, ?s, ?s, ?s)", $addname, $addtel, $addemail, $addcomment);
            echo "Запись добавлена \n";
            // Показываем список всех контактов
            $do = new action();
            $do->view();
        }

Функция редактирования
public function edit($id) {
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            // Задаём вопросы и записываем данные в переменные
            echo "Введите имя контакта: \n";
            $editname = readline();
            echo "Введите телефон контакта: \n";
            $edittel = readline();
            echo "Введите email контакта: \n";
            $editemail = readline();
            echo "Введите комментарий к контакту: \n";
            $editcomment = readline();

            // Обновляем запись
            $db->query("UPDATE contacts SET name = ?s, tel = ?s, email = ?s, comment = ?s WHERE id = ?i", $editname, $edittel, $editemail, $editcomment, $id);
            echo "Запись обновлена \n";
            // Показываем список всех контактов
            $do = new action();
            $do->view();
        }

Функция удаления
 public function delete($id){
            echo "Вы действительно хотите удалить контакт #".$id."? (y/n) \n";
            $del = readline();
            if ($del == "y") {
                // Создаём объект класса настроек
                $sets = new set();
                // Создаём объект класса базы данных и указываем ему параметры
                $db = new SafeMySQL($sets->bdset);
                // Удаляем контакт из базы
                $db->query("DELETE FROM contacts WHERE id = ?i", $id);
                echo "Запись удалена \n";
                // Показываем список всех контактов
                $do = new action();
                $do->view();
            }
            else echo "Ну нет, так нет. \n";

        }

Функция показа справки
        public function help() {
            echo "==============================================\n";
            echo "Справка по программе\n";
            echo "==============================================\n";
            echo "php contacts.php view - вывод всех контактов\n";
            echo "php contacts.php view 3 - вывод контакта с определённым идентификатором\n";
            echo "php contacts.php add - добавление контакта\n";
            echo "php contacts.php delete 3 - удаление контакта с определённым идентификатором\n";
            echo "php contacts.php help - показать эту подсказку\n";
        }


Я старался написать понятный даже новичку код, комментировал почти каждую строчку и использовал ООП.
Программа не претендует на звание правильной и эффективной, но если кому понадобится — вот
Код полного файла
<?php
    // Программа для хранения контактов

    // Подключем класс базы данных
    include "db.php";
    // Настройка программы
    class set {
        public $bdset = array(
            'host' => 'localhost', // Хост сервера базы данных
		    'user' => 'root',       // Логин для доступа к БД
		    'pass' => 'root',// Пароль для доступа к БД
		    'db'   => 'cont',       // Название базы данных
         );
        public $q = "hello";
    }
    // Класс обработки действий
    class action {
        // Функция показа контакта (контактов)
        public function view(){
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            $data = $db->getAll("SELECT * FROM contacts");
            foreach ($data as $key) {
                echo "==============================================\n";
                echo "Идентификатор: ".$key["id"]."\n";
                echo "ФИО:           ".$key["name"]."\n";
                echo "Телефон:       ".$key["tel"]."\n";
                echo "Email:         ".$key["email"]."\n";
                echo "Комментарий:   ".$key["comment"]."\n";
                echo "==============================================\n";
            }
        }
        // Функция добавления контакта
        public function add() {
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            // Задаём вопросы и записываем данные в переменные
            echo "Введите имя контакта: \n";
            $addname = readline();
            echo "Введите телефон контакта: \n";
            $addtel = readline();
            echo "Введите email контакта: \n";
            $addemail = readline();
            echo "Введите комментарий к контакту: \n";
            $addcomment = readline();

            // Добавляем в базу
            $db->query("INSERT INTO contacts (name, tel, email, comment) VALUES (?s, ?s, ?s, ?s)", $addname, $addtel, $addemail, $addcomment);
            echo "Запись добавлена \n";
            // Показываем список всех контактов
            $do = new action();
            $do->view();
        }
        // Функция удаления контакта
        public function delete($id){
            echo "Вы действительно хотите удалить контакт #".$id."? (y/n) \n";
            $del = readline();
            if ($del == "y") {
                // Создаём объект класса настроек
                $sets = new set();
                // Создаём объект класса базы данных и указываем ему параметры
                $db = new SafeMySQL($sets->bdset);
                // Удаляем контакт из базы
                $db->query("DELETE FROM contacts WHERE id = ?i", $id);
                echo "Запись удалена \n";
                // Показываем список всех контактов
                $do = new action();
                $do->view();
            }
            else echo "Ну нет, так нет. \n";

        }
        // Функция редактирования контакта
        public function edit($id) {
            // Создаём объект класса настроек
            $sets = new set();
            // Создаём объект класса базы данных и указываем ему параметры
            $db = new SafeMySQL($sets->bdset);
            // Задаём вопросы и записываем данные в переменные
            echo "Введите имя контакта: \n";
            $editname = readline();
            echo "Введите телефон контакта: \n";
            $edittel = readline();
            echo "Введите email контакта: \n";
            $editemail = readline();
            echo "Введите комментарий к контакту: \n";
            $editcomment = readline();

            // Обновляем запись
            $db->query("UPDATE contacts SET name = ?s, tel = ?s, email = ?s, comment = ?s WHERE id = ?i", $editname, $edittel, $editemail, $editcomment, $id);
            echo "Запись обновлена \n";
            // Показываем список всех контактов
            $do = new action();
            $do->view();
        }
        // Функция показа справки
        public function help() {
            echo "==============================================\n";
            echo "Справка по программе\n";
            echo "==============================================\n";
            echo "php contacts.php view - вывод всех контактов\n";
            echo "php contacts.php view 3 - вывод контакта с определённым идентификатором\n";
            echo "php contacts.php add - добавление контакта\n";
            echo "php contacts.php delete 3 - удаление контакта с определённым идентификатором\n";
            echo "php contacts.php help - показать эту подсказку\n";
        }

    }

    system("clear"); //Очищаем экран перед выводом
    // Шапка программы (там написано contacts)
    echo "             _           _\n";
    echo " ___ ___ ___| |_ ___ ___| |_ ___\n";
    echo "|  _| . |   |  _| .'|  _|  _|_ -|\n";
    echo "|___|___|_|_|_| |__,|___|_| |___|\n";
    echo "Надёжное хранение ваших контактов\n";
    // Выполнение действия, в зависимости от параметра
    switch ($argv[1]) {
        case 'view':
            $do = new action();
            $do->view();
            break;
        case 'edit':
            if (isset($argv[2])) {
                $do = new action();
                $do ->edit($argv[2]);
            }
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
        case 'add':
            $do = new action();
            $do ->add();
            break;
        case 'delete':
            if (isset($argv[2])) {
                $do = new action();
                $do ->delete($argv[2]);
            }
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
        case 'help':
            $do = new action();
            $do ->help();
            break;

        default:
            // Если параметр нам не подходит, или его нет, говорим об ошибке
            echo "Ошибка параметра, воспользуйтесь справкой \n";
            break;
    }
    echo "\n";

Комментарии (10)


  1. Borro
    21.02.2016 22:34
    +3

    Если уж хотите писать консольные приложения, то рекомендую Symfony Console Component — там и ООП, и удобное форматирование вывода/ввода, инициализация аргументов


    1. pingvi69
      21.02.2016 22:52

      Задача была именно с чистым php


      1. Fedcomp
        22.02.2016 10:27

        Что мешает подключить именно сам Console component? или у вас даже vendor не было?


  1. Delphinum
    22.02.2016 00:00
    +2

    А почему не:

    touch script.php
    nano scrtipt.php

    #!/usr/bin/php
    <?php
    echo 'Hello world';

    chmod +x script.php
    ./script.php

    Какое же консольное приложение если его приходится вызывать из под php интерпретатора? )


    1. garex
      22.02.2016 01:23

      Тогда уж

      #!/usr/bin/env php
      <?php // cool scripts goes hia

      И расширение убрать нафик — королю баша не подобает знать на чём написана очередная тулза.


  1. Anonym
    22.02.2016 01:18
    +3

    Подумал, что ресурсом ошибся. Когда я давным-давно писал о том, как сделать демона на php, меня закидали помидорами. А теперь вон скриптики учимся писать. Беда...


    1. Delphinum
      22.02.2016 02:01

      Открою вам секрет, автора тоже закидали помидорами


  1. DrPass
    22.02.2016 01:33
    +3

    > Статья рассчитана на новичков php, на людей которые не знают, как писать консольные программы
    Может, с образовательной точки зрения лучше было бы не рассказывать, как якобы писать «консольные приложения на РНР», а объяснить более «архитектурно», что такое потоки ввода/вывода, как вывод, который генерирует скрипт, получает веб-сервер, как его же можно направить в обычный вывод консоли и т.д.?


    1. Akdmeh
      22.02.2016 03:12

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


      1. Fedcomp
        22.02.2016 10:28

        Да практически по любой теме есть документация где то еще. Значит на хабр ничего не писать?