Php отладка на сервере

Удаленная отладка с использованием xdebug port forwarding

Каждый разработчик время от времени сталкивается с непонятными ошибками. Как правило, их причина неочевидна и чтобы их пофиксить, нужно детально понять, что происходит в коде. Модуль xdebug — инструмент для профессионального поиска ошибок. Когда выполнение кода доходит до точки останова, xdebug присоединяется к IDE, которая слушает порт (по умолчанию 9000). Эта схема хорошо работает на localhost. Если вы находитесь в прямой видимости удаленного сервера, то можно прописать в конфиге xdebug ваш ip, и производить отладку аналогично. Но если компьютер разработчика находится за NAT, то прямой доступ с сервера к нему невозможен.
Я давно использую xdebug на localhost, но, разобравшись с port forwarding, научился отлаживать на удаленном сервере и решил написать инструкцию, которая может быть полезной каждому разработчику, а главное — она работает.
В качестве IDE я использовал PhpStorm, браузер Chrome, ОС Ubuntu. Port forwarding без проблем работает и в windows.

Настройки сервера

sudo apt-get install php5-xdebug sudo nano /etc/php5/conf.d/xdebug.ini 

Опция xdebug.idekey может быть PhpStorm1, netbeans-xdebug, XDEBUG_ECLIPSE, в зависимости от IDE, или пустым.

zend_extension=/usr/lib/php5/20100525/xdebug.so xdebug.profiler_enable = 0 xdebug.remote_enable = 1 xdebug.remote_host = 127.0.0.1 xdebug.remote_port=9000 xdebug.remote_handler=dbgp xdebug.idekey=PhpStorm1 

В итоге вывод phpinfo() должен содержать информацию о xdebug:

Настройки клиента

Chrome Xdebug helper

Если планируется использовать idekey, то для Chrome нужно поставить Xdebug helper.
В настройках расширения параметр IDE key нужно указать PhpStorm1 и в Domain filter вписать host. При отладке в адресной строке нужно нажимать Debugging Enabled.

Настройка PhpStorm

File -> Settings -> xdebug. Port 9000. На панели Edit debug configuration -> Add New Configuration -> PHP Web Application
Нужно указать Name, Start URL, создать новый сервер. У сервера указать Name, Host, Port, path mapping. Сохранить все.

Теперь можно поставить точку останова и нажать на кнопку debug, чтобы IDE начала слушать порт. Запустится браузер со страницей Server + Start URL, а в параметре будет XDEBUG_SESSION_START, который определяет идентификатор сессии. Не теряйте его при отладке.

Port forwarding

Xdebug стучится в порт, который слушает IDE. Если мы хотим отлаживать удаленный сервер и сидим за NATом, то наши порты недоступны. Оптимальный вариант — перенаправление удаленного порта на локальный с помощью ssh. Для работы под windows нужно установить Cygwin с пакетом ssh.

$ ssh -R 9000:127.0.0.1:9000 user@server 
Проверка port forwarding

Нужно попробовать установить связь на удаленной машине на ее 9000 порт. Если все сделано правильно, то соединение будет установлено, по факту, с нашим локальным портом.
Успешеный коннект:

> telnet 127.0.0.1 9000 Trying 127.0.0.1. Connected to 127.0.0.1. Escape character is '^]'. 
telnet: Unable to connect to remote host: Connection refused - Перенаправление не работает. Возможно проблема в антивирусе или файрволе. Connection closed by foreign host - IDE не слушает порт 

Источник

Читайте также:  Python tkinter file types

Отладка PHP приложений на удаленном хосте при помощи XDebug и vim в Linux

В PHP приложениях отладка при помощи var_dump, debug_backtrace и прочих полезных функций не всегда удобна, и возникает потребность в полноценном отладчике. Эта статья — для тех, кто по каким-либо причинам не хочет использовать IDE, поддерживающие отладку PHP приложений из коробки, вроде NetBeans или PhpStorm, а хочет использовать для этих целей vim, и при этом отладка происходит на удаленном хосте.

Для vim существует плагин «DBGp client», но он позволяет нормально отлаживать только в случае, когда пути до всех файлов на удаленной и на локальной машинах одинаковые. Например, если локальной машине у вас есть:
/home/user/application/
/home/user/framework/

а на удаленной машине они расположены в:
/var/www/html/application/
/var/www/framework/

то отладить приложение при помощи «DBGp client» не получится, так как он ничего не знает о другом расположении исходников.

  1. Кратко — настройку всего необходимого для удаленной отладки приложения.
  2. Модификацию плагина для поддержки различных путей.
  3. Кратко — использование отладчика.

Установка

Настраиваем vim на локальном хосте

Скачайте и установите плагин:
$ cd ~/.vim
$ wget www.vim.org/scripts/download_script.php?src_id=7285 -O debugger.zip
$ unzip debugger.zip
$ rm debugger.zip

Внимание: vim должен быть собран с поддержкой python, проверить это можно при помощи «:version«, в выводе должна быть строка «+python».

Устанавливаем и настраиваем Xdebug на удаленном хосте

Установите расширение Xdebug любым удобным для вас способом. Например, на Debian Squeeze это делается просто:
# apt-get install php5-xdebug
А в общем случае, лучше почитать официальную инструкцию по установке.

Настройте подключение к локальному debug-клиенту — для этого в php.ini пропишите следующие строчки, заменив 192.168.1.110 на IP локальной машины (при необходимости порт тоже можно перенастроить):
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_host = 192.168.1.110

Читайте также:  Python hello world урок
Настраиваем соответствие файлов

Идея простая — при отправке запроса дебагеру (например, на установку breakpoint), мы должны преобразовывать путь на локальном хосте в путь на удаленном хосте, и наоборот, при получении информации от дебагера (например, о том что сейчас он находится на какой-то строке какого-то файла), мы должны сделать обратное преобразование.
Дописываем в конец файла debugger.py следующий код:

class FileMapping: def __init__(self, mapping_file): self.local_to_remote = <> self.remote_to_local = <> mapping = open(mapping_file, 'r') for line in mapping: local, remote = line.split(' ') local = local.strip() remote = remote.strip() if not (local in self.local_to_remote): self.local_to_remote[local] = [] self.local_to_remote[local].append(remote) if not (remote in self.remote_to_local): self.remote_to_local[remote] = [] self.remote_to_local[remote].append(local) def local_to_remote_file(self, local): for local_path in self.local_to_remote.keys(): if local.startswith(local_path): # use the first mapping as we don't know which one we should take remote_path = self.local_to_remote[local_path][0] return remote_path + local[len(local_path):] def remote_to_local_file(self, remote): for remote_path in self.remote_to_local.keys(): if remote.startswith(remote_path): for local_path in self.remote_to_local[remote_path]: local = local_path + remote[len(remote_path):] # use the first existing file if os.path.exists(local): return local return None file_mapping = FileMapping('/home/alexey/mapping') 

А в файл mapping (/home/alexey/mapping — замените на свой путь) записываем соответствие локальный и удаленных директорий, например:
/home/alexey/framework /var/www/framework
/home/alexey/application /var/www/html

Просматриваем код плагина в поисках мест, где от Xdebug приходят имена файла. В итоге, все они сводятся к вызову одного метода — set_srcview, в начало которого мы и добавляем изменение имени файла:

def set_srcview(self, file, line): """ set srcview windows to file:line and replace current sign """ file = file_mapping.remote_to_local_file(file) 

Теперь ищем места, где наоборот от debug-клиента к Xdebug передаются имена файлов. Таких мест два:
1. Класс Debugger, метод run, заменяем строку

'-t line -f ' + self.breakpt.getfile(bno) + ' -n ' + str(self.breakpt.getline(bno)) + ' -s enabled', \ 
'-t line -f ' + file_mapping.local_to_remote_file(self.breakpt.getfile(bno)) + ' -n ' + str(self.breakpt.getline(bno)) + ' -s enabled', \ 
'-t line -f ' + self.breakpt.getfile(bno) + ' -n ' + str(self.breakpt.getline(bno)), \ 
'-t line -f ' + file_mapping.local_to_remote_file(self.breakpt.getfile(bno)) + ' -n ' + str(self.breakpt.getline(bno)), \ 

Уже поправленный debugger.py можно взять тут.

Читайте также:  Php file access functions

Использование

Запускаем отладку

Чтобы начать отладку web-приложения, необходимо запустить vim и нажать .
Далее, в течение 5 секунд (ниже описано, как увеличить интервал), необходимо запустить какой-либо PHP скрипт, передав GET-ом переменную XDEBUG_SESSION_START со значением 1, например просто открыв соответствующую страницу в браузере, например:
webdev/debug.php?XDEBUG_SESSION_START=1
Альтернативно в php.ini можно задать переменную xdebug.remote_autostart. В таком случае, при запуске любого PHP скрипта, Xdebug будет пытаться подключиться к debug-клиенту.
Подробнее можно прочитать в официальной документации Xdebug.
В итоге должно получиться что-то вроде этого — должен открыться скрипт, который вы запустили:

  1. WATCH WINDOW — просмотр контекста
  2. HELP WINDOW — краткое описание возможностей
  3. STACK WINDOW — стек вызова функций
  4. TRACE WINDOW — лог общения debug-клиента c Xdebug, полезно посмотреть если отладка не заработала
Настройка под себя

и заменив 5 на нужное вам количество секунд.
Комбинации клавиш задаются в debugger.vim, например себе я переназначил на нажатие «,dr»:
map ,dr :python debugger_run()
Текст в HELP WINDOW можно поменять в классе HelpWindow, методе on_create.

Навигация по коду
  • Step into () — шаг с заходом внутрь функций.
  • Step over () — шаг без захода внутрь функций.
  • Step out () — выход из функции по стеку вверх.
  • Run () — продолжить выполнение до следующего breakpoint.
  • Stack up (:Up) — переход по стеку вверх (смотрите STACK WINDOW).
  • Stack down (:Dn) — переход по стеку вниз (смотрите STACK WINDOW).
Просмотр текущего состояния
  • Property get () — получить значение переменной (надо поставить курсор на нужную переменную и нажать ).
  • Context get () — получить весь текущий контекст (грубо говоря, все переменные, доступные в данном контексте).
  • Eval (,e) — выполнить произвольное выражение в текущем контексте и получить его значение.

Установка breakpoints

Toggle breakpoint (:Bp) — установить breakpoint в текущей строке, или удалить, если он уже есть.
На скриншоте — зеленая строка — это строка с breakpoint, красная — это текущая строка:

Resize

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

Источник

Оцените статью