Консольные команды в Yii

Радостная девушка

Для решения специфических задач часто используются готовые консольные команды. Но намного интереснее не только использовать чужие, но и уметь создавать свои. Это поможет легко автоматизировать любую рутинную работу, на которую обычно тратится довольно много времени. Многие фреймворки имеют встроенные инструменты для написания не только самих веб-приложений, но и для создания инфраструктуры пользовательских консольных команд.

Очень удобно в командной строке перейти в папку приложения на фреймворке Symfony и выполнить:

php app/console cache:clear

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

Можно сделать в админ-панели вашего сайта кнопку для очистки кэша, но консольный вариант мы можем добавить в более продвинутый Bash скрипт, который будет не только очищать кэш, но и делать что-то ещё при загрузке новой версии файлов на рабочий сервер. Такие команды можно автоматически прописать в так называемых «хуках» у системы контроля версий.

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

Фантазии нет границ, и некоторые увлечённые люди могут совместить COM-порт, микроконтроллер и дворники от автомобиля, чтобы консольной командой очищать от пыли свой монитор...

Перейдём теперь к изучению консольной работы в PHP.

Консольный режим в PHP

Так называемый интерфейс командной строки (Command Line Interface) представляет собой возможность запускать PHP-файлы в консоли. Если в системе установлен PHP, то можно попробовать открыть консоль и ввести команду:

php -v

Если Windows сообщит нам, что команда php не найдена, то нужно либо перейти в каталог с файлом php.exe, либо добавить путь этого файла в глобальную переменную PATH окружения и перезагрузить систему.

Если проблем с этим нет, то команда запустит процесс php с параметром -v. В ответ на это нам выведется информация о версии установленного у нас интерпретатора.

Создадим теперь файл console.php:

<?php
echo "Console command\n";
echo $argc . PHP_EOL;
print_r($argv);

Переменные $argv и $argc содержат в себе массив параметров и их количество. Попробуем теперь запустить выполнение этого скрипта в командной строке с помощью нашего интерпретатора:

php console.php

Как альтернативный вариант в Unix системах мы можем добавить аннотацию в первой строке файла как #!/usr/bin/php или в более универсальном виде:

#!/usr/bin/env php
<?php
echo "Console command\n";
echo $argc . PHP_EOL;
print_r($argv);

после этого можно сделать файл исполняемым и запускать прямым вызовом:

chmod +x console.php
./console.php

В любом из этих случаев наш скрипт выполнится и в консоли будет выведен результат его работы:

Console command
1
Array(
    [0] => console.php,
)

Входящие параматры $argv и $argc устроены таким образом, что первым значением передаётся само имя файла.

Попробуем вызвать наш скрипт немного другим образом:

php console.php aaa bbb --ccc=ddd

Результат работы нашего скрипта изменится, так как все дополнения попадут в массив аргументов:

Console command
4
Array
(
    [0] => console.php
    [1] => aaa
    [2] => bbb
    [3] => --ccc=ddd
)

Попробуем выполнить в командной строке и через браузер один и тот же скрипт index.php:

<?php
set_time_limit(0);
for ($i=0; $i<100; $++) {
    echo 'Step ' . $i . PHP_EOL;
    sleep(1);
}
echo 'End' . PHP_EOL;

Вкладка браузера «зависнет» на 100 секунд, после чего мы увидим результат. А при выполнении в консоли строки будут выводиться в реальном времени. Нажав в консоли комбинацию Ctrl+C или Ctrl+Break мы прервём исполнение в любой момент. Также можно воспользоваться классическими приёмами работы в командной строке и стандартным образом записать результат в файл:

php index.php > log.txt

Интересные возможности предоставляет нам использование функции fgets() с потоком ввода STDIN. Этим способом можно запрашивать информацию от пользователя:

<?php
set_time_limit(0);
echo 'What is your name?' . PHP_EOL;
$name = fgets(STDIN);
echo 'Hello, ' . trim($name) . '!' . PHP_EOL;

Это удобный инструмент для создания диалогов:

<?php
set_time_limit(0);
echo 'Are you a man? (Y/n): ';
$man = fgets(STDIN);
echo strtoupper(trim($man)) == 'Y' ? 'Your are a man!' : 'Your are not a man!';
echo PHP_EOL;

Выполнение скрипта прервётся, пока кто-то не введёт ответ и не нажмёт Enter.

Таким образом мы можем создавать консольные скрипты не только на Bash, Perl, Ruby или Python, но и на PHP. Нюансы использования CLI-режима можно изучить, например, здесь.

Внутри скрииптов мы можем запускать другие стандартные консольные команды функциями system() или exec(). Консольные скрипты легко добавляются в список планировщика Cron:

0 * * * root cd /path/to/app && php console.php

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

Обратите внимание, что при запуске PHP-скрипта в интерфейсе командной строки классические HTTP элементы $_GET, $_POST, $_REQUEST, $_COOKIE, $_SERVER['REQUEST_URI'], $_SERVER['REQUEST_TYPE'] и некоторые другие не будут определены.

Консольные команды в Yii

Вписывать некий функционал в «обычные» PHP-файлы интересно, но до тех пор, пока для работы с базой данных хватит стандартного mysql_query или ручного подключения PDO. Эффективнее использовать некоторые вещи сразу из Yii, например Yii::app()->db или свои же модели.

Yii Framework предоставляет нам такую возможность. В консоли можно зайти в папку protected и запустить файл yiic.php:

php yiic.php

Это универсальный варинт для любой системы. В Windows с тем же успехом можно запустить BAT-файл yiic.bat:

yiic

В Linux можно сделать исполняемым файл yiic:

chmod +x yiic

и запускать уже его

./yiic

В итоге на экране мы увидим приветствие и перечисление встроенных команд, которые мы можем использовать:

Yii command runner (based on Yii v1.1.14)
Usage: yiic.php  [parameters...]

The following commands are available:
 - message
 - migrate
 - shell
 - webapp

To see individual command help, use the following:
   yiic.php help 

Миграции мы обсудим подробно как-нибудь потом, а сейчас попробуем сделать что-то самостоятельное.

Итак, зайдём в папку protected/commands и создадим файл CacheCommand.php со следующим содержимым:

class CacheCommand extends CConsoleCommand
{
    public function run($args) {
        Yii::app()->cache->flush();
        echo 'The cache is cleared' . PHP_EOL;
    }
}

Это класс, наследующийся от CConsoleCommand и переопределяющий базовый метод run($args). Вернёмся на уровень выше (в папку protected) и запустим в командной строке нашу новую команду cache:

php yiic.php cache

Если все пути в файле yiic.php указаны верно и в конфигурационном файле protected/config/console.php настроен компонент cache:

return array(
    ...
    'components'=>array(
        ...
        'cache'=>array(
            'class'=>'CFileCache',
        ),
    ),
    ...
);

то на экране должна высветиться фраза «The cache is cleared».

В метод run() при запуске передаётся массив $args, который представляет из себя ни что иное, как рассмотренный нами ранее массив параметров $argv.

Теперь поступим следующим образом: удалим метод run(), добавим два метода actionClear и actionCheck и снова запустим yiic cache:

class CacheCommand extends CConsoleCommand
{
    public function actionClear() {
        Yii::app()->cache->flush();
        echo 'The cache is cleared' . PHP_EOL;
    }
 
    public function actionCheck() {
        echo 'Testing of ' . get_class(Yii::app()->cache) . PHP_EOL;
        Yii::app()->cache->set('test', 'test value');
        if (Yii::app()->cache->get('test') == 'test value') {
            echo 'Storing is valid' . PHP_EOL;
        } else {
            echo 'Storing is failed' . PHP_EOL;
        }
        Yii::app()->cache->delete('test');
        if (empty(Yii::app()->cache->get('test'))) {
            echo 'Deleting is valid' . PHP_EOL;
        } else {
            echo 'Deleting is failed' . PHP_EOL;
        }
    }
}

На экране вместо сообщения о выполненни мы увидим некое объяснение:

Error: Unknown action: index

Usage: yiic.php cache 
Actions:
    clear
    check

Это сообщение сгенерировано методом базового класса CConsoleCommand::run (который мы теперь не переопределяем). В первой строке идёт сообщение об ошибке (не найден метод по умолчанию actionIndex). Далее идёт автоматически сгенерированная методом CConsoleCommand::getHelp справка по команде. Она говорит, что в классе CacheCommand присутствуют два метода-действия, и нам нужно уточнить, какой из них мы хотим выполнить. Эту же справку мы можем получить и самостоятельно командой help:

php yiic.php help cache

Фактичестки, классы консольных команд можно строить по тому же принципу, как и контроллеры.

Учтём теперь это замечание и запустим наши команды:

php yiic.php cache clear
php yiic.php cache check

Теперь оба действия сработают правильно.

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

Команды с параметрами

Родство действий команды с действиями контроллера на этом не заканчивается. Аналогично действия команд могут принимать аргументы. Как система маршрутизации извлекает из адреса и передаёт контроллеру GET-параметры, так и анализатор консольного приложения Yii преобразует введённые значения и передаёт их в аргументы команды.

Создадим команду с аргументом $name:

class ShowCommand extends CConsoleCommand
{
    public function actionHello($name) {
        echo 'Hello, ' . $name . '!' . PHP_EOL;
    }
}

и запустим её:

php yiic.php show hello --name=Vasya

Добавим возраст:

class ShowCommand extends CConsoleCommand
{
    public function actionHello($name, $age=18) {
        echo 'Hello, ' . $name . '! You are ' . $age . ' years old.' . PHP_EOL;
    }
}

и передадим оба значения:

php yiic.php show hello --name=Vasya --age=21

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

А что будет, если не передавать значение имени?

php yiic.php show hello --name --age=21

В данном случае Yii воспримет --name как логический флаг и присвоит ему значение true.

А вдруг нам нужно перечислить несколько значений? Для этого объявляем аргумент типа array:

class ShowCommand extends CConsoleCommand
{
    public function actionHello(array $name) {
        echo 'Hello, ' . implode(', ', $name) . PHP_EOL;
    }
}

и передаём все имена:

php yiic.php show hello --name=Vasya --name=Petya --name=Dima

Код возврата

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

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

Сама система эти коды не различает, но мы можем их сделать полезными для себя. Расставим в любой нашей команде контрольные точки:

class CalculateCommand extends CConsoleCommand
{
    public function run($args) {
        ...
        if (!...) {
            return 1;
        }
        ...
        try {
            ...
        } catch (Exception $e) {
            return 2;
        }
        ...
        return 0;
    }
}

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

В предыдущих командах мы ни разу не встречали строку return 0;. Это нормально, так как Yii по умолчанию делает это за нас.

Выполнение через yiic.php и свои фронт-контроллеры

Всё, что содержит файл protected/yiic.php – это указание путей к файлу конфигурации protected/config/console.php и подключение файла framework/yiic.php, в котором и происходит создание приложения. Изучив исходный код мы можем сделать аналог файла framework/yiic.php в виде какого-нибудь protected/cli.php:

<?php
$yii = dirname(__FILE__) . '/framework/yii.php';
$config = dirname(__FILE__) . '/config/console.php';
 
defined('YII_DEBUG') or define('YII_DEBUG', true);
 
require_once($yii);
Yii::createConsoleApplication($config)->run();

Этот код практически не отличается от кода файла index.php, за исключением указания другого конфигурационного файла и создания консольного приложения методом createConsoleApplication вместо стандартного createWebApplication. При этом вместо экземпляра CWebApplication в Yii::app() будет содержаться немного другой класс CConsoleApplication.

В итоге ничего особенного не изменится. Как и прежде можно будет запускать любую созданную нами команду:

php cli.php cache clear

Но разница всё же будет. Попробуем выполнить исходный скрипт и наш без указания имени команды:

php yiic.php
php cli.php

В первом случае в отчёте мы увидим список cache, message, migrate, shell, webapp. Во втором же будет отображаться только наша команда cache. Откуда же берутся все остальные?

Подключение сторонних команд

Если откроем файл framework/yiic.php, то найдём там строки:

$app = Yii::createConsoleApplication($config);
$app->commandRunner->addCommands(YII_PATH . '/cli/commands');
...
$app->run();

Именно здесь и происходит добавление в результирующий список всех имеющихся встроенных команд из папки framework/cli/commands перед запуском приложения вызовом $app->run(). Это удобно для работы с целыми папками. То же самое можно организовать и в нашем файле, но это требует изменения самого файла protected/yiic.php.

Давайте теперь создадим ещё одну команду:

class CalculateCommand extends CConsoleCommand
{
    public $dbConnection = '';
    public function run($args) {
        echo 'Calculate command with connection=' . $this->dbConnection . PHP_EOL;
    }
}

но поместим файл CalculateCommand.php не в protected/commands, а в protected/components и запустим стандартный входной скрипт для консольных команд yiic.php:

php yiic.php

Естественно, что команда calculate в списке не появится, так как Yii просмотрит protected/commands, а этот класс находится в другой папке. Доработаем параметры приложения, добавив в console.php секцию commandMap:

return array(
    'components' => array(
        'db' => array(...),
    ),
    'commandMap' => array(
        'calculate' => array(
            'class' => 'application.components.CalculateCommand',
            'dbConnection' => 'db',
        ),
    ),
);

Теперь при запуске

php yiic.php

мы увидим нашу команду в списке и сможем её выполнить.

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

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

Подводные камни

Запуск в командной строке имеет свою специфику. Рассмотрим некоторые трудности, с которыми можно столкнуться при написании консольных команд в Yii.

Глобальные переменные запроса

Как мы уже упоминали, в CLI-режиме некоторые HTTP-переменные массива $_SERVER, массивы $_SESSION и $_COOKIE будут неопределены. Действительно, в командной строке не работают сессии и cookies. При обращении к $_SERVER['REQUEST_URI'], $_SERVER['HTTP_METHOD'] напрямую или через Yii::app()->request можно получить пустые значения или ошибки. Поэтому нужно избегать их использования в общих компонентах, работающих как в веб-приложении, так и в консольном. Это ещё один серьёзный довод в пользу отделения пользовательских данных от бизнес-логики моделей и прочих компонентов.

Псевдоним webroot

При использовании загрузки файлов удобно определять корневую директорию сайта вызовом Yii::getPathOfAlias('webroot'). Расположение папки загрузок получить при этом достаточно легко:

$path = Yii::getPathOfAlias('webroot.upload');
$image = $path . DIRECTORY_SEPARATOR . $model->image;

Простым вызовом

echo Yii::getPathOfAlias('webroot.upload');

мы получаем путь

/home/site/public_html/upload

в соответствии с установленным как dirname($_SERVER['SCRIPT_FILENAME']) в конструкторе класса CApplication путём для webroot.

Если же мы сделаем то же самое в консольной команде, то увидим не то, что нам бы хотелось:

./upload

и абсолютные адреса файлов получить не удастся.

Всё из-за того, что $_SERVER['SCRIPT_FILENAME'] в консольном режиме содержит значение yiic.php без пути. Ну и с логической точки зрения при запуске в консоли изначально не может быть какого-либо корневого публичного пути.

Соответственно, если необходимо обрабатывать изображения в фоновом режиме (запуская периодически консольную команду по планировщику Cron), то нужно либо переписать все компоненты, работающие с файлами, с учётом невозможности получения корневого пути сайта webroot (что очень сложно), либо просто переопределить webroot вручную перед запуском команды:

<?php
Yii::setPathOfAlias('webroot', Yii::getPathOfAlias('application') . '/..');
 
class ImageCommand extends CConsoleCommand {
...
}

Если у вас папка protected вынесена из public_html, то нужно немного изменить адрес.

Псевдонимы модулей

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

Yii::import('blog.models.Post');

или

<?php $this->widget('blog.widgets.RecentPostsWidget'); ?>

При попытке импорта модели записи блога таким образом в консольной команде мы получим ошибку. Самый простой способ избавиться от неё – указание полного псевдонима пути:

Yii::import('application.modules.blog.models.Post');

Использование планировщика Cron

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

cd /home/site/public_html/protected && php yiic.php rating recalculate

Но мы хотим, чтобы она запускалась автоматически каждые 10 минут.

Делаем файл yiic исполняемым, создаём файл /etc/cron.d/site и добавляем в него строку:

0 */10 * * www-data cd /home/site/public_html/protected && yiic rating recalculate

или (если файл исполняемым не сделан) одну из двух:

0 */10 * * www-data cd /home/site/public_html/protected && /usr/bin/php yiic.php rating recalculate
0 */10 * * www-data /usr/bin/php -q /home/site/public_html/protected/yiic.php rating recalculate

Порой какая-либо команда может слишком долго ждать ответ от другого сервера или обрабатывать данные. Для таких долгих команд можно сделать так, чтобы пока не завершится предыдущий процесс новые не запускались. Это можно сделать с помощью утилиты flock:

0 * * * www-data /usr/bin/flock -xn /var/lock/rating.lock -c '/usr/bin/php -q /home/site/public_html/protected/yiic.php rating recalculate'

Теперь на время запуска будет создаваться блокирующий файл /var/lock/rating.lock. Пока не завершится породивший его процесс новые экземпляры команд запускаться не будут.

Что же дальше?

В текущем уроке мы познакомились с некоторыми нюансами использования консольных команд в PHP в общем и в Yii в частности. Теперь самое время прочесть статью на эту тему из официального руководства.

А пример как в консольном режиме можно настроить полностью автоматическую систему публикации программного кода сайта на сервер можно посмотреть в видео:

В следующей статье мы напишем команду минимизации, местами сильно упрощающую жизнь.

А от опытных разработчиков в комментариях хотелось бы узнать, какие «самодельные» консольные команды вы используете.

Другие статьи

Три программиста пишут код проекта. И с кодом у них нет проблем. Есть три рабочих машины, центральный репозиторий и главный рабочий сервер, берущий файлы из этого же репозитория. Работа кипит. у каждого на своём компьютере установлен PhpMyAdmin, что им позволяет время от времени вносить изменения в свою базу данных.

На прошлом уроке мы познакомились с консольным режимом в PHP и с консольными командами в Yii. Теперь пришла пора собрать вместе наши знания и перейти к практике. При разработке любых проектов удобно разделять CSS и JavaScript на отдельные файлы, но их обилие в секции HEAD заметно уменьшает скорость загрузки веб-страницы. Итак, поехали!

В этот знаменательный день, 15-е ноября, автор данного сайта справляет очень хороший праздник. В общем, у меня отличное настроение и хочется всем дарить подарки. В связи с данным событием на эти два дня объявляю маленький конкурс. Присоединяйтесь!

В первой части мы с вами рассмотрели работу системы маршрутизации, изучили некоторые нюансы и научились правильно составлять шаблоны адресов. В этой же части мы попробуем перейти непосредственно к пониманию работы и нюансам использования менеджера адресов в Yii Framework.

Комментарии

 

script

Спасибо. О многом не знал.
У вас редко появляются статьи. Я знаю как их трудно писать.
Думаю не плохо было бы сделать раздел коротких заметок. Это позволило бы чаще обновлять блог и получать новых посетителей.

Ответить

 

Tom

А как эти консольные команды выполнять на виртуальных хостингах? Через exec ?

Вообще вот в статье про миграции вы пишете как ими управлять.
Например я из админки сайта вижу список непримененных миграций. И в админке жму - "Применить". Скрипт же должен запустить консольную команду. Все тут получиться?

Ответить

 

Дмитрий Елисеев

Хостинг TimeWeb, например, кроме FTP в панели предоставляет SSH доступ. Им и пользуюсь. А так да, можно exec() или system(), если они доступны.

Ответить

 

BSCheshir

Столкнулся с обратной задачей: на бесплатном плане у hostinger.ru доступен только мастер "Создать новую Cron-задачу", где прописан префикс "Выполнить команду php -f /home/u123456789/". Позволяет дополнить только именем файла, без каких либо параметров. Не подскажете, как скормить консольному приложению на yii параметры, подключив его в php-файле?

Ответить

 

BSCheshir

Покопался по исходникам yii: по порядку вызова передача параметров запуска приложения осуществляется
в методе processRequest() класса CConsoleApplication, где массив $_SERVER['argv'] передаётся в метод
run() класса CConsoleCommandRunner. (Первый параметр - название команды, т.е. ключ -f неверно задаёт порядок)
В дальнейшем используется fgets(STDIN), следовательно, теоретически, достаточно подменить $_SERVER['argv']
и подключить файл (Предполагается, что задача для cron лежит на одном уровне с public_html).

$_SERVER['argv']=Array($_SERVER['argv'][0],'migrate','--interactive=0','mark','000000_000000');
require_once(dirname(__FILE__).'/public_html/projectsubfolder/protected/cron.php');


Возможно, в статье следует уточнить, что yii работает с $_SERVER['argv'], а не $argv и $argc

Ответить

 

Сашка

Как вариант можно вспомнить об exec()

т.е. пишем:

exec('php /full-dir-to-script/protected/yiic.php sitemap')

ну и помним что exec() не всегда разрешена из-за безопасности..

Ответить

 

alexphp

В коде CacheCommand в строке

echo 'Testing of ' . get_class(Yii::app()->cache) . PHP_EOL

добавьте точку после PHP_EOL.

Ответить

 

Дмитрий Елисеев

Добавил. Спасибо!

Ответить

 

Alexander

В классе CacheCommand ругается на

empty(Yii::app()->cache->get('test'))

В api посмотрел: get() method

(Return- the value stored in cache, false if the value is not in the cache, expired or the dependency has changed.)

Изменил на:

Yii::app()->cache->get('test') === false

-Вроде работает. Причем на mac и linux ошибку не выдает, а в freebsd возвращает

Ответить

 

Andrewkha

Простой и глупый вопрос.

Написал консольный экшн (yii2), который возвращает какую-то цифирь. Куда она записывается? Как ее посмотреть? И как заставить отправлять письмо администратору?

Ответить

 

Дмитрий Елисеев

Смотря куда возвращает. Если возвращаете через return; то это код завершения. Если команда выполняется по Cron, то он запишет это в лог как ошибку, если вернётся что-то отличное от нуля. А если хотите посмотреть при ручном запуске в консоли, то выводите всё через echo.

Ответить

 

Andrewkha

Спасибо. Еще короткий вопрос. Можно ли как-то в ходе выполнения приложения делать проверку, в каком режиме оно запущено - в консольном или веб? В одной из моделей в beforeSave нужно делать одну вещь только при запуске в веб режиме

Ответить

 

Дмитрий Елисеев

Можно проверить класс приложения:

If (Yii::$app instanceof WebApplication) {
   ...
}

Ещё можно использовать сценарии или явно присваивать значение в контроллере.

Ответить

 

Andrewkha

Спасибо. Ну еще немного Вас помучаю, если не против :)
Использую консольное приложение в связке с SwiftMailer. Конфигурация SM одинакова для веб приложения и консольного. Из веб приложения все отлично работает, в консольном получаю ошибку
Exception 'Swift_TransportException' with message 'Connection could not be established with host smtp.googlemail.com [ #0]'

Есть ли какая-то тонкость настройки SM для работы с консолью?

Ответить

 

Andrewkha

Видимо, проблема не в SM и не Yii, а в моем QNAP, на котором хостится сайт. С тестовой машинки все отрабатывает.
Но поскольку Unix/Linux знаю очень плохо, буду благодарен, если есть идеи, куда копать, в каком компоненте/конфигурации может быть проблема. Хотя бы идея, что гуглить...

Ответить

 

Дмитрий

Дмитрий доброго времени суток.
Подскажите как протестировать консольное приложение в PhpStorm.
Тестирование вебприложения не составляет труда, вызвал дебагер и поставил точку останова.
А как быть с консольным? Спасибо.

Ответить

 

Дмитрий Елисеев

Это «отладить», а не «протестировать». А так ответ есть в руководстве:

php -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=127.0.0.1 -dxdebug.remote_connect_back=0 yii my/command
Ответить

 

Дмитрий

Спасибо огромное Дмитрий. Точно, "отладить" ;-) !

Ответить

Оставить комментарий

Войти | Завести аккаунт


(никто не увидит)



Можно использовать теги <p> <ul> <li> <b> <i> <a> <pre>