检查PHP中的memory_limit

60
我需要检查我的脚本安装程序中的memory_limit是否至少为64M。这只是PHP代码的一部分,应该可以正常工作,但可能由于这个"M"而无法正确读取值。如何解决?
  //memory_limit
    echo "<phpmem>";
    if(key_exists('PHP Core', $phpinfo))
    {
        if(key_exists('memory_limit', $phpinfo['PHP Core']))
        {
            $t=explode(".", $phpinfo['PHP Core']['memory_limit']);
            if($t[0]>=64)
                $ok=1;
            else
                $ok=0;
            echo "<val>{$phpinfo['PHP Core']['memory_limit']}</val><ok>$ok</ok>";
        }
        else
           echo "<val></val><ok>0</ok>";
    }
    else
        echo "<val></val><ok>0</ok>";
    echo "</phpmem>\n"; 

我正在使用XML代码,所以这是不可能的。 - Spacedust
你能展示一下 var_dump($phpinfo); 或者至少是 var_dump($phpinfo['PHP Core']); 吗?这样我们就可以看到你的起点是什么了。 - DaveRandom
PH8-cli中已删除了内存限制的ini规则,现在内存限制是无限制的(返回-1、false,没有限制)。 - undefined
10个回答

93

在命令行上检查:

php -i | grep "memory_limit"

3
你能解释一下这个输出的意思吗:memory_limit => -1 => -1?这段输出意味着当前PHP脚本的内存限制被设置为无限制。其中,memory_limit表示内存限制的参数名,-1表示无限制,箭头“=>”用于连接参数名和参数值。 - Ron Piggott
1
对于一些 PHP 设置,-1 表示“无限制”,但我不确定 memory_limit 是否也是如此。您可以从 php.ini 文件中检查它。在命令行上执行 php -i | grep "php.ini" 并检查 Loaded Configuration File 中的 memory_limit。 - Okan
2
如果终端打印 => -1,那么这表示内存限制是无限的。 - Fernando León

49

先尝试转换值(例如:64M -> 64 * 1024 * 1024),然后进行比较并打印结果。

<?php
$memory_limit = ini_get('memory_limit');
if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) {
    if ($matches[2] == 'M') {
        $memory_limit = $matches[1] * 1024 * 1024; // nnnM -> nnn MB
    } else if ($matches[2] == 'K') {
        $memory_limit = $matches[1] * 1024; // nnnK -> nnn KB
    }
}

$ok = ($memory_limit >= 64 * 1024 * 1024); // at least 64M?

echo '<phpmem>';
echo '<val>' . $memory_limit . '</val>';
echo '<ok>' . ($ok ? 1 : 0) . '</ok>';
echo '</phpmem>';

请注意上述代码仅为示意,请勿忘记处理以下情况:-1(无内存限制),仅限整数值(以字节为单位),G(以千兆字节为单位),k/m/g(以千字节、兆字节、千兆字节为单位,因为简写大小写不敏感)等。


6
提供的正则表达式不完整、不精确,会导致在不同的安装环境下产生错误的结果。 - hakre
ini_get()函数在某些服务器中会抛出异常,您是否对此进行了任何调整? - Disapamok
请记得处理内存限制为-1的情况。 - Kieran
'$ok = ($memory_limit >= 640 * 1024 * 1024); // at least 64M?' 你的意思是至少要640M吗? - temirbek

29

1. PHP-CLI:

用于检查ini的命令行:

$ php -r "echo ini_get('memory_limit');"

或者检查 php-cli 信息并使用 grep 命令查找 memory_limit 的值:

$ php -i | grep "memory_limit"

2. PHP-FPM:

将此行粘贴到index.php任何可以在浏览器上查看的PHP文件中,然后检查结果:

<?php echo ini_get('memory_limit');

另一种方式是使用 phpinfo() 函数:

<?php phpinfo();

然后查找 memory_limit 的值 在这里输入图片描述


6
这是FYI的内容,它返回PHP CLI版本的内存限制,但您的nginx/apache将使用"其他" PHP进程,即PHP的fpm版本(不知道如何描述)。最好在两个.ini文件中手动检查:/etc/php/7.4/cli/php.ini/etc/php/7.4/fpm/php.ini - Sliq

16

这里有另一种更简单的方法来检查。

$memory_limit = return_bytes(ini_get('memory_limit'));
if ($memory_limit < (64 * 1024 * 1024)) {
    // Memory insufficient      
}

/**
* Converts shorthand memory notation value to bytes
* From http://php.net/manual/en/function.ini-get.php
*
* @param $val Memory size shorthand notation string
*/
function return_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    $val = substr($val, 0, -1);
    switch($last) {
        // The 'G' modifier is available since PHP 5.1.0
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }
    return $val;
}

2
这个怎么样?$bytes = (int)$mem * 1024 ** ['k' => 1, 'm' => 2, 'g' => 3][strtolower($mem)[-1]] ?? 0; - kaluzki

8

这是一篇很老的帖子,但我还是想在这里留下它:

/* converts a number with byte unit (B / K / M / G) into an integer */
function unitToInt($s)
{
    return (int)preg_replace_callback('/(\-?\d+)(.?)/', function ($m) {
        return $m[1] * pow(1024, strpos('BKMG', $m[2]));
    }, strtoupper($s));
}

$mem_limit = unitToInt(ini_get('memory_limit'));

4

不是非常精确但更简单的解决方案:

$limit = str_replace(array('G', 'M', 'K'), array('000000000', '000000', '000'), ini_get('memory_limit'));
if($limit < 500000000) ini_set('memory_limit', '500M');                     

如果您将 K 视为 2^10,它将无法工作。因此,它并不是非常通用。但为这一发明点赞。 - elixon
这个很好用,因为在第二行比较中你可以有同样的简化。到目前为止,我已经在几百个带有图像修改插件的网站上使用了它 - 所需的内存量从来不是非常精确的,所以我总是检查比需要的数量多30%,然后1024和1000之间的差异只是一个舍入误差 :) - Rauli Rajande

4

如果您对CLI内存限制感兴趣:

cat /etc/php/[7.0]/cli/php.ini | grep "memory_limit"

FPM / "普通"

cat /etc/php/[7.0]/fpm/php.ini | grep "memory_limit"

4
只要您的数组$phpinfo['PHP Core']['memory_limit']包含memory_limit的值,它就会执行以下操作:
  • 该值的最后一个字符可以表示简写符号。如果它是无效的,则被忽略。
  • 字符串的开头以 PHP 特定的方式转换为数字:忽略空格等。
  • 数字和简写符号(如果有)之间的文本将被忽略。

例如:

# Memory Limit equal or higher than 64M?
$ok = (int) (bool) setting_to_bytes($phpinfo['PHP Core']['memory_limit']) >= 0x4000000;

/**
 * @param string $setting
 *
 * @return NULL|number
 */
function setting_to_bytes($setting)
{
    static $short = array('k' => 0x400,
                          'm' => 0x100000,
                          'g' => 0x40000000);

    $setting = (string)$setting;
    if (!($len = strlen($setting))) return NULL;
    $last    = strtolower($setting[$len - 1]);
    $numeric = (int) $setting;
    $numeric *= isset($short[$last]) ? $short[$last] : 1;
    return $numeric;
}

与简写符号相关的详细信息在PHP手册的FAQ条目中概述,极端细节是一些PHP内存拉伸乐趣的协议的一部分。

如果设置为-1,PHP不会限制这里,但系统会。因此,您需要决定安装程序如何处理该值。


这是紧凑的代码,但在PHP 7.1+下会出现错误:$numeric = 0 + $setting;抛出异常,因为由于后缀,$setting不是数字值(消息为“[...]中遇到了一个非格式良好的数字值”)。在至少7.2中,可以改用以下代码:$numeric = (int)$setting; - Gabriel Magana
@GabrielMagana:说得好,我写那个代码已经有一段时间了,使用(int)转换比0+更可取。我编辑了答案。 - hakre

2
感谢您的启发。
我曾经遇到过同样的问题,但是我没有直接从互联网上复制粘贴某些函数,而是为此编写了一个开源工具。请随意使用它或提供反馈!
只需使用Composer安装它,然后像这样获取当前PHP内存限制: https://github.com/BrandEmbassy/php-memory
$configuration = new \BrandEmbassy\Memory\MemoryConfiguration();
$limitProvider = new \BrandEmbassy\Memory\MemoryLimitProvider($configuration);
$limitInBytes = $memoryLimitProvider->getLimitInBytes();

0

这就是答案

您可以检查内存是否为无限大于64M

<?php
    // is memory unlimited ? 
    function kdev_is_memory_unlimited ($memory_limit = null){
        if(empty($memory_limit))
            $memory_limit = ini_get('memory_limit');
        return  (is_numeric($memory_limit) && (int)$memory_limit < 0) ? true : false;
    }
    // Get Size of Memory As MB
    function get_memory_size(){
        $memory_limit = ini_get('memory_limit');
        $unlimited = kdev_is_memory_unlimited();
        if ($unlimited){
            return true; // is unlimited!
        }else if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) {
            if ($matches[2] == 'K') {
                $memory_limit = $matches[1] / 1024; 
            }else if ($matches[2] == 'G') {
                $memory_limit = $matches[1] * 1024; 
            }else{
                $memory_limit = $matches[1];
            }
        }
        return $memory_limit;
    }

通过我们的函数获取内存大小
    $memory = get_memory_size(); 

条件示例 如果此内存是无限的或大于64 M
    if(kdev_is_memory_unlimited() || $memory >= 64)
    {
            echo "Memory Checked! Your MEMORY is " . $memory."M <br>";
    }

考试2,内存是无限的还是有整数限制?
    $is_memory_pass = (kdev_is_memory_unlimited() || $memory >= 64);

考试3,只有记忆是无限的。
    $is_memory_unlimited = kdev_is_memory_unlimited();

考试4,记忆仅仅是有限的,而且我们有很多东西要记住。
    $is_memory_limited = (is_numeric($memory) && $memory >= 64);

考试4,或者
    $is_memory_limited = (!kdev_is_memory_unlimited() && $memory >= 64);

检查结果
    echo $is_memory_pass ? "MEMORY is " . $memory."M, Thaats enough!!!" : 'You momery is lower than 64M. please increase it <br>';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接