Как проверить php страницу на ошибки

Вчера всё работало, а сегодня не работает / Код не работает как задумано

или

Debugging (Отладка)


В чем заключается процесс отладки? Что это такое?

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


Важное замечание:

Есть много IDE и редакторов кода, которые позволяют производить отладку. Процесс настройки в них у всех различается. Поэтому стОит обратиться к документации по настройке отладки для непосредственно той среды разработки и той версии, в которой работаете именно ВЫ.

На текущий момент будет рассмотрен пример с PHPStorm 2017.


Подготовка

Для начала необходимо, чтобы в PHP имелась библиотека для отладки под названием xdebug. Если её еще нет, то надо установить.

ВАЖНО! Для очень новых версий PHP (например 8), требуется и новый xdebug, а он, в свою очередь, работает на порту 9003. Не пропустите указание правильного порта в IDE!! (Примерно в разделе PHP -> Debug -> Debug Port . Где точно — зависит от конкретной IDE)

Для WINDOWS:

скачать dll, например на xdebug.org.

Обычно все библиотеки лежат в папке ext внутри папки PHP. Туда и надо поместить dll.

Далее в php.ini прописываем настройки:

[Xdebug]
zend_extension="C:/server/php/ext/php_xdebug.dll" // <!-- тут свой путь до dll!!! Это для среды Windows. 
; Для Linux путь должен быть что-то типа zend_extension=/usr/lib/php/20151012/xdebug.so 
xdebug.default_enable = 1
xdebug.remote_enable = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "localhost"
xdebug.remote_port = 9000
xdebug.auto_trace = 0

Перезагружаем сервер, на всякий случай.

Для UBUNTU:

  • sudo apt update ИЛИ sudo apt-get update

  • sudo apt install php-xdebug или если нужнен отладчик для конкретной версии PHP, то sudo apt install php7.0-xdebug где 7.0 указывается версия PHP

  • sudo nano /etc/php/7.0/mods-available/xdebug.ini

    вписываем строки:

     zend_extension=/usr/lib/php/20151012/xdebug.so
     xdebug.remote_autostart = 1
     xdebug.remote_enable = 1
     xdebug.remote_handler = dbgp
     xdebug.remote_host = 127.0.0.1
     xdebug.remote_log = /tmp/xdebug_remote.log
     xdebug.remote_mode = req
    

    Примечание: каталог 20151012, скорее всего, будет другим. cd в /usr/lib/php и проверьте, в каком каталоге в этом формате находится файл xdebug.so, и используйте этот путь. 7.0 — тоже отличается, в зависимости от того, какая версия у вас используется

  • Перезагружаем сервер, на всякий случай.


Теперь если в файле .php написать phpinfo(); то можно будет увидеть в самом низу такую картину:

введите сюда описание изображения

Открываем PHPStorm

  • нажимаем create project from existing files
  • выбираем Web server is installed locally, source files are located under its document root
  • выбираем папку с файлами, и нажав вверху кнопку «Project Root» помечаем папку как корень проекта
  • нажимаем «Next»
  • нажимаем Add new local server

введите сюда описание изображения

  • вводим имя сервера любое и Web Server root URL. В рассматриваемом примере это http://localhost/testy2

введите сюда описание изображения

  • нажимаем «Next» и затем «Finish»

Запуск

Для начала в левой части панели с кодом на любой строке можно кликнуть ЛКМ, тем самым поставив точку останова (breakpoint — брейкпойнт). Это то место, где отладчик автоматически остановит выполнение PHP, как только до него дойдёт. Количество breakpoint’ов не ограничено. Можно ставить везде и много.

введите сюда описание изображения

Если кликнуть ПКМ и во всплывающем меню выбрать Debug (или в верхнем меню — RunDebug), то при первом запуске PHPStorm попросит настроить интерпретатор. Т.е. надо выбрать версию PHP из папки, где он лежит, чтобы шторм знал, какую версию он будет отлаживать.

введите сюда описание изображения

Теперь можно нажать Debug!!!

В данном случае, т.к. функция вызывается сразу на той же странице, то при нажатии кнопки Debug — отладчик моментально вызовет функцию, выполнение «заморозится» на первом же брейкпойнте. В ином случае, для активации требуется исполнить действие, при котором произойдет исполнение нужного участка кода (клик на кнопку, передача POST-запроса с формы с данными и другие действия).

введите сюда описание изображения

Цифрами обозначены:

  1. Стэк вызовов, все вложенные вызовы, которые привели к текущему месту кода.
  2. Переменные. На текущий момент строки ниже номера 3 ещё не выполнились, поэтому определена лишь $data
  3. Показывает текущие значения любых переменных и выражений. В любой момент здесь можно нажать на +, вписать имя любой переменной и посмотреть её значение в реальном времени. Например: $data или $nums[0], а можно и $nums[i] и item['test']['data'][$name[5]][$info[$key[1]]] и т.д. На текущий момент строки ниже номера 3 ещё не выполнились, поэтому $sum и $output обозначены красным цветом с надписью «cannot evaluate expression».

Процесс

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

введите сюда описание изображения

Show Execution Point (Alt+F10) — переносит в файл и текущую линию отлаживаемого скрипта. Например, если файлов много, решили посмотреть что в других вкладках, а потом забыли где у вас отладка :)

Step Over (F8) — делает один шаг, не заходя внутрь функции. Т.е. если на текущей линии есть какая-то функция, а не просто переменная со значением, то при клике данной кнопки, отладчик не будет заходить внутрь неё.

Step Into (F7) — делает шаг. Но в отличие от предыдущей, если есть вложенный вызов (например функция), то заходит внутрь неё.

Step Out (Shift+F8) — выполняет команды до завершения текущей функции. Удобно, если случайно вошли во вложенный вызов и нужно быстро из него выйти, не завершая при этом отладку.

Rerun (Ctrl+F5) — перезапускает отладку.

Resume Program(F9) — продолжает выполнение скрипта с текущего момента. Если больше нет других точек останова, то отладка заканчивается и скрипт продолжает работу. В ином случае работа прерывается на следующей точке останова.

Stop (Ctrl+F2) — завершает отладку.

View Breakpoints (Ctrl+Shift+F8) — просмотр всех установленных брейкпойнтов.

Mute Breakpoints — отключает брейкпойнты.

Итак, в текущем коде видно значение входного параметра:

  • $data = "23 24 11 18" — строка с данными через пробел
  • $nums = (4) ["23", "24", "11", "18"] — массив, который получился из входной переменной.

введите сюда описание изображения

Если нажмем F8 2 раза, то окажемся на строке 7; во вкладках Watches и Variables и в самой странице с кодом увидим, что переменная $sum была инициализирована и её значение равно 0.

Если теперь нажмем F8, то попадем внутрь цикла foreach и, нажимая теперь F8, пока не окончится цикл, можно будет наблюдать на каждой итерации, как значения $num и $sum постоянно изменяются. Тем самым мы можем проследить шаг за шагом весь процесс изменения любых переменных и значений на любом этапе, который интересует.

Дальнейшие нажатия F8 переместят линию кода на строки 11, 12 и, наконец, 15.


Дополнительно

Если нажать на View Breakpoints в левой панели, то можно не только посмотреть все брейкпойнты, но в появившемся окне можно еще более тонко настроить условие, при котором на данной отметке надо остановиться.
В функции выше, например, нужно остановиться только когда $sum превысит значение 20.

введите сюда описание изображения

Это удобно, если останов нужен только при определённом значении, а не всегда (особенно в случае с циклами).

How to use the free code checker

Code

Copy and paste your PHP code into the editor.

Language

Select your language from the dropdown.

Check

Click the Check code button.

Improve

Use the results to improve your PHP code.

Get your PHP code bug-free and secure right from the IDE

This free code checker can find critical vulnerabilities and security issues in PHP code bases with a click. To take your application security to the next level, we recommend using Snyk Code for free right from your IDE.

Improved PHP code security powered by Snyk Code

This free web based PHP code checker is powered by Snyk Code. Sign up now to get access to all the features including vulnerability alerts, real time scan results, and actionable fix advice within your IDE.

Human-in-the-Loop PHP Code Checker

Snyk Code is an expert-curated, AI-powered PHP code checker that analyzes your code for security issues, providing actionable advice directly from your IDE to help you fix vulnerabilities quickly.

Real-time

Scan and fix source code in minutes.

Actionable

Fix vulns with dev friendly remediation.

Integrated in IDE

Find vulns early to save time & money.

Ecosystems

Integrates into existing workflow.

More than syntax errors

Comprehensive semantic analysis.

AI powered by people

Modern ML directed by security experts.

In-workflow testing

Automatically scan every PR and repo.

CI/CD security gate

Integrate scans into the build process.

Frequently asked questions

Если у вас сайт на PHP, даже самый простой, время от времени в его скриптах могут возникать ошибки. Это может привести к различным неприятным последствиям, от некорректной работы некоторых компонентов сайта (например, формы обратной связи), до недоступности сайта целиком. Как самостоятельно распознать тип ошибки PHP и понять, что с ней делать дальше?

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

error 500

Как обнаружить ошибку PHP на сайте

1. Встроенными средствами браузера

Итак, если на сайте вместо привычной страницы ничего не отображается (вы видите “пустую страницу”), то, вероятнее всего, в одном из скриптов возникла ошибка. В этом можно убедиться, воспользовавшись встроенными «Инструментами разработчика» вашего браузера. В каждом браузере они могут называться немного по-разному, но суть от этого не меняется.

Например, в браузере Google Chrome это вкладка Dev Tools (или «Инструменты разработчика»). В Mozilla Firefox — это расширение Firebug  (его нужно установить отдельно в меню Adds On) или же вкладка Developer.

Внутри «Инструментов разработчика» нас интересует вкладка, которая называется Network (или Net, или каким-то похожим образом).

Если на странице сайта присутствует ошибка, в этой вкладке вы увидите код ответа 500 (“Internal Server Error”).Ошибка 505 server error

2. Если вывод сообщений об ошибках в браузер отключен

Случается, что вывод сообщений об ошибках в браузер отключён. Чтобы сообщение об ошибке отображалось в браузере, достаточно добавить в файл .htaccess в корневой директории сайта следующую строку:

php_value display_errors on

Файл .htaccess вы найдете по адресу: /home/login/domains/domain.ru/public_html/, где вместо login следует подставить логин вашего аккаунта, а вместо domain.ru — домен вашего сайта.

После сохранения файла .htaccess и обновления страницы вы сможете увидеть ошибку.

Если сайтом используется, например, CMS WordPress, то отображение ошибок можно также включить, заменив в файле wp-config.php:

 define(‘WP_DEBUG’, false);

на:

define(‘WP_DEBUG’, true);

3. С помощью журнала ошибок PHP

Иногда по различным причинам отображать ошибки в браузере нежелательно. В этом случае лучше всего сохранять их в какой-нибудь файл, например errors.log — журнал ошибок PHP. Для этого достаточно в файле .htaccess добавить следующую строку:

 php_value error_log /home/login/domains/domain.ru/log/errors.log

Здесь /home/login/domains/domain.ru/log/errors.log — это полный путь до файла, в который будут записываться ошибки PHP (если файла с таким именем нет, он будет создан автоматически при появлении ошибки).
Теперь, если мы снова зайдем на сайт с ошибкой (либо обновим страницу с ошибкой), то в errors.log будут записаны сообщения об ошибках.

Журнал ошибок PHP можно просмотреть, например, с помощью файлового менеджера в Панели управления, открыв файл errors.log:

03

Также можно открыть файл с ошибками и нажать кнопку “Включить автообновление”. Таким образом, новые записи в журнале можно просматривать в реальном времени.

 Расшифровка ошибок PHP

Как правило, в сообщении об ошибке достаточно подробно указано где именно и при выполнении какой части кода она возникла. Например:

Сообщение об ошибке PHP Здесь ошибка заключается в следующем:

Fatal error: Call to undefined function weblizar_get_options() in /home/login/domains/domain.ru/public_html/wp-content/themes/enigma/header.php on line 14

“Вызов неопределенной функции weblizar_get_options() в файле используемой на сайте темы enigma”.

Вероятнее всего, был поврежден один из файлов темы, поэтому можно восстановить только директорию темы ./wp-content/themes/enigma/ , а не всего сайта.

Что делать, в зависимости от типа ошибки PHP

Условно ошибки PHP можно разбить на 4 уровня:

  1. PARSE ERROR
  2. FATAL ERROR
  3. WARNING
  4. NOTICE
Parse Error

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

Что делать?

1. Если вы НЕ специалист в PHP, восстановите сайт из последней резервной копии на тот момент, когда сайт работал без ошибок.

2. Если вы специалист и самостоятельно вносили правки в код сайта, вы наверняка сможете отследить синтаксическую ошибку и исправить ее. Но проще все же воспользоваться пунктом 1.

Fatal Error и Warning

Возникают, если при выполнении кода какой-то его участок не может быть выполнен (например, попытка открыть несуществующий файл). Разница между 2-ым и 3-им уровнем в том, что при получении “критической ошибки” (FATAL ERROR) выполнение скрипта завершится, а при получении “предупреждения” (WARNING) — нет.

Что делать?

Восстановите сайт из последней доступной резервной копии на тот момент, когда он работал без ошибок.

Notice

К этому уровню ошибок относятся различные “замечания”, суть которых обычно отображена в тексте ошибки.

Что делать?

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

Частые ошибки PHP и их решение

 Fatal Error: Allowed Memory

Означает, что для выполнения какой-либо части кода PHP не хватает выделенной оперативной памяти. При этом лимит памяти ограничен какими-то директивами «изнутри» сайта (то есть где-либо в скриптах сайта, либо директивой memory_limit в файле .htaccess). Чтобы исправить это, измените данный лимит в большую сторону, например, в файле .htaccess.

Для этого найдите в .htaccess такую директиву:

php_value memory_limit 128M

Вместо 128M укажите желаемый размер ограничения. Обратите внимание, что символ «M» (латинская M) указывается слитно со значением.

Помните, что есть максимальные значения памяти, отведенной на выполнение скриптов PHP, предусмотенные вашим тарифом хостинга (например, на тарифах виртуального хостинга это 512 Мб, премиум — 1024 Мб). Уточните эти значения у вашего провайдера, если они не указаны явно.

Fatal Error: Out of memory

То же самое, что и предыдущая ошибка, с той разницей, что достигнут лимит памяти, заданный “снаружи”. Обратите внимание на параметр “Памяти на процесс, Мб, не более“ в условиях пользования нашим сервисом.

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

Также в этом случае мы советуем попробовать отключить акселераторы PHP, если они у вас подключены.

Unable to allocate memory for pool

Сайтам на аккаунте не хватает выделенной на тарифном плане памяти для акселераторов PHP.

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

Также, например, можно отключить акселератор APC для определенного сайта, добавив в файл .htaccess корневой директории следующую директиву:

php_value apc.cache_by_default off

Обычно имеет смысл оставлять APC для использования на самом посещаемом из ваших сайтов — это позволит использовать именно на нем преимущества акселератора, не заполняя его память данными с других, менее посещаемых сайтов.

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

Мы постараемся предложить возможные варианты решения.

Желаем вам приятной работы!

Время на прочтение
10 мин

Количество просмотров 12K

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

Пример гипотезы:

Функции strpos легко передать аргументы в неправильном порядке. 

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

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

Предпосылки

Вот уже несколько месяцев я занимаюсь поддержкой PHP линтера NoVerify (почитать о котором можно в статье NoVerify: линтер для PHP от Команды ВКонтакте).

Время от времени в команде появляются идеи для новых диагностик. Идей может быть много, а проверить хочется все, особенно если предложенная проверка нацелена на выявление критических дефектов.

Ранее я активно разрабатывал go-critic и ситуация была схожей, с той лишь разницей, что анализировались исходники на Go, а не на PHP. Когда я узнал об утилите gogrep, мой мир перевернулся. Как видно из названия, эта утилита имеет что-то общее с grep’ом, только поиск производится не по регулярным выражениям, а по синтаксическим шаблонам (позже объясню, что это значит).

Я уже не хотел жить без умного grep, поэтому в один вечер решил сесть и написать phpgrep.

Анализируемый корпус

Чтобы было увлекательно, мы сразу погрузимся в применение. Будем анализировать небольшой набор достаточно известных и крупных PHP проектов, доступных на GitHub.

В наш набор попали следующие проекты:

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

Итак, поехали!

Использование присваивания в качестве выражения

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

  • контекст ожидает результат логической операции (логическое условие) и
  • правая часть выражения не имеет побочных эффектов и является константной,

то, скорее всего, в коде ошибка.

Для начала, возьмём за «логический контекст» следующие конструкции:

  1. Выражение внутри «if ($cond)«.
  2. Условие тернарного оператора: «$cond ? $x : $y«.
  3. Условия продолжений циклов «while ($cond)» и «for ($init; $cond; $post)«.

В правой части присваивания мы ожидаем константы или литералы.

Зачем на нужны такие ограничения?

Начнём с (1):

# утилита поиска по синтаксическим шаблонам
# |     производим поиск по текущей директории (и всем дочерним)
# |     |
# |     |
phpgrep . 'if ($_ = []) $_' # 1
#         |               
#         |               
#         строка шаблона поиска

# Дополнительные 3 шаблона через отдельные запуски.
phpgrep . 'if ($_ = ${"const"}) $_' # 2
phpgrep . 'if ($_ = ${"str"}) $_'   # 3
phpgrep . 'if ($_ = ${"num"}) $_'   # 4

Здесь мы видим 4 шаблона, единственным различием между которыми выступает присваиваемое выражение (RHS). Начнём с первого из них.

Шаблон «if ($_ = []) $_» захватывает if, у которого любому выражению присваивается пустой массив. $_ сопоставляется с любым expression или statement.

         литерал пустого массива (RHS)
         |
if ($_ = []) $_
    |        |
    |        любое тело if'а, причём не важно, с {} или без
    любой LHS у присваивания

В следующих примерах используются более сложные группы const, str и num. В отличие от $_ они описывают ограничения на совместимые операции.

  • const — именованная константа или константа класса.
  • str — строковой литерал любого типа.
  • num — числовой литерал любого типа.

Этих шаблонов достаточно, чтобы добиться нескольких срабатываний на корпусе.

⎆ moodle/blocks/rss_client/viewfeed.php#L37:

if ($courseid = SITEID) {
    $courseid = 0;
}

Вторым срабатыванием в moodle стала зависимость ADOdb. В upstream библиотеки проблема всё ещё присутствует.

⎆ ADOdb/drivers/adodb-odbtp.inc.php#L741:

В этом фрагменте прекрасно многое, но для нас релевантна только первая строка. Вместо сравнения поля databaseType мы выполняем присваивание и всегда входим внутрь условия.

Ещё одно интересное место, где мы хотим выполнять действия только для «корректных» записей, но, вместо этого, выполняем их всегда и, более того, отмечаем любую запись как корректную!

⎆ moodle/question/format/blackboard_six/formatqti.php#L598:

// For BB Fill in the Blank, only interested in correct answers.
if ($response->feedback = 'correct') {
    // ...
}

Расширенный список шаблонов для этой проверки

Повторим то, что мы изучили:

  • Шаблоны выглядят как PHP-код, который они находят.
  • $_ обозначает «что угодно». Можно сравнить с . в регулярных выражениях.
  • ${"<class>"} работает как $_ с ограничением на тип элементов AST.

Стоит ещё подчеркнуть, что всё, кроме переменных, сопоставляется дословно (literally). Это значит, что шаблону «array(1, 2 + 3)» будет удовлетворять лишь идентичный по синтаксической структуре код (пробелы не влияют). С другой стороны, шаблону «array($_, $_)» удовлетворяет любой литерал массива из двух элементов.

Сравнение выражения с самим собой

Потребность сравнить что-либо с самим собой возникает очень редко. Это может быть проверка на NaN, но как минимум в половине случаев это ошибка copy/paste.

⎆ Wikia/app/extensions/SemanticDrilldown/includes/SD_FilterValue.php#L103:

if ( $fv1->month == $fv1->month ) return 0;

Справа должно быть «$fv2->month«.

Для выражения повторяющихся частей в шаблоне мы используем переменные с именами, отличными от «_«. Механизм повторений в шаблоне похож на обратные ссылки в регулярных выражениях.

Шаблон «$x == $x» будет как раз тем, что найдёт пример выше. Вместо «x» может использоваться любое имя. Здесь важно лишь то, чтобы имена были идентичны. Переменные шаблона, которые имеют различающиеся имена, не обязаны иметь совпадающее содержимое при захвате.

Следующий пример найден с помощью «$x <= $x«.

⎆ Drupal/core/modules/views/tests/src/Unit/ViewsDataTest.php#L166:

$prev = $base_tables[$base_tables_keys[$i - 1]];
$current = $base_tables[$base_tables_keys[$i]];
$this->assertTrue(
  $prev['weight'] <= $current['weight'] &&
  $prev['title'] <= $prev['title'], // <-------------- ошибка
  'The tables are sorted as expected.');

Дублирующиеся подвыражения

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

Один из моих любимцев — «$_ ? $x : $x«.
Это тернарный оператор, у которого true/false ветки идентичны.

⎆ joomla-cms/libraries/src/User/UserHelper.php#L522:

return ($show_encrypt) ? '{SHA256}' . $encrypted : '{SHA256}' . $encrypted;

Обе ветви дублируются, что подсказывает о потенциальной проблеме в коде. Если мы посмотрим на код вокруг, то сможем понять, что там должно было быть вместо этого. В угоду читабельности я вырезал часть кода и сократил название переменной $encrypted до $enc.

case 'crypt-blowfish':
    return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt);
case 'md5-base64':
    return ($show_encrypt) ? '{MD5}' . $enc : $enc;
case 'ssha':
    return ($show_encrypt) ? '{SSHA}' . $enc : $enc;
case 'smd5':
    return ($show_encrypt) ? '{SMD5}' . $enc : $enc;
case 'sha256':
    return ($show_encrypt) ? '{SHA256}' . $enc : '{SHA256}' . $enc;
default:
    return ($show_encrypt) ? '{MD5}' . $enc : $enc;

Я бы поставил на то, что коду необходим следующий патч:

- ($show_encrypt) ? '{SHA256}' . $encrypted : '{SHA256}' . $encrypted;
+ ($show_encrypt) ? '{SHA256}' . $encrypted : $encrypted;

Опасные приоритеты операций в PHP

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

Во многих языках программирования выражение «x & mask != 0» имеет интуитивный смысл. Если mask описывает какой-то бит, то данный код проверяет, что в x этот бит не равен нулю. К сожалению, для PHP это выражение будет вычисляться так: «x & (mask != 0)«, что почти всегда не то что вам нужно.

WordPress, Joomla и moodle используют SimplePie.

⎆ SimplePie/library/SimplePie/Locator.php#L254
⎆ SimplePie/library/SimplePie/Locator.php#L384
⎆ SimplePie/library/SimplePie/Locator.php#L412
⎆ SimplePie/library/SimplePie/Sanitize.php#L349
⎆ SimplePie/library/SimplePie.php#L1634

$feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0

SIMPLEPIE_FILE_SOURCE_REMOTE определён как 1, поэтому выражение будет эквивалентно:

$feed->method & (1 === 0)
// =>
$feed->method & false

Примеры шаблонов для поиска

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

Можно ли такие места найти с помощью phpgrep? Ответ: да!

phpgrep . '$_ == $_ ? $_ : $_ ? $_ : $_'
phpgrep . '$_ != $_ ? $_ : $_ ? $_ : $_'

Прелести проверки URL с помощью регулярных выражений

⎆ Wikia/app/maintenance/wikia/updateCentralInterwiki.inc#L95:

if ( preg_match( '/(wowwiki.com|wikia.com|falloutvault.com)/', $url ) ) {
    $local = 1;
} else {
    $local = 0;
}

По задумке автора кода, мы проверяем URL на совпадение с одним из 3-х вариантов. К сожалению, символ . не экранирован, что приведёт к тому, что вместо falloutvault.com мы можем завести себе falloutvaultxcom на любом домене и пройти проверку.

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

Найти такие места можно с помощью запуска phpgrep:

phpgrep . 'preg_match(${"pat:str"}, ${"*"})' 'pat~[^\].(com|ru|net|org)b'

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

Фильтры можно применять к любой переменной шаблона. Кроме регулярных выражений есть также структурные операторы = и !=. Полный список можно найти в документации.

${"*"} захватывает произвольное количество любых аргументов, поэтому нам можно не волноваться за опциональные параметры функции preg_match.

Дубликаты ключей в литерале массива

В PHP вы не получите никакого предупреждения, если выполните этот код:

<?php
var_dump(['a' => 1, 'a' => 2]);
// Результат: array(1) {["a"]=> int(2)}

Мы можем найти такие массивы с помощью phpgrep:

[${"*"}, $k => $_, ${"*"}, $k => $_, ${"*"}]

Этот шаблон можно расшифровать так: «литерал массива, в котором есть хотя бы два идентичных ключа в произвольной позиции». Выражения ${"*"} помогают нам описать «произвольную позицию», допуская 0-N элементов до, между и после интересующих нас ключей.

⎆ Wikia/app/extensions/wikia/WikiaMiniUpload/WikiaMiniUpload_body.php#L23:

$script_a = [
    'wmu_back' => wfMessage( 'wmu_back' )->escaped(),
    'wmu_back' => wfMessage( 'wmu_back' )->escaped(),
    // ...
];

В данном случае это не является грубой ошибкой, но мне известны случаи, когда дублирование ключей в крупных (100+ элементов) массивах несло как минимум неожиданное поведение, в котором один из ключей перекрывал значение другого.


На этом наш краткий экскурс на примерах окончен. Если вам хочется ещё, в конце статьи описано, как получить все результаты.

Что же такое phpgrep?

Большая часть редакторов и IDE используют для поиска кода (если это не поиск по специальному символу типа класса или переменной) обычный текстовой поиск — проще говоря, что-то вроде grep’а.

Вы вводите «$x«, находите «$x«. Вам могут быть доступны регулярные выражения, тогда вы можете пытаться, по сути, парсить PHP-код регулярками. Иногда это даже работает, если ищется что-то вполне определённое и простое — например, «любая переменная с некоторым суффиксом». Но если эта переменная с суффиксом должна быть частью другого составного выражения, возникают трудности.

phpgrep — это инструмент для удобного поиска PHP-кода, который позволяет искать не с помощью text-oriented регулярок, а с помощью syntax-aware шаблонов.

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

Опциональный контент: Quick Start

Quick start

Установка

Для amd64 есть готовые релизные сборки под Linux и Windows, но если у вас установлен Go, то достаточно одной команды, чтобы получить свежий бинарник под вашу платформу:

go get -v github.com/quasilyte/phpgrep/cmd/phpgrep

Если $GOPATH/bin находится в системном $PATH, то команда phpgrep станет сразу же доступной. Чтобы это проверить, попробуйте запустить команду с параметром -help:

phpgrep -help

Если же ничего не происходит, найдите, куда Go установил бинарник и добавьте его в переменную окружения $PATH.

Старый и надёжный способ посмотреть $GOPATH, даже если он не выставлен явно:

go env GOPATH

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

Создайте тестовый файл hello.php:

<?php
function f(...$xs) {}
f(10);
f(20);
f(30);
f($x);
f();

Запустите на нём phpgrep:

# phpgrep hello.php 'f(${"x:int"})' 'x!=20'
hello.php:3: f(10)
hello.php:5: f(30)

Мы нашли все вызовы функции f с одним аргументом-числом, значение которого не равно 20.

Как работает phpgrep

Для разбора PHP используется библиотека github.com/z7zmey/php-parser. Она достаточно хороша, но некоторые ограничения phpgrep следуют из особенностей используемого парсера. Особенно много трудностей возникает при попытках нормально работать со скобочками.

Принцип работы phpgrep прост:

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

Самое интересное — это как именно сопоставляются на равенство два AST-узла. Иногда тривиально: один-к-одному, а мета-узлы могут захватывать более одного элемента. Примерами мета-узлов является ${"*"} и ${"str"}.

Заключение

Было бы нечестно говорить о phpgrep, не упомянув structural search and replace (SSR) из PhpStorm. Они решают похожие задачи, причём у SSR есть свои преимущества, например, интеграция в IDE, а phpgrep может похвастаться тем, что является standalone программой, которую гораздо проще поставить, например, на CI.

Помимо прочего, phpgrep — это ещё и библиотека, которую можно использовать в своих программах для матчинга PHP кода. Особенно это полезно для линтеров и кодогенерации.

Буду рад, если этот инструмент будет вам полезен. Если же эта статья просто мотивирует вас посмотреть в сторону вышеупомянутого SSR, тоже хорошо.

Дополнительные материалы

Полный список шаблонов, который был использован для анализа, можно найти в файле patterns.txt. Рядом с этим файлом можно найти скрипт phpgrep-lint.sh, упрощающий запуск phpgrep со списком шаблонов.

В статье не дан полный список срабатываний, но вы можете воспроизвести эксперимент, произведя клонирование всех названых репозиториев и запустив phpgrep-lint.sh на них.

Черпать вдохновение на шаблоны проверок можно, например, из статей PVS studio. Мне очень понравилась Logical Expressions: Mistakes Made by Professionals, которая трансформируется во что-то такое:

# Для "x != y || x != z":
phpgrep . '$x != $a || $x != $b'
phpgrep . '$x !== $a || $x != $b'
phpgrep . '$x != $a || $x !== $b'
phpgrep . '$x !== $a || $x !== $b'

Вам также может быть интересна презентация phpgrep: syntax-aware code search.

В статье используются изображения гоферов, которые были созданы через gopherkon.

Что такое PHP?

PHP (Hypertext PreProcessor) — PHP это язык сценариев на стороне сервера, разработанный в первую очередь для веб-разработки. Код PHP может быть встроен в HTML или может использоваться в сочетании с различными системами веб-шаблонов, системами управления веб-контентом и веб-фреймворками.

Что такое онлайн PHP песочница?

Онлайн PHP Песочница была создана для отладки, тестирования и запуска вашего php кода онлайн. Также это позволяет разработчикам делиться своим PHP кодом с сообществом. Этот инструмент работает с белым списком функций. Все функции, для которых требуется доступ к диску, системе или сети, занесены в черный список, другие — в белый. Максимальное время выполнения составляет 3 секунды.

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

Для разрыва строки эхо-вывода в режиме CLI необходимо использовать PHP_EOL или n

Протестируйте свой PHP код онлайн без необходимости веб-сервера.

Могу ли я запустить PHP программу онлайн?

С помощью нашего инструмента вы можете редактировать PHP-код и просматривать результат в своем браузере.

Просто вставьте свой PHP-код в текстовое поле выше и нажмите кнопку «Выполнить», и вы получите результат выполнения PHP Онлайн.

Как проверить синтаксис PHP онлайн?

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

Зачем нужно запускать PHP скрипт онлайн?

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

Пример

<?php
echo "Hello World!";

После выполнения кода вы увидите «Hello World!».

PHP — популярнейший скриптовый язык программирования общего назначения, который активно применяется при разработке web-приложений. Он поддерживается множеством хостинг-провайдеров и является одним из лидирующих языков, используемых в целях создания динамических web-сайтов. Иногда возникает необходимость выполнить проверку синтаксиса кода PHP. В статье будет рассмотрено, как это сделать.

Для проверки кода сегодня используют специальные онлайн-сервисы — валидаторы (validators). Они работают предельно просто: пользователю достаточно скопировать свой код в специальную форму и нажать кнопку «Проверить код» либо клавишу «Check». Также перед подтверждением проверки надо будет отметить галочкой нужную версию. Отдельные сервисы допускают возможность перетаскивания/загрузки файла с кодом.

Один из популярных сервисов для валидации — https://phpcodechecker.com/. Он даёт возможность легко и быстро найти синтаксическую ошибку в коде. Найденные проблемы будут выделены, плюс произойдёт автоматический переход на строку с ошибкой (вы сэкономите время поиска). Выделенная ошибка будет сопровождаться соответствующими комментариями.

Существуют ситуации, когда нужно выяснить, какая конкретно версия языка функционирует на вашем сервере. Если речь идёт о конкретном веб-сайте, используйте функцию phpinfo(). Необходимо поместить в корневой каталог файл phpinfo.php со следующим содержимым:


Далее достаточно будет открыть веб-браузер и перейти по адресу вашдомен/phpinfo.php. В результате версия PHP-сервера отобразится на экране.

1-1801-88acea.png

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

На этом всё. Как видите, проверить PHP код с точки зрения синтаксических ошибок можно легко и быстро, для чего существуют специальные инструменты — валидаторы. Не составит труда и узнать версию PHP в случае необходимости.

Узнайте, правилен ли ваш код! Проверяйте его на специальных онлайн-сервисах!

PHP_970x90-20219-10b307.jpg

Как проверить сайт на ошибки онлайн?

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

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

  • Инструменты для валидации веб-сайта
    • W3C markup validation service (он же validator w3 org)
    • CSS validator
    • Checklink
    • Feed
    • Mobile checker
    • HTML Validator
    • Watson’s site validation check
    • XML well checker and validator
    • Robots checker
    • URL checker
  • Инструменты для оценки и проверки универсального доступа
    • Webaccessibility checker
    • Color contrast
    • Web accessibily evaluation tool-WAVE
    • Accessibility with style
    • Adobe PDF conversion
  • Оценка производительности сайта
    • Pingdom tools
    • Webpage analyzer
  • Проверка кросс-браузерности
    • Browser shots
    • IE net renderer
    • Viewlike

W3C markup validation service (он же validator w3 org)

Этот сервис поможет проверить валидность разметки веб-документов в форматах HTML, XHTML, SMIL, MathML и т. д. И позволит исключить необходимость использования дополнительных инструментов.

Какие проверки осуществляются:

  • Анализ синтаксиса и стилей;
  • Проверка сайта на ошибки онлайн.

Позволяет проверить код CSS и (X)HTML-документы с таблицами. Если нужно валидировать CSS, встроенный в (X)HTML-код, то сначала нужно будет проверить разметку.

Проверяет ссылки и анкоры на отдельных веб-страницах или на целом сайте. Этот инструмент позволяет выявить проблемы, связанные со ссылками, анкорами и объектами в веб-странице, CSS-таблицами и т. д. Сначала убедитесь, что в проверяемых документах используется валидная (X)HTML-разметка и CSS-код.

Бесплатный сервис для W3C-валидации ленты рассылок (Feed), который позволяет проверить синтаксис Atom или RSS. Вы можете проверить сайт на ошибки по URL или с помощью прямого ввода кода.

Инструмент позволяет проводить различные тесты веб-страниц для определения того, насколько они адаптированы под мобильные устройства. Тесты описаны в спецификации mobileOK Basic Tests 1.0. Веб-страница считается адаптированной, если проходит сразу все тесты.

HTML Validator от WDG по функционалу напоминает сервис валидации от W3C. Основные отличия были исключены с выходом обновленной версии W3C-валидатора.

Валидатор HTML онлайн Dr. Watson – бесплатный сервис, который позволяет проверить сайт на ошибки онлайн. Укажите URL-адрес страницы, которую необходимо проверить, и Watson сразу же сделает ее копию. Он также умеет исследовать множество других аспектов сайта: валидность ссылок, скорость скачивания, оптимизация под поисковые системы и т. д. Многие функции совмещены в одну. Если требуется решение «все в одном», то этот инструмент вам точно пригодится.

Какие проводятся проверки:

  1. Скорость загрузки страницы;
  2. Анализ синтаксиса и стилей;
  3. Подсчет количества слов;
  4. Проверка орфографии;
  5. Проверка ссылок;
  6. Уровень оптимизации под поисковые системы;
  7. Проверка входящих ссылок;
  8. Проверка исходного кода.

Эту форму можно использовать для проверки XML-документов на валидность. Инструмент проверяет и все подкрепленные внешние файлы на наличие синтаксических ошибок и находит лишние пробелы.

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

URL checker

InternetSupervision™ — это сервис, который отслеживает доступность HTML, FTP, почтовых серверов (SMTP и POP3), наблюдает за производительностью сайта и транзакциями в интернет-магазине (включая активность некоторых форм на странице).

Webaccessibility checker

Этот инструмент умеет проверять отдельные HTML-страницы на соответствие стандартам универсального доступа.

Этот инструмент позволяет проверить контрастность и яркость цветов на переднем и заднем фоне всех DOM-элементов. Правильное сочетание цветов гарантирует, что текст будет виден даже людям с плохим зрением. AccessColor также помогает найти оптимальное сочетание цветов для HTML и CSS-документов.

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

Accessibility with style

HERA – инструмент для проверки доступности веб-страниц и их соответствия спецификации Web Content Accessibility Guidelines. HERA выполняет необходимый набор тестов на каждой странице, и автоматически определяет проблемные места.

Этот сервис позволяет конвертировать любые веб-страницы на английском языке в PDF-документы. «Прогоняя» контент через этот инструмент, вы столкнетесь с тем, что Adobe временами будет испытывать сложности с доступом к тому или иному фрагменту.

Инструмент для проверки сайта на наличие ошибок. Full Page Test загружает сразу HTML-страницу, включая все объекты (изображения, CSS, Javascript, RSS, Flash и фреймы). Затем он имитирует процесс загрузки страницы в веб-браузере, и подсчитывает, сколько времени уходит на загрузку того или иного объекта.

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

Browser shots

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

IE NetRenderer позволяет проверить, как отображается сайт в Internet Explorer 7, 6 или 5.5.

Viewlike

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

А какими инструментами для тестирования сайтов пользуетесь вы? Пожалуйста, поделитесь в комментариях!

  • Как проверить outlook на ошибки
  • Как проверить ost файл на ошибки
  • Как проверить net framework на ошибки
  • Как проверить mkv видеофайл на наличие ошибок
  • Как проверить microsd карту на ошибки