调试Magento商店的基本原理
-
16-10-2019 - |
题
我该如何调试我的Magento商店
这个问题现在与我们现在不太相关,但是在5年前存在Magento SE网站,这可能是我们的第一个问题。对于那些刚进入Magento或不熟悉它的人来说,知道调试的基本面可能是排除问题原因的关键。尽管现在与我们无关紧要,但我们还是以一种自我解答的方法来抢占这个问题。
帮助我的网站下降!
- 我的设计有过错吗?
- 第三方模块是否有故障?
- 为什么我看不到错误?
这些问题都可以通过遵循标准化的方法来调试,即使是最基本的用户也可以完成。通过消除调试Magento商店的基本面的过程。
解决方案
调试有点像艺术,但是可以通过遵循简单的方案轻松掌握的事情。
按照每个点,直到最终达到解决方案。
启用PHP错误
这是大多数问题的关键。出于安全性或其他原因,默认情况下,PHP错误显示可能会因您的PHP配置而被禁用。
您可以通过更永久的解决方案或仅仅是更临时的东西启动错误。
永久解决方案
对于apache/mod_php用户
在您的文档根中 .htaccess
文件 - 只需将其放在顶部即可。
php_flag display_startup_errors on
php_flag display_errors on
php_flag html_errors on
php_flag log_errors on
php_value error_log /home/path/public_html/var/log/system.log
对于nginx/fastcgi用户
在您的nginx VirtualHost配置中,在最终中 location .php {
指令,或 fastcgi_params
文件(如果指定了一个)
fastcgi_param PHP_VALUE display_startup_errors=on;
fastcgi_param PHP_VALUE display_errors=on;
fastcgi_param PHP_VALUE html_errors=on;
fastcgi_param PHP_VALUE log_errors=on;
fastcgi_param PHP_VALUE error_log=/home/path/public_html/var/log/system.log;
临时/通用解决方案
对于任何平台
编辑Magento Bootstrap index.php
在您的文档词根和不输入中,以下行:
#ini_set('display_errors', 1);
启用开发人员模式
当您遇到错误并突然单击“错误报告”页面,并获得了一个看似无用的错误字符串 1184257287824
- 您有一些选择。
永久解决方案
对于apache/mod_php用户
在您的文档根中 .htaccess
文件 - 只需将其放在顶部即可。
SetEnv MAGE_IS_DEVELOPER_MODE true
对于nginx/fastcgi用户
在您的nginx VirtualHost配置中,在最终中 location .php {
指令,或 fastcgi_params
文件(如果指定了一个)
fastcgi_param MAGE_IS_DEVELOPER_MODE true;
临时/通用解决方案
编辑Magento Bootstrap index.php
在您的文档根中,要么使 if
语句始终为真,或为您的特定IP启用。
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE']) || true) {
Mage::setIsDeveloperMode(true);
}
或者
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE']) || $_SERVER['REMOTE_ADDR'] == 'my.ip.add.ress') {
Mage::setIsDeveloperMode(true);
}
检查您的权限
不正确的权限会导致很多问题,其中很多并不容易找到。
例如。
如果PHP不能写信给./media
目录和您的JS组合启用了 - Magento无法为媒体生成组合的文件和关联的唯一URI。因此,相反,您将在浏览器源代码中找到的是媒体文件的完整服务器路径/home/path/public_html/media/xxx
否则,该站点似乎可以正常工作 - 实际上没有关键错误。
请记住,这种做法对于专用托管是安全的,但如果Apache流程不是每个用户,则可能会出现共享托管的安全问题。
在我们的示例中,SSH/FTP用户是 sonassi
, ,Apache用户是 apache
小组是 apache
将FTP/SSH用户添加到Apache组
最重要的是,我们需要确保FTP/SSH用户是Apache组的一部分,在我们的示例中, apache
(但通常也是 www-data
)
usermod -a -G apache sonassi
继续向小组添加与FTP/SSH的用户一样多。
重置原始权限
因此,在开始之前,请确保所有权限都正确。
chown -R sonassi:apache /home/path/public_html/
find /home/path/public_html/ -type d -exec chmod 775 {} \;
find /home/path/public_html/ -type f -exec chmod 664 {} \;
使更改永久
ACL和粘性
Linux中的ACL允许我们定义特定规则,在我们的情况下,创建时应继承的权限文件应继承。一个 粘得 (稍后提到)照顾小组的继承,但无济于事,这就是我们使用ACL的原因。
首先在主动分区上启用ACL支持, 请确保您的内核已通过ACL支持编译.
您的分区可能是 /
, /home
, /var
或其他东西,请根据适当的替换。
mount -o remount,acl /home
现在启用了ACL,我们可以设置ACL规则和组粘性位:
setfacl -d -m u::rwx,g::rwx,o::rx /home/path/public_html/
chmod g+s /home/path/public_html/
但是我没有ACL支持
如果您的内核不支持ACL,您也可以使用 umask
(这是Bash,FTP和PHP的运行时间设置)设置默认文件权限。 Magento通常会设置 umask(0)
在 index.php
, 但是,改变这是您的利益。
在你的 index.php
更改 umask
线路
umask(022);
在您的SSH狂欢环境中,将其设置在您的 .bashrc
或者 .bash_profile
umask 022
对于您的FTP服务器,您需要为其读取文档,但是原理是相同的。
将主题恢复为默认
您的主题或软件包可能负责此问题。恢复回到香草Magento主题是一种快速的方法。
**这需要注意,某些模块可能取决于某些主题功能*
与其通过管理面板更改任何内容,而是更简单地重命名有问题的目录。
通过SSH
mv ./app/design/frontend/myBrokenTheme{,.tmp}
mv ./skin/frontend/myBrokenTheme{,.tmp}
或通过您的FTP客户端,将您的软件包和其他内容重命名为其他。例如。 myBrokenTheme.tmp
如果这解决了您的问题
然后,您需要更深入地了解模板的哪一部分是有问题的。因此,还原包裹并尝试以下内容,每一个之间进行测试。
从本质上讲,该过程是在您沿着文件树穿越时逐渐启用目录 - 直到找到有问题的文件为止。
- 将布局目录重命名为
.tmp
- 将模板目录重命名为
.tmp
然后,如果两者得出修复程序,请将布局目录中的所有文件重命名为 .tmp
- (对于SSH用户 ls | xargs -I {} mv {} {}.tmp
或者 rename 's/^/.tmp/' *
)
然后逐渐启用每个文件1 x 1,直到解决。
如果这无法解决您的问题
有潜力 base/default
或者 enterprise/default
目录已被污染 - 最好用已知的干净版本代替。
您可以通过下载干净的Magento建造并根据需要更换目录来做到这一点。通过SSH,您可以做到这一点:
cd /home/path/public_html/
mkdir clean_mage
cd clean_mage
MAGENTO_VERSION=1.7.0.0
wget -O magento.tgz http://www.magentocommerce.com/downloads/assets/$MAGENTO_VERSION/magento-$MAGENTO_VERSION.tar.gz
tar xvfz magento.tgz
cd /home/path/public_html/app/design/frontend
mv base{,.tmp}
cp -par /home/path/public_html/clean_mage/magento/app/design/frontend/base .
cd /home/path/public_html/skin/frontend
mv base{,.tmp}
cp -par /home/path/public_html/clean_mage/magento/skin/frontend/base .
您也可以借此机会 diff
这两个目录如果要验证任何更改。
diff -r base base.tmp
NB。此方法将在过程中引起更多错误,因为模块依赖性决定了特定文件的存在。 不幸的是,它的课程标准。
禁用本地模块
默认情况下,Magento定义PHP包括按以下顺序加载类的路径
Local > Community > Core
如果文件在本地 - 加载它并且不再进行。
如果文件在社区中 - 加载它并且不再进行。
如果在其他任何地方都找不到文件 - 从核心加载该文件。
同样,与其通过Magento Admin面板禁用模块,而是在文件级别上执行此操作更为实用。
通常,为了禁用模块“正确”的方式,您将编辑相应的 ./app/etc/modules/MyModule.xml
文件并设置 <active>false</active>
- 但是,这实际上并不能阻止类加载。
如果另一个类在模块中扩展给定类(忽略任何洋红色依赖性声明),则仍然会加载它 - 无论扩展是否是禁用的。
因此,禁用扩展程序的最佳手段是重命名目录。
首先禁用本地
只需通过FTP重命名目录,或使用以下SSH命令
mv ./app/code/local{,.tmp}
然后禁用社区
mv ./app/code/community{,.tmp}
如果问题是从任何一个解决的
然后是理解哪个模块特别源于哪个模块的情况。与上述包装诊断的示例一样,适用同一过程。
因此,还原X目录并尝试以下测试。
本质上,该过程是逐步启用目录(模块),直到误差重新出现
- 将目录中的所有模块重命名为
.tmp
(对于SSH用户ls | xargs -I {} mv {} {}.tmp
或者rename 's/^/.tmp/' *
) - 通过删除,逐渐启用每个模块
.tmp
从文件名
如果问题未解决
然后,核心本身可能会受到污染。主要的Magento PHP核心包括
./app/code/core
./lib
因此,再次重命名这些目录并以干净的变体复制。假设您已经下载了上述清洁版的Magento版本,则可以通过SSH进行操作:
cd /home/path/public_html/app/code
mv core{,.tmp}
cp -par /home/path/public_html/clean_mage/magento/app/code/core .
然后,如果问题仍未解决,请替换 lib
目录也是
cd /home/path/public_html
mv lib{,.tmp}
cp -par /home/path/public_html/clean_mage/magento/lib .
此时,您的Magento商店将不过是带有修改数据库的香草安装。
实际上,一些模型仍存储在数据库中(例如,顺序增量) - 因此,在这一点上,它成为手动进行这些编辑的情况。到目前为止,上面的所有步骤都是可逆的,没有持久的损坏。但是,如果我们也正在导入一个干净的Magento数据库 - 它可能会证明是不可逆的(尚无恢复备份)。
上面的指南使您能够确定错误;不解决最终错误。
内容愿意来自 www.sonassi.com/knowledge-base/magento-debug-process 和 www.sonassi.com/sknowledge-base/stop-magento-permissions-errors-permanly
其他提示
作为 在Twitter上要求 和 讨论了元 我将在这里开始对非DEVS的调试教程。
首先,我认为(即使您也试图参与这一点)Magento对于没有开发人员/开发团队的商人来说太复杂了。但是,如果您勇敢并想尝试一下,我们将在这里尽力为您提供帮助。我认为有些问题是“我该怎么做?”之间的边界。和“请让我的工作,我对Google太愚蠢”是一条非常好的线条。我了解Google认为这通常很难,因为您不知道自己在谷歌搜索什么,因为您还不知道命名。话虽如此,让我们收集每个人都可以使用Magento商店做的事情,即使您也不是开发人员。
一个很好的答案,如何调试Magento,当您想变得肮脏时 Sonassi已经给出了, ,但是我尝试添加东西并复制我认为适用于商人的东西。
免责声明:本文中提到的所有目录和文件均相对于Magento根文件夹
/var/www
但是,根据托管提供商的不同,您所谓的文档根可能无处不在,请询问您的提供商,如果您找不到Magento!
开发模式
你想遇到真正的错误,不是那么糟糕 “发生错误” 洋红色通常提供的页面。
谢谢 fontis.com 对于此图像。
页面上提到的报告可以在 var/reports/<the_number>
当您激活开发模式时,Magento会引发真正的错误,这些错误可能会泄漏凭据,例如数据库的凭据! 因此,在打开生产服务器之前先考虑一下!
打开你的 index.php
在Magento的根文件夹中的文件,根据版本,您可以在第73行周围找到这些行:
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
Mage::setIsDeveloperMode(true);
}
#ini_set('display_errors', 1);
要现在活动模式,您必须更改这些行。
如果您知道您的IP地址 (至少在德国,大多数人每24小时每24小时得到一个新的人),Google在这里为您提供帮助:
您的公共IP地址是87.138.100.68
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])
|| $_SERVER['REMOTE_ADDR'] == 'my.ip.add.ress'
) {
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
}
如果您出于任何原因不知道您的IP,则可以为所有人显示错误。
#if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE']) || true) {
Mage::setIsDeveloperMode(true);
#}
ini_set('display_errors', 1);
记录
Magento将许多内容记录到两个文件中:
var/log/exception.log
var/log/system.log
总是记录例外。需要在后端启用系统日志:
System > Configuration > Developer > Log
放 Enabled
是的,您在 system.log
并在 exception.log
这是主题问题吗?
您有自己的主题,此处在后端配置:
系统>配置>设计
谢谢 kb.magenting.com 对于图像
在这里,您可以配置软件包和主题。如果您想尝试在默认主题中重现错误,请从输入字段中删除所有内容。然后单击保存,然后 与演示商店中的标准洋红色主题一起查看标准主题, ,如果您在1.8之前有一家商店,您可以在 Magento社区版用户指南
如果您无法在默认主题中重现问题,则主题已断开,请联系主题供应商。我们不支持第三方主题,尤其是商业主题。
现在怎么办?
您发现一个真正的错误,可以复制,在默认主题中可以再现吗?太好了,请打开一个问题,我们正在尽力提供帮助。
在问题中:
- 描述你在做什么
- 提出了什么错误
- 日志文件中有什么吗?
- 也许是错误的屏幕截图
- 首先,您应该启用开发人员模式
- 您也可以在index.php中显示错误:ini_set('display_errors',1);
- 用任何智能IDE(phpstrom/eclipse)编译Xdebug扩展
- 禁用自定义和第三方模块
- 查看您的异常和错误日志,在异常日志上解决列出的错误
- 检查服务器上必须加载卷发和MCRYPT扩展
- 检查文件夹和文件权限Chown -r sonassi:apache/home/path/public_html/find/home/path/partion/public_html/-type d -exec d -exec chmod 775 {} ;查找/home/path/public_html/-type f -exec chmod 664 {} ;
- 更新媒体和VAR目录权限0777如果未设置
- 启动IDE(phpstrom),然后在index.php 10.press F8上设置调试器起点
对于使用上述步骤,您应该肯定会出现错误。
调试回溯
这是在Magento中调试功能调用的好功能。
将此函数添加到Incluber/config.php或创建新文件中,并将所有常见的使用PHP功能放置。
function back_trace($exit = true) { $call_back_methods = ''; $call_back_methods .= ''; $call_back_methods .= 'S.N.Function NameLine NumberFile Name'; $counter = 1; foreach (debug_backtrace() as $index => $data) { //if (0 == $index) continue; $call_back_methods .= '' . $counter++ . ''; $call_back_methods .= '' . $data['function'] . ''; $call_back_methods .= '' . $data['line'] . ''; $call_back_methods .= '' . $data['file'] . ''; } $call_back_methods .= ''; print $call_back_methods; if (true == $exit) exit; }