简体   繁体   English

get_file_content()耗尽了允许的内存大小(读取.dat文件)

[英]get_file_content() exhausted allowed memory size(reading .dat file)

I am in trouble while running my php script. 我在运行PHP脚本时遇到麻烦。

I am try to read data from a .dat file by using get_file_content() 我尝试使用get_file_content().dat文件读取数据

Here is my code: 这是我的代码:

$file = 'abc.dat'; $data = file_get_contents($file);

But while it giving me error like 但是虽然它给我错误

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 2097152 bytes) in /.... 致命错误:/ ....中已用完的允许内存大小为67108864字节(尝试分配2097152字节)。

I tried many solutions for it like ini_set('memory_limit', '128M'); 我尝试了很多解决方案,例如ini_set('memory_limit','128M'); , init_set('maximum_exec_time', '0'); init_set('maximum_exec_time','0');

But IT's not working for me.... 但是IT不能为我工作。

I have uploaded my php file on one of webhost. 我已经将我的php文件上传到了一个虚拟主机上。 While Everything works smooth when i run the script on localhost. 当我在本地主机上运行脚本时,一切都会顺利进行。

Can anyone help me please...?? 谁能帮我...? Is there any other way for read my long file.??? 还有其他方法可以读取我的长文件。

Edited: 编辑:

Yes, i need realy need whole data in one array. 是的,我真的需要在一个数组中存储整个数据。

The concept behind code is Face Detection and comparison in PHP. 代码的概念是PHP中的人脸检测和比较 Here is the code for Face Detection, PLEASE GIVE ME ANY SUGGESTiON..!! 这是人脸检测的代码,请给我任何建议.. !!

<?php


ini_set('max_execution_time', 123456);

class FaceDetector { 类FaceDetector {

protected $detection_data;
protected $canvas;
protected $face;
private $reduced_canvas;

public function __construct($detection_file = 'detection1.dat')
{
    if (is_file($detection_file)) {

        $this->detection_data = file_get_contents($detection_file);

    } else {
        throw new Exception("Couldn't load detection data");
    }
}


public function faceDetect($file)
{
    if (is_resource($file)) {

        $this->canvas = $file;

    } elseif (is_file($file)) {

        $this->canvas = imagecreatefromjpeg($file);

    } else {

        throw new Exception("Can not load $file");
    }

    $im_width = imagesx($this->canvas);
    $im_height = imagesy($this->canvas);

    //Resample before detection?
    $ratio = 0;
    $diff_width = 320 - $im_width;
    $diff_height = 240 - $im_height;
    if ($diff_width > $diff_height) {
        $ratio = $im_width / 320;
    } else {
        $ratio = $im_height / 240;
    }

    if ($ratio != 0) {
        $this->reduced_canvas = imagecreatetruecolor($im_width / $ratio, $im_height / $ratio);

        imagecopyresampled(
            $this->reduced_canvas,
            $this->canvas,
            0,
            0,
            0,
            0,
            $im_width / $ratio,
            $im_height / $ratio,
            $im_width,
            $im_height
        );

        $stats = $this->getImgStats($this->reduced_canvas);

        $this->face = $this->doDetectGreedyBigToSmall(
            $stats['ii'],
            $stats['ii2'],
            $stats['width'],
            $stats['height']
        );

        if ($this->face['w'] > 0) {



            $this->face['x'] *= $ratio;
            $this->face['y'] *= $ratio;
            $this->face['w'] *= $ratio;

        }
    } else {
        $stats = $this->getImgStats($this->canvas);


        $this->face = $this->doDetectGreedyBigToSmall(
            $stats['ii'],
            $stats['ii2'],
            $stats['width'],
            $stats['height']
        );
    }

    return ($this->face['w'] > 0);
}


public function toJpeg()
{
    $color = imagecolorallocate($this->canvas, 255, 0, 0); //red

    imagerectangle(
        $this->canvas,
        $this->face['x'],
        $this->face['y'],
        $this->face['x']+$this->face['w'],
        $this->face['y']+ $this->face['w'],
        $color
    );
    $image = imagecreatefromjpeg('lena512color.jpg');
    $filename = './3/cropped_whatever1.JPG';
    //$original=imagejpeg($this->canvas);
    $cropped = imagecreatetruecolor($this->face['w']+5, $this->face['w']+5);
    //imagecopy($cropped, $original, 0, 0, $this->face['x'],$this->face['y'], $this->face['x']+$this->face['w'], $this->face['y']+ $this->face['w']);
    header('Content-type: image/jpeg');

    $im_width = imagesx($this->canvas);
    $im_height = imagesy($this->canvas);

    $start_x=$im_width-($im_width-$this->face['x']);
    $start_y=$im_height-($im_height-$this->face['y']);

    $result=imagecopy ( $cropped , $image , 0 , 0, $start_x , $start_y , $this->face['w']+5, $this->face['w']+5);
    //print $result;
    imagejpeg($cropped);
    imagejpeg($cropped, $filename, 100);
}

public function toJson()
{
    return json_encode($this->face);
}

public function getFace()
{
    return $this->face;
}

protected function getImgStats($canvas)
{
    $image_width = imagesx($canvas);
    $image_height = imagesy($canvas);
    $iis =  $this->computeII($canvas, $image_width, $image_height);
    return array(
        'width' => $image_width,
        'height' => $image_height,
        'ii' => $iis['ii'],
        'ii2' => $iis['ii2']
    );
}

protected function computeII($canvas, $image_width, $image_height)
{
    $ii_w = $image_width+1;
    $ii_h = $image_height+1;
    $ii = array();
    $ii2 = array();

    for ($i=0; $i<$ii_w; $i++) {
        $ii[$i] = 0;
        $ii2[$i] = 0;
    }

    for ($i=1; $i<$ii_h-1; $i++) {
        $ii[$i*$ii_w] = 0;
        $ii2[$i*$ii_w] = 0;
        $rowsum = 0;
        $rowsum2 = 0;
        for ($j=1; $j<$ii_w-1; $j++) {
            $rgb = ImageColorAt($canvas, $j, $i);
            $red = ($rgb >> 16) & 0xFF;
            $green = ($rgb >> 8) & 0xFF;
            $blue = $rgb & 0xFF;
            $grey = (0.2989*$red + 0.587*$green + 0.114*$blue)>>0;  // this is what matlab uses
            $rowsum += $grey;
            $rowsum2 += $grey*$grey;

            $ii_above = ($i-1)*$ii_w + $j;
            $ii_this = $i*$ii_w + $j;

            $ii[$ii_this] = $ii[$ii_above] + $rowsum;
            $ii2[$ii_this] = $ii2[$ii_above] + $rowsum2;
        }
    }
    return array('ii'=>$ii, 'ii2' => $ii2);
}

protected function doDetectGreedyBigToSmall($ii, $ii2, $width, $height)
{
    $s_w = $width/20.0;
    $s_h = $height/20.0;
    $start_scale = $s_h < $s_w ? $s_h : $s_w;
    $scale_update = 1 / 1.2;
    for ($scale = $start_scale; $scale > 1; $scale *= $scale_update) {
        $w = (20*$scale) >> 0;
        $endx = $width - $w - 1;
        $endy = $height - $w - 1;
        $step = max($scale, 2) >> 0;
        $inv_area = 1 / ($w*$w);
        for ($y = 0; $y < $endy; $y += $step) {
            for ($x = 0; $x < $endx; $x += $step) {
                $passed = $this->detectOnSubImage($x, $y, $scale, $ii, $ii2, $w, $width+1, $inv_area);
                if ($passed) {
                    return array('x'=>$x, 'y'=>$y, 'w'=>$w);
                }
            } // end x
        } // end y
    }  // end scale
    return null;
}

protected function detectOnSubImage($x, $y, $scale, $ii, $ii2, $w, $iiw, $inv_area)
{
    $mean  = ($ii[($y+$w)*$iiw + $x + $w] + $ii[$y*$iiw+$x] - $ii[($y+$w)*$iiw+$x] - $ii[$y*$iiw+$x+$w])*$inv_area;

    $vnorm = ($ii2[($y+$w)*$iiw + $x + $w]
              + $ii2[$y*$iiw+$x]
              - $ii2[($y+$w)*$iiw+$x]
              - $ii2[$y*$iiw+$x+$w])*$inv_area - ($mean*$mean);

    $vnorm = $vnorm > 1 ? sqrt($vnorm) : 1;

    $passed = true;
    for ($i_stage = 0; $i_stage < count($this->detection_data); $i_stage++) {
        $stage = $this->detection_data[$i_stage];
        $trees = $stage[0];

        $stage_thresh = $stage[1];
        $stage_sum = 0;

        for ($i_tree = 0; $i_tree < count($trees); $i_tree++) {
            $tree = $trees[$i_tree];
            $current_node = $tree[0];
            $tree_sum = 0;
            while ($current_node != null) {
                $vals = $current_node[0];
                $node_thresh = $vals[0];
                $leftval = $vals[1];
                $rightval = $vals[2];
                $leftidx = $vals[3];
                $rightidx = $vals[4];
                $rects = $current_node[1];

                $rect_sum = 0;
                for ($i_rect = 0; $i_rect < count($rects); $i_rect++) {
                    $s = $scale;
                    $rect = $rects[$i_rect];
                    $rx = ($rect[0]*$s+$x)>>0;
                    $ry = ($rect[1]*$s+$y)>>0;
                    $rw = ($rect[2]*$s)>>0;
                    $rh = ($rect[3]*$s)>>0;
                    $wt = $rect[4];

                    $r_sum = ($ii[($ry+$rh)*$iiw + $rx + $rw]
                              + $ii[$ry*$iiw+$rx]
                              - $ii[($ry+$rh)*$iiw+$rx]
                              - $ii[$ry*$iiw+$rx+$rw])*$wt;

                    $rect_sum += $r_sum;
                }

                $rect_sum *= $inv_area;

                $current_node = null;

                if ($rect_sum >= $node_thresh*$vnorm) {

                    if ($rightidx == -1) {

                        $tree_sum = $rightval;

                    } else {

                        $current_node = $tree[$rightidx];

                    }

                } else {

                    if ($leftidx == -1) {

                        $tree_sum = $leftval;

                    } else {

                        $current_node = $tree[$leftidx];
                    }
                }
            }

            $stage_sum += $tree_sum;
        }
        if ($stage_sum < $stage_thresh) {
            return false;
        }
    }
    return true;
}

} }

You you really need all of the file loaded into memory at the same time? 真的需要将所有文件同时加载到内存中吗? If so, then you need to talk to your host about getting your memory limit increased, and they will probably tell you to upgrade your plan or move to a VPS. 如果是这样,那么您需要与主机商谈增加内存限制的问题,他们可能会告诉您升级计划或迁移到VPS。

Ideally, you should be working with you data in the smallest chunks for whatever you're doing. 理想情况下,无论您做什么,都应该以最小的块使用数据。 eg: 例如:

$myfile = '/path/to/file.dat';
$processed_data = array();

if( ! $fh = fopen($myfile, 'r') ) { die("could not open $myfile."); }

while( $line = fgets($fh) ) {
  $processed_data[] = processing_function($line);
}
fclose($fh);

Where processing_function() is only returning the exact data you need, thus keeping your memory usage to a minimum. 其中processing_function()仅返回所需的确切数据,从而将内存使用量降至最低。

If you posted the code that details what you're actually doing with this data people might be able to suggest a better way to go about it. 如果您发布的代码详细说明了您实际使用此数据所做的工作,那么人们可能会提出更好的解决方案。

It seems like your memory_limit is set to 64MB. 看来您的memory_limit设置为64MB。 Can you confirm that your memory limit is indeed 128M when the script is running: 您是否可以在运行脚本时确认内存限制确实为128M:

var_dump(ini_get('memory_limit'));

If it is not 128M, what hosting are you using? 如果不是128M,您正在使用什么主机? Usually this can be upped by htaccess: 通常,这可以通过htaccess进行升级:

php_value memory_limit 128M

If that doesn't fix it, you will need to contact your hosting provide (we can't help you with exact ode if you don't want to disclose the name of your hosting provider) to up the memory limit. 如果仍不能解决问题,则需要联系托管服务提供商(如果您不想透露托管服务提供商的名称,我们将无法为您提供确切的帮助)以提高内存限制。

You can use buffer like here: Alternative way to read raw I/O stream in PHP If you could process the data in the while cycle, then: 您可以像这样使用缓冲区: 在PHP中读取原始I / O流的另一种方法如果可以在while周期中处理数据,则:

$f = fopen('abc.dat', 'r');
$data = '';
while ($buffer =  fread($f, 8192)) do_some_processing($buffer);
fclose($f);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM