RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 701142
Accepted
Алексей Шиманский
Алексей Шиманский
Asked:2020-08-03 00:30:46 +0000 UTC2020-08-03 00:30:46 +0000 UTC 2020-08-03 00:30:46 +0000 UTC

如何以及通过什么方式来查找 PHP 代码中的错误?

  • 772

在开发过程中,有时代码无法按预期工作或根本无法工作。我坐下来想:什么地方错了?看代码一个小时后,我去找教授。Stack Overflow等资源并发布问题 “这里的错误在哪里?” 或“为什么它不起作用?”

结果,问题通常是一个小的、愚蠢的拼写错误、语法错误等等。如果你为每一个废话都浏览资源,你就不会成为那样的专业人士。我想成为。

问题:查找PHP代码错误的方法有哪些?有哪些工具、方法、插件、路径等?


UPD(10/16/2021):当前主题中有效方法的列表(以免滚动浏览所有内容):

  • 错误信息
  • 调试
  • 祖父的方式
  • 在本地工作,但不适用于主机/适用于 XXX,但不适用于 YYY(关于日志记录)
  • 解析/语法错误;意外的 XXX 错误以及如何解决它们
  • 此外

 

php отладка
  • 7 7 个回答
  • 10 Views

7 个回答

  • Voted
  1. Best Answer
    Алексей Шиманский
    2020-08-03T00:33:17Z2020-08-03T00:33:17Z

    昨天一切正常,但今天不工作/代码没有按预期工作

    或者

    调试


    调试过程是怎样的?这是什么?

    调试过程包括我们在任何地方停止脚本的执行,查看变量、函数中的内容,分析并移动到其他地方;我们正在寻找那些行为偏离正确行为的地方。


    重要的提示:

    有许多IDE和代码编辑器可让您进行调试。每个人的设置过程都不同。因此,值得参考有关为开发环境本身和您正在使用的版本设置调试的文档。

    目前,将考虑来自PHPStorm 2017的示例。


    训练

    首先,PHP需要有一个名为xdebug的调试库。如果它还不存在,那么你需要安装它。

    对于Windows:

    下载 dll,例如在xdebug.org 上。

    通常所有库都在PHPext文件夹内的一个文件夹中。那才是应该放的地方。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版本的调试器,那么指定的PHPsudo apt install php7.0-xdebug版本 在哪里7.0

    • 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可能不同。cdin/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
    • 选择包含文件的文件夹,然后单击顶部的“项目根目录”按钮,将文件夹标记为项目的根目录
    • 点击下一步”
    • 单击添加新的本地服务器

    在此处输入图像描述

    • 输入任何服务器名称和Web Server root URL。在这个例子中,这个http://localhost/testy2

    在此处输入图像描述

    • 单击“下一步”,然后单击“完成”

    发射

    首先,在面板左侧任意一行的代码上,您可以单击ЛКМ,从而设置一个断点(breakpoint - breakpoint)。这是调试器一到达它就会自动停止PHP执行的地方。断点的数量没有限制。你可以到处放很多东西。

    在此处输入图像描述

    Если кликнуть ПКМ и во всплывающем меню выбрать Debug (или в верхнем меню - Run → Debug), то при первом запуске 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.

    在此处输入图像描述

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

    • 25
  2. Алексей Шиманский
    2020-08-03T00:31:54Z2020-08-03T00:31:54Z

    错误信息

    无论是在本地还是在生产服务器上,都需要读取和处理所有错误。不同之处在于,在本地服务器上,您需要配置将错误输出到屏幕。在战场上 -不要在屏幕上显示错误,但你需要写入日志,在那里你可以阅读和分析它们。

    要在屏幕上显示所有错误,您需要在脚本的最开头编写:

    ini_set('display_errors',1);
    error_reporting(E_ALL ^E_NOTICE);
    

    在这种情况下,这些行将向屏幕报告所有严重错误。如果没有报错,则需要这样写:

    error_reporting(E_ALL);
    

    要显示语法错误,您需要更正php.ini(或.htaccess添加行php_flag display_errors 1)。

    结果:

    在此处输入图像描述

    在此处输入图像描述

    在此处输入图像描述

    您可以立即看到:

    • 级别(警告、通知、错误)
    • 错误的全文
    • 有错误的脚本名称
    • 同一脚本中的行号

    可以到脚本到指定行进行分析。

    不懂英文?

    打开任何在线翻译器并复制错误文本,将大写字母替换为小写字母:

    致命错误:未捕获的错误:在第 6 行的 W:\test\index.php 中调用未定义的函数 getSum()

    致命错误:未捕获的错误:调用未定义的 getSum() 函数 
    在第 6 行的 W:\test\index.php 中
    

    直接的俄语说:不定函数getSum。所以有一个电话,但没有通知,你需要朝指示的方向看。

    • 16
  3. Алексей Шиманский
    2020-08-03T00:30:46Z2020-08-03T00:30:46Z

    祖父的方式

    尽管有下面描述的方法,但应立即注意,有一些很棒的工具可以帮助您更快地检测和修复错误。其中之一是集成开发环境 (IDE)。您可以在问题中阅读更多相关信息:

    预防、发现和消除错误的方法有哪些?


    关于方式。

    这种方法在古代是用的,当时他们只是写代码,其实就是在记事本里。现在它也可以工作了,尽管有了智能开发环境和调试器,这不是最快和最有效的方法。

    老套地使用echo/ print_r/ var_dump。有时加上die(),这样代码就不会更进一步。

    动作算法:

    1. 我们写echo(ИМЯ_ПЕРЕМЕННОЙ)orprint_r(ИМЯ_ПЕРЕМЕННОЙ)到脚本的要点之一。让我们看看这些值是什么。
    2. 如果值符合预期,则错误如下。去掉变量output,写在下面。
    3. 如果值不是你所期望的,那么问题就更高了。把变量output去掉,写在上面。
    4. 我们重复步骤 2 和(或)3,直到我们到达上面一行的变量输出给出正确结果的行,但下面的行没有。

    例子:

    $test1 = 3;
    $test2 == 2;
    $result = $test1 + $test2;
    echo $result;
    

    我们期望看到 5,但我们看到 3。让我们写

    echo '$test1: '.$test1.', $test2: '.$test2.', $result: '.$result;
    

    看看

    $test1: 3, $test2: , $result: 3
    

    $test1- 正确的值

    $test2并且$result是无效值。特别是在$test2

    所以,至少,问题出在$test2. 如果你仔细观察,你会发现他们不小心把等号而不是赋值号。

    $test2 == 2;
            ^------- лишний знак    
    

    定影。

    (注)如果代码原则上不执行,比如什么都不输出,那么就echo 'тестовая_фраза';在代码里写,越写越高,直到出现。铭文一出现,就代表很明显,事情就在下方一行。

    底线:您所需要的只是在算法的每一步查看必要的变量,并了解错误发生的时间点。

    • 13
  4. pwnz
    2020-09-03T21:52:11Z2020-09-03T21:52:11Z

    Все ответы сверху хороши и правильны, но хочется добавить еще пару моментов. Внедрения в проект статического анализатора PHPStan, Phan или Psalm , так же можно использовать все 3 сразу :) Подробней есть статья на хабре тык

    • 5
  5. Alex V
    2020-09-14T00:13:10Z2020-09-14T00:13:10Z

    Файл php.ini может блокировать вывод ошибок. Решение. Проверить параметры error_reporting = E_ALL, display_errors = On, display_startup_errors = On в php.ini. Если вы не знаете где файл php.ini? Используйте php функцию phpinfo(). Откроется таблица. Там есть путь до php.ini. Найдите параметр “Loaded Configuration File” и “Configuration File (php.ini) Path”. Вот здесь я нашел об этом. profi.spage.me/php/show-php-file-errors-enable-php-error-display

    • 2
  6. Алексей Шиманский
    2022-07-30T16:55:38Z2022-07-30T16:55:38Z

    ## Локально работает, а на хостинге нет.

    ## У XXX работает, а у YYY нет.

    Если на локальном компьютере работает, а на хостинге - нет, то в первую очередь надо посмотреть ЛОГИ на хостинге. В них всегда написано, что не так.

    还需要考虑PHP、apache等的版本,需要和开发时完全一致。比如开发是在PHP8.1上进行的,托管是PHP5.3 ,工作能力的概率就低。


    同样,如果它对某人有效,但对您无效,那么您还需要首先确保PHP的版本、Web 服务器、数据库和设置是相同的。

    如果一切都一样,但是,例如,白屏:至少您需要启用错误显示(请参阅当前答案)或查看服务器上的日志。如果在 Linux 下进行开发,那么日志通常位于文件夹/var/logs/apache2/...或/vae/logs/nginx/....

    • 0
  7. user316324
    2020-01-18T14:40:10Z2020-01-18T14:40:10Z

    Нужно начинать с самой большой переменной и спускаться вниз по var_dump();, и найти неверное значение какой-то переменной.

    • -4

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5