1С Битрикс · 8 мин чтения

Командная PHP-строка в Битриксе: как выполнить код из админки без FTP

Командная php строка битрикс это страница в административном разделе, где вводишь PHP-код, жмёшь кнопку и получаешь результат уже в контексте загруженного ядра. Не нужно создавать файл, заливать его по FTP и потом не забыть удалить. Я пользуюсь ей, когда нужно быстро проверить, что лежит в инфоблоке, сбросить кэш или выставить опцию, а доступа к серверу у меня нет или он неудобен. Ниже собрал, как её открыть, что в ней рабочее, где она опасна и когда лучше взять другой инструмент.

Где находится PHP-консоль в админке Битрикса

Страница открывается по адресу /bitrix/admin/php_command_line.php на вашем домене, обычно с параметром языка, например ?lang=ru. Нужна авторизация под пользователем с правами администратора. Если страница не открывается, значит у учётной записи не хватает прав на административный раздел или доступ к ней закрыли на уровне хостинга или правил веб-сервера.

В поле вводится чистый PHP без открывающего тега <?php. Код исполняется на стороне сервера в окружении уже подключённого ядра, поэтому классы CIBlockElement, CUser, COption и D7-таблицы доступны сразу. Модули вроде iblock или sale иногда нужно подключить вручную, как и в обычном скрипте:

\Bitrix\Main\Loader::includeModule('iblock');
echo PHP_VERSION . ' / ' . SM_VERSION;

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

Что важно знать про сам механизм. Код выполняется в рамках обычного HTTP-запроса, значит действуют те же ограничения по времени выполнения и памяти, что и у любой страницы. Тяжёлую миграцию на десятки тысяч элементов отсюда запускать нельзя, скрипт оборвётся на середине.

Что можно сделать через PHP-консоль без доступа по FTP

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

Прочитать данные из инфоблока

Классическая ситуация: редактор говорит, что элемент не появился на сайте. Смотрю последние пять элементов инфоблока, их активность и название:

\Bitrix\Main\Loader::includeModule('iblock');
$res = CIBlockElement::GetList(
    ['ID' => 'DESC'],
    ['IBLOCK_ID' => 5],
    false,
    ['nTopCount' => 5],
    ['ID', 'IBLOCK_ID', 'NAME', 'ACTIVE']
);
while ($el = $res->Fetch()) {
    echo $el['ID'] . ' | ' . $el['NAME'] . ' | ' . $el['ACTIVE'] . '<br>';
}

Замените 5 на ID своего инфоблока. В выборке я всегда указываю IBLOCK_ID и ID, как требует документация к CIBlockElement::GetList, иначе свойства могут отдаваться некорректно.

Для пользователей я беру D7, как и рекомендует документация, вместо старого CUser::GetList:

$rows = \Bitrix\Main\UserTable::getList([
    'select' => ['ID', 'LOGIN', 'EMAIL', 'ACTIVE'],
    'filter' => ['=ACTIVE' => 'Y'],
    'order' => ['ID' => 'DESC'],
    'limit' => 5,
])->fetchAll();
foreach ($rows as $r) {
    echo $r['ID'] . ' | ' . $r['LOGIN'] . ' | ' . $r['EMAIL'] . '<br>';
}

Метод getList возвращает объект результата, а fetchAll() превращает его в массив строк. Если вы пользуетесь старым CUser::GetByID, помните, что он тоже возвращает объект CDBResult, а не массив, и до массива нужно дойти через ->GetNext().

Сбросить кэш и проверить опции

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

BXClearCache(true);
echo 'cache cleared';

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

Опции читаются и пишутся через COption. Например, посмотреть, включена ли проверка агентов на хите:

echo COption::GetOptionString('main', 'check_agents', 'Y');

Этими же вызовами вендор предлагает отключить выполнение агентов на хите при переносе на cron: в документации есть пример с COption::SetOptionString для agents_use_crontab и check_agents, после которого в консоли должно получиться «NN». Сам перенос на cron на этом не заканчивается, дальше правится dbconn.php и создаётся свой файл для crontab, так что одной консолью там не обойтись.

Вернуть доступ в админку

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

$user = new CUser;
$ok = $user->Update(1, [
    'PASSWORD' => 'НовыйПароль123!',
    'CONFIRM_PASSWORD' => 'НовыйПароль123!',
]);
echo $ok ? 'ok' : $user->LAST_ERROR;

Здесь 1 это ID пользователя. Пароль в строке остаётся в истории браузера и в логах запросов, поэтому после входа его нужно сменить ещё раз уже штатно, через профиль.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Чем командная строка PHP отличается от FTP, SSH и файла в /local

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

Способ Нужен доступ к серверу Долгие задачи Остаётся файл
PHP-консоль в админке Нет, только вход в админку Нет, лимиты веб-запроса Нет
Скрипт по FTP Да, учётные данные FTP Нет, тоже веб-запрос Да, его надо удалять
Скрипт из CLI по SSH или через планировщик хостинга Да, SSH или cron в панели Да Да, лучше держать вне webroot

Скрипт по FTP хуже по одной причине: забытый файл в корне сайта остаётся доступным по прямой ссылке. Я встречал на проектах копии вида index.php.bak рядом с оригиналом, которые веб-сервер отдавал как есть, а PHP-копия принимала POST в обход исправленной логики. Консоль такого следа не оставляет.

Для долгих задач я поднимаю ядро из командной строки хостинга. Скрипт кладётся вне public_html, в начале задаётся $_SERVER['DOCUMENT_ROOT'], определяются константы NO_KEEP_STATISTIC, NOT_CHECK_PERMISSIONS и BX_CRONTAB, затем подключается /bitrix/modules/main/include/prolog_before.php. На одном shared-хостинге ядро 22.0.300 падало под PHP 8.0, 8.1 и 8.2 и поднялось только под бинарником PHP 7.4, поэтому первым делом я пробую другие версии PHP на хостинге, а не пишу прямой SQL.

Риски: чем опасна PHP-консоль на рабочем сайте

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

Ошибка в строке бьёт по боевым данным

Код исполняется сразу, без предпросмотра и отката. Неверный фильтр в CIBlockElement::Update или Delete применится ко всем подходящим записям. Перед любой записывающей операцией я делаю бэкап базы и сначала запускаю тот же код только на чтение, чтобы посмотреть, сколько записей он затронет. Для создания свойств и элементов я использую API (CIBlockProperty::Add, CIBlockElement::Add), а не прямой INSERT: после прямой вставки в таблицы свойств пришлось вручную чистить кэш метаданных инфоблоков.

Вывод объектов раскрывает пароль базы

Это самая неприятная ловушка. Если сделать print_r, var_dump или json_encode от результата CDBResult или CIBlockResult, в вывод попадёт вложенное подключение к базе с полем DBPassword. Пароль MySQL окажется на экране, в скриншоте или в вашей переписке с заказчиком. Поэтому я вывожу только скалярные поля из Fetch(), как в примерах выше, а файлы .settings.php и dbconn.php в консоли не печатаю вообще.

Консоль это готовая точка для захвата сайта

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

Типичные ошибки при работе с командной PHP-строкой

На практике чаще всего ломается не сам Битрикс, а привычки, перенесённые из обычных скриптов.

  • Забытое подключение модуля. Без \Bitrix\Main\Loader::includeModule('iblock') класс CIBlockElement может оказаться недоступным, и вы получите ошибку вместо результата.
  • Строка с открывающим тегом. Добавленный в начале <?php ломает выполнение, потому что код вводится без тегов.
  • Ожидание массива вместо объекта. Методы вроде GetList возвращают объект результата, массив получается только через Fetch() или fetchAll().
  • Проверка записи по возвращаемому значению. CIBlockElement::SetPropertyValuesEx ничего не возвращает, и условие вида if (!CIBlockElement::SetPropertyValuesEx(...)) печатает ложную ошибку при записанных данных. Результат нужно проверять повторной выборкой.
  • Агент или событие, которое не сработало, потому что код выполнен в окружении без пользователя. Переменной USER в агентах нет, и авторизация через Authorize там не работает, а консоль это обычный веб-запрос с текущим пользователем, так что поведение у них разное.

Если код правит SEO-поля элемента, после CIBlockElement::Update с IPROPERTY_TEMPLATES нужно сбросить вычисленные значения через (new \Bitrix\Iblock\InheritedProperty\ElementValues($iblockId, $id))->clearValues(), иначе страница продолжит отдавать старый title.

Когда одной консоли мало и нужен программист

Консоль подходит для разовых проверок и коротких правок в несколько строк. Как только задача становится регулярной, ей нужны логи, откат, проверка на тестовой копии и нормальное место в коде, и разумнее оформить её в агент, обработчик события или файл в каталоге /local. Вендор для кастомизации тоже ведёт в /local: при обработке папок приоритет у /local перед /bitrix, и правки в штатных каталогах пропадают при обновлениях.

Если у вас нет времени разбираться с ядром, я занимаюсь доработкой и поддержкой 1С-Битрикс, цена от 3 000 ₽ в час, мелкую задачу можно взять от одного часа. Обычно в такой час входит диагностика через консоль, исправление и чистка кэша, после чего я показываю, что именно было сделано.

Условия и возможности 1С-Битрикса меняются от версии к версии, поэтому перед запуском на боевом сайте я сверяюсь с документацией на dev.1c-bitrix.ru.

Частые вопросы

Где находится командная PHP-строка в Битриксе?

Страница открывается по адресу /bitrix/admin/php_command_line.php на вашем домене под администратором. Если страница недоступна, проверьте права пользователя и правила доступа к административному разделу на хостинге.

Нужно ли вводить открывающий тег PHP?

Нет. Код вводится без <?php, и с тегом он не выполнится. Результат выводится через echo, а объекты лучше не печатать целиком, чтобы не раскрыть данные подключения к базе.

Можно ли запускать через консоль тяжёлые скрипты?

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

Безопасно ли оставлять доступ к консоли подрядчику?

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

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно