简体   繁体   English

PHP 致命错误允许内存大小耗尽

[英]PHP Fatal error allowed memory size exhausted

I'm writing a codeigniter application, upon doing a query i get hit with the following fatal error.我正在编写一个 codeigniter 应用程序,在执行查询时遇到以下致命错误。

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in /var/www/html/cryd/_zcore/core/Loader.php on line 262致命错误:在第 262 行的 /var/www/html/cryd/_zcore/core/Loader.php 中允许的 134217728 字节的内存大小耗尽(试图分配 262144 字节)

I could increase the allowed memory size, but it seems that the issue could be much more graver, that if it is a memory leak, i'd just be giving php more memory to play around with.我可以增加允许的内存大小,但似乎问题可能更严重,如果它是内存泄漏,我只是给 php 更多内存来玩。 The query is not even that intensive, it just returns one row of data.查询甚至没有那么密集,它只返回一行数据。

Here is my controller这是我的控制器

    <?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Invest_webhook extends CI_Controller {


    private $web_msg = null;
    private $proceed = 1;
    private $data = null;
    private $receive = null;
    private $complete = 0;
    private $member = null;
    private function loadPage($page,$data=null){
        $data = array_merge($data,$this->lang->language);
        $this->parser->parse('dashboard/header',$data);
        $this->parser->parse('dashboard/'.$page);
        $this->parser->parse('dashboard/footer');
    }

    public function webhook(){
        echo memory_get_peak_usage()."<br/>";
        //$update = file_get_contents("php://input");
        //$update = json_decode($update,true);

        $update = array(
            'notification_id' => '57233292b6a3d133e9c83822',
            'delivery_attempt' => 1,
            'type' => 'address',
            'data' => Array(
                'network' => "BTCTEST",
                'address' => '2N1jfZt8Uc721FAWNjdVpQZjfTxeG271RKy',
                'balance_change' => 1.00000000,
                'amount_sent' => 0.00000000,
                'amount_received' => 1.00000000,
                'txid' => '',
                'confirmations' => 4,
                'is_green' => false
            ),
            'created_at' => 1497176944
        );

        $data = $this->get_investment_data($update['data']['address']);
        if(!$data){
            die('This address does not exist');
        }

        $this->data = $data[0];
        $this->member = $this->get_member_data($this->data['tid']);

        //Start the process to verify transaction and credit investment
        $this->verify_investment();
        $this->update_investment();

        //$parameter = $this->web_msg;
        //include APPPATH."libraries/telegrambotv2.php";
        //$bot = new Telegram('331263599:AAEpHNAdyN1X5TenBk_QkJdt7xfwzDI6YeQ','bot');

        echo $this->web_msg."<br/>";        
    }

    private function verify_investment(){
        include APPPATH."/libraries/BlockIo.php";
        $this->load->config('block');
        $block = new BlockIo($this->config->item('api_token'),$this->config->item('api_secret'));
        $address = ($this->data['address']);
        $receive = $block->get_address_balance(array('addresses' => $address));

        $receive = $receive->data->available_balance;


        $expect = $this->data['inv'];

        settype($receive,'float');
        settype($expect,'float');
        echo '<br/>'.$receive."<br/>".$expect."<br/>";
        if($receive == $expect){

            $this->receive = $receive;
            return true;
        }
        $this->proceed = 0;
        $this->web_msg = 'inv_mismatch';
        return false;
    }

    private function get_member_data($tid){
        $this->load->model('invest_model','invest');
        return $this->get_member_data($tid);
    }

    private function update_investment(){
        if(!$this->proceed){
            return;
        }
        $this->load->model('invest_model','invest');

        $einv = $this->member['inv'];


        settype($einv,'float');

        $new_inv = $einv + $this->receive;
        $this->member['inv'] = $new_inv;
        $this->member['last_inv'] = 'NOW()';
        $this->data['confirmed'] = 1;

        if($this->invest->update_investment($this->data,$this->member)){
            $this->web_msg = 'inv_complete';
            $this->complete = 1;
            return true;
        } else {
            $this->proceed = 0;
            $this->web_msg = 'inv_unx_err';
            return false;
        }
    }

    private function get_investment_data($address){
        $this->load->model('invest_model','invest');
        return $this->invest->investment_data($address);
    }

    private function log($text){
        $file = fopen(APPPATH."/logs/investments/log.log",'a');
        fwrite($file,$text);
        fwrite($file,"\n");
        fclose($file);
    }
}

and here is my model这是我的模特

    <?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Invest_model extends CI_Model {
    public function __construct(){
        parent::__construct();
    }

    public function investment_data($address){
        $this->db->where('address',$address);
        $this->db->where('confirmed',0);
        $f = $this->db->get('investments');
        return $f->result_array();
    }

    public function current_investment($tid){
        $this->db->select('inv');
        $this->db->where('tid',$tid);
        $f = $this->db->get('users');
        $f = $f->row_array();
        return $f;
    }

    public function get_member_data($tid){
        echo "<hr/>";
        echo memory_get_peak_usage()."<br/>";
        $this->db->where('tid',$tid);
        echo memory_get_peak_usage()."<br/>";
        $f = $this->db->get('users');
        echo memory_get_peak_usage()."<br/>";
        return $f->row_array();
    }

    public function update_investment($inv,$member){
        $this->db->trans_begin();
        $this->db->set($inv);
        $this->db->where('address',$inv['address']);
        $this->db->update('investments');
        $this->db->set($member);
        $this->db->where('tid',$member['tid']);
        $this->db->update('users');
        if($this->db->trans_status() === FALSE){
            $this->db->trans_rollback();
            return false;
        } else {
            $this->db->trans_commit();
            return true;
        }
    }

}

I am not as to where i can optimize this further, its pretty simple and straight forward, if its a problem in my logical appraoch, hopefully a better mind than mine will be able to spot and guide me further.我不知道我可以在哪里进一步优化它,它非常简单直接,如果它在我的逻辑方法中存在问题,希望比我更好的头脑能够发现并进一步指导我。

Thanks in advance.提前致谢。

Your code looks fine.您的代码看起来不错。 Check if some function is getting called repeatedly.检查某些函数是否被重复调用。

You could use你可以使用

ini_set('memory_limit', '-1');

as a temporary solution.作为临时解决方案。 or just increase the memory_limit或者只是增加memory_limit

Chceck you php.ini file.检查你的php.ini文件。 If it is in the below form,如果是下面的形式,

memory_limit=8G

Change that in the form of MBMB的形式更改它

memory_limit=8192M

You can also do it in your code like你也可以在你的代码中这样做

ini_set('memory_limit', '8192M'); 

Put this line on your codeigniter's index.php.将此行放在您的 codeigniter 的 index.php 中。 So it will be affected for whole project.所以它会影响整个项目。

ini_set('memory_limit', '-1');

Note: This is just a quick fix.注意:这只是一个快速修复。 This bug has not been resolved in php itself.这个错误在 php 本身还没有解决。

If anybody else has this problem:如果其他人有这个问题:

Make sure your memory size in php.ini has an M after the number.确保 php.ini 中的内存大小在数字后有一个 M。

I had 512 in there....when I changed it to 512M.....no more problem.我有 512 在那里....当我把它改成 512M.....没问题了。

z z

If you want to know where the memory goes you should look into PHP memory profiling:PHP memory profiling如果您想知道内存去了哪里,您应该查看 PHP 内存分析:PHP 内存分析

Personally I would just increase the PHP max_memory to 256MB and see if it's enough;)就我个人而言,我只是将 PHP max_memory 增加到 256MB,看看是否足够;)

The problem occurs because a private method kept calling itself over and over again until the allocated memory is exhausted and the script stops execution出现这个问题是因为一个私有方法一直在不断地调用自己,直到分配的内存耗尽并且脚本停止执行

private function get_member_data($tid){
    return $this->get_member_data($tid);
}

This is a stupid human error, the above method should have been re-written as below这是一个愚蠢的人为错误,上面的方法应该重写如下

private function get_member_data($tid){
//Call to model method
    return $this->invest->get_member_data($tid);
}

Sorry, and thanks everyone.对不起,谢谢大家。

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

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