运行 PHP 来自 cli 的脚本:php.ini memory_size 未考虑
run PHP script from cli : php.ini memory_size not taken into account
我正在尝试从命令行 运行 一个 php 脚本(magento reindexer 脚本)。该脚本消耗大量内存,因此出现以下错误:PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 72 bytes) in /home/karanta/www/karanta.fr/lib/Zend/Db/Adapter/Abstract.php on line 691
为了解决这个问题,我编辑了 /etc/php5/cli/php.ini
文件并设置了 memory_limit = 2048M
.
为了检查配置,我 运行 一个包含来自 cli 的 phpinfo();
的脚本,我看到:memory_limit => 2048M => 2048M
,所以配置似乎被正确考虑了。 ini_get('memory_limit);
也 returns 2048M.
然而,当我重新运行 重建索引脚本时,我仍然得到 PHP Fatal error: Allowed memory size of 536870912 bytes exhausted
,就好像 memory_limit 仍然是 512M。脚本无法完成,我不知道如何扩充 memory_limit 以允许脚本完成。
编辑:我还尝试将指令 ini_set("memory_limit", -1);
直接添加到 PHP 脚本中,但它仍然挂起相同的 PHP Fatal error: Allowed memory size of 536870912 bytes exhausted
.
额外信息:
服务器是 ovh 运行ning Debian GNU/Linux 7.5 的专用机器,内存为 64GB!
php -v
returns:
PHP 5.6.12-1 (cli) Copyright (c) 1997-2015 The PHP Group Zend Engine
v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
free -k -h
脚本执行期间 returns:
total used free shared buff/cache available
Mem: 62G 1,8G 48G 84M 12G 60G
Swap: 1,0G 0B 1,0G
ps -aux
returns:
karanta 25568 5.6 0.0 229484 41824 pts/1 S 07:54 0:04 php shell/indexer.php --reindex catalog_url
按照@IgorGreg 的建议,我尝试使用Zend_Memory 设置内存限制。我写了这个 php 脚本,我从 cli 运行 替换了 shell/indexer.php 脚本。
<?php
require_once 'app/Mage.php';
$app = Mage::app('admin');
umask(0);
$memoryManager = Zend_Memory::factory('none');
$memoryManager->setMemoryLimit(-1);
$process = Mage::getModel('index/process')->load(3);
$process->reindexAll();
?>
仍然出现同样的错误。
设置memory_limit为-1表示没有内存限制。但是,如果您在 php.ini 或 .htaccess 中设置此值,它可能会在 运行 时间内被脚本覆盖。
为了确保它会生效,最好在脚本中使用ini_set("memory_limit", -1);
。
通常,在 php.ini 中将 memory_limit 设置为 -1 并不是一个好主意。它可能会导致您的系统在某些情况下挂起。
Magento 建立在 Zend framework 1 之上,它有自己的内存管理器。 documentation
说你可以像这样设置内存限制:
$memoryManager->setMemoryLimit(-1);
不需要是-1,可以是1,073,741,824,或者任何整数,以字节为单位。
不过我还没试过。
在Linux系统中,可以有三种独立的内存限制设置,一种用于Apache DSO模块php实例,一种用于命令行php实例,一种用于cgi php 实例.
每个安装都有自己的 php.ini 文件,例如 /etc/php5/apache2/php.ini
和 /etc/php5/cli/php.ini
并且可能能够覆盖设置 memory_limit 关闭(通常发现在共享主机中)。
cli 的 php.ini
文件需要增加 memory_limit。
如果您使用 apc 缓存,可能会出现另一个问题。必须通过将以下内容添加到 apc 配置文件来启用它。
apc.enable-cli=1
如果您在 cPanel/WHM 下 运行 ,那么第三个麻烦来源是,由于实施了安全限制,可能会安装多个不同版本的 php。我必须联系我们的托管服务提供商才能 运行 那一个下来。尝试从出现故障的命令行中使用 which php
并确保它与可通过 cron 脚本访问的版本相同。该特定版本的 php.ini 文件也必须设置。
Magento 在 CLI 模式下解析 .htaccess
文件,如果发现内存限制或任何其他 PHP 设置,应用它们(是的,认真的....)
负责代码在shell/abstract.php
:
/**
* Parse .htaccess file and apply php settings to shell script
*
*/
protected function _applyPhpVariables()
{
$htaccess = $this->_getRootPath() . '.htaccess';
if (file_exists($htaccess)) {
// parse htaccess file
$data = file_get_contents($htaccess);
$matches = array();
preg_match_all('#^\s+?php_value\s+([a-z_]+)\s+(.+)$#siUm', $data, $matches, PREG_SET_ORDER);
if ($matches) {
foreach ($matches as $match) {
@ini_set($match[1], str_replace("\r", '', $match[2]));
}
}
preg_match_all('#^\s+?php_flag\s+([a-z_]+)\s+(.+)$#siUm', $data, $matches, PREG_SET_ORDER);
if ($matches) {
foreach ($matches as $match) {
@ini_set($match[1], str_replace("\r", '', $match[2]));
}
}
}
}
解决方案
不要通过.htaccess
设置内存限制和执行时间,使用php.ini
或虚拟主机配置。
请按照以下步骤操作。
1。根据您的要求将以下内容更改为 .htaccess
php_value memory_limit 256M => php_value memory_limit 2048M
- 与其一并重建索引,不如像
一样一个一个重建索引
php indexer.php --reindex catalog_product_price
需要通过 .htaccess 增加内存限制,因为您可以在 abstract.php 中看到它会引用 .htaccess 配置。
如果您还有任何疑问,请告诉我
谢谢
我正在尝试从命令行 运行 一个 php 脚本(magento reindexer 脚本)。该脚本消耗大量内存,因此出现以下错误:PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 72 bytes) in /home/karanta/www/karanta.fr/lib/Zend/Db/Adapter/Abstract.php on line 691
为了解决这个问题,我编辑了 /etc/php5/cli/php.ini
文件并设置了 memory_limit = 2048M
.
为了检查配置,我 运行 一个包含来自 cli 的 phpinfo();
的脚本,我看到:memory_limit => 2048M => 2048M
,所以配置似乎被正确考虑了。 ini_get('memory_limit);
也 returns 2048M.
然而,当我重新运行 重建索引脚本时,我仍然得到 PHP Fatal error: Allowed memory size of 536870912 bytes exhausted
,就好像 memory_limit 仍然是 512M。脚本无法完成,我不知道如何扩充 memory_limit 以允许脚本完成。
编辑:我还尝试将指令 ini_set("memory_limit", -1);
直接添加到 PHP 脚本中,但它仍然挂起相同的 PHP Fatal error: Allowed memory size of 536870912 bytes exhausted
.
额外信息:
服务器是 ovh 运行ning Debian GNU/Linux 7.5 的专用机器,内存为 64GB!
php -v
returns:
PHP 5.6.12-1 (cli) Copyright (c) 1997-2015 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
free -k -h
脚本执行期间 returns:
total used free shared buff/cache available
Mem: 62G 1,8G 48G 84M 12G 60G
Swap: 1,0G 0B 1,0G
ps -aux
returns:
karanta 25568 5.6 0.0 229484 41824 pts/1 S 07:54 0:04 php shell/indexer.php --reindex catalog_url
按照@IgorGreg 的建议,我尝试使用Zend_Memory 设置内存限制。我写了这个 php 脚本,我从 cli 运行 替换了 shell/indexer.php 脚本。
<?php
require_once 'app/Mage.php';
$app = Mage::app('admin');
umask(0);
$memoryManager = Zend_Memory::factory('none');
$memoryManager->setMemoryLimit(-1);
$process = Mage::getModel('index/process')->load(3);
$process->reindexAll();
?>
仍然出现同样的错误。
设置memory_limit为-1表示没有内存限制。但是,如果您在 php.ini 或 .htaccess 中设置此值,它可能会在 运行 时间内被脚本覆盖。
为了确保它会生效,最好在脚本中使用ini_set("memory_limit", -1);
。
通常,在 php.ini 中将 memory_limit 设置为 -1 并不是一个好主意。它可能会导致您的系统在某些情况下挂起。
Magento 建立在 Zend framework 1 之上,它有自己的内存管理器。 documentation 说你可以像这样设置内存限制:
$memoryManager->setMemoryLimit(-1);
不需要是-1,可以是1,073,741,824,或者任何整数,以字节为单位。
不过我还没试过。
在Linux系统中,可以有三种独立的内存限制设置,一种用于Apache DSO模块php实例,一种用于命令行php实例,一种用于cgi php 实例.
每个安装都有自己的 php.ini 文件,例如 /etc/php5/apache2/php.ini
和 /etc/php5/cli/php.ini
并且可能能够覆盖设置 memory_limit 关闭(通常发现在共享主机中)。
cli 的 php.ini
文件需要增加 memory_limit。
如果您使用 apc 缓存,可能会出现另一个问题。必须通过将以下内容添加到 apc 配置文件来启用它。
apc.enable-cli=1
如果您在 cPanel/WHM 下 运行 ,那么第三个麻烦来源是,由于实施了安全限制,可能会安装多个不同版本的 php。我必须联系我们的托管服务提供商才能 运行 那一个下来。尝试从出现故障的命令行中使用 which php
并确保它与可通过 cron 脚本访问的版本相同。该特定版本的 php.ini 文件也必须设置。
Magento 在 CLI 模式下解析 .htaccess
文件,如果发现内存限制或任何其他 PHP 设置,应用它们(是的,认真的....)
负责代码在shell/abstract.php
:
/**
* Parse .htaccess file and apply php settings to shell script
*
*/
protected function _applyPhpVariables()
{
$htaccess = $this->_getRootPath() . '.htaccess';
if (file_exists($htaccess)) {
// parse htaccess file
$data = file_get_contents($htaccess);
$matches = array();
preg_match_all('#^\s+?php_value\s+([a-z_]+)\s+(.+)$#siUm', $data, $matches, PREG_SET_ORDER);
if ($matches) {
foreach ($matches as $match) {
@ini_set($match[1], str_replace("\r", '', $match[2]));
}
}
preg_match_all('#^\s+?php_flag\s+([a-z_]+)\s+(.+)$#siUm', $data, $matches, PREG_SET_ORDER);
if ($matches) {
foreach ($matches as $match) {
@ini_set($match[1], str_replace("\r", '', $match[2]));
}
}
}
}
解决方案
不要通过.htaccess
设置内存限制和执行时间,使用php.ini
或虚拟主机配置。
请按照以下步骤操作。
1。根据您的要求将以下内容更改为 .htaccess php_value memory_limit 256M => php_value memory_limit 2048M
- 与其一并重建索引,不如像 一样一个一个重建索引
php indexer.php --reindex catalog_product_price
需要通过 .htaccess 增加内存限制,因为您可以在 abstract.php 中看到它会引用 .htaccess 配置。
如果您还有任何疑问,请告诉我
谢谢