PHP Fatale fout toegestaan ​​geheugengrootte uitgeput

Ik schrijf een codeigniter-toepassing, na het uitvoeren van een vraag krijg ik de volgende fatale fout.

Fatale fout: toegestane geheugengrootte van 134217728 bytes uitgeput (geprobeerd   om 262144 bytes toe te wijzen) in /var/www/html/cryd/_zcore/core/Loader.php   op regel 262

Ik zou de toegestane geheugenomvang kunnen vergroten, maar het lijkt erop dat het probleem veel ernstiger zou kunnen zijn, dat als het een geheugenlek is, ik PHP meer geheugen zou geven om mee te spelen. De vraag is zelfs niet zo intensief, het geeft slechts één rij met gegevens terug.

Hier is mijn 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()."
"; //$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."
"; } 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 '
'.$receive."
".$expect."
"; 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); } }

en hier is mijn 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 "

";
        echo memory_get_peak_usage()."
"; $this->db->where('tid',$tid); echo memory_get_peak_usage()."
"; $f = $this->db->get('users'); echo memory_get_peak_usage()."
"; 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; } } }

Ik ben niet van plan om dit verder te optimaliseren, het is vrij eenvoudig en ongecompliceerd, als het een probleem is in mijn logische benadering, hopelijk zal een betere geest dan de mijne in staat zijn om mij verder te volgen en te begeleiden.

Bij voorbaat dank.

3
een ding dat srsly vreemd is - je mapstructuur /var/www/html/cryd/_zcore/core/Loader.php ziet er verkeerd uit, de Loader.php zou in [jouw_directory] systeem/kern moeten zijn/- wat is uw CI-versie?
toegevoegd de auteur sintakonte, de bron
Ik zie geen enkele of while-lus die de oorzaak zou kunnen zijn. Ook recursieve oproepen kunnen dit veroorzaken. Wat is de DB-laag die u gebruikt, bijvoorbeeld $ this-> db-> get
toegevoegd de auteur Adder, de bron
Ik was me er niet van bewust dat mysqli alles doet om $ this-> db-> where te doen, ik zou hebben geraden dat dit van een enkele DB-laag in eigen land is.
toegevoegd de auteur Adder, de bron
@Adder Bedoelt u de bestuurder die ik gebruik? zijn mysqli.
toegevoegd de auteur Haider Ali, de bron
@sintakonte de codeigniter-installatie is geconfigureerd om een ​​afzonderlijke toepassingsmap en een afzonderlijke kernmap te gebruiken. Het kernsysteem bevindt zich in _zcore terwijl alle toepassingen zich in _botadmin bevinden
toegevoegd de auteur Haider Ali, de bron

5 antwoord

Je code ziet er goed uit. Controleer of een functie herhaaldelijk wordt aangeroepen.

Je zou kunnen gebruiken

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

as a temporary solution. or just increase the memory_limit

Chceck je php.ini bestand. Als het in de onderstaande vorm is,

memory_limit=8G

Change that in the form of MB

memory_limit=8192M

Je kunt het ook in je code doen zoals

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

Zet deze regel op de index.php van uw code-afzender. Dus het zal worden beïnvloed voor het hele project.

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

Opmerking: dit is slechts een snelle oplossing. Deze bug is niet opgelost in PHP zelf.

3
toegevoegd
Nou ja, dit zou werken, maar ik vraag me af of het iets in mijn code is. Er zijn geen recursieve verbindingen met de database of iets anders.
toegevoegd de auteur Haider Ali, de bron
Ja, ik weet niet wat het veroorzaakt. Er zijn maximaal 3 oproepen naar de database om informatie op te halen uit 2-3 tabellen en vervolgens één query om bij te werken. Niets van dat gebeurt recursief. Ik moet echter vlaggen toevoegen om dit te controleren
toegevoegd de auteur Haider Ali, de bron
Een privémethode in de controller riep zichzelf steeds opnieuw totdat het toegewezen geheugen was uitgeput.
toegevoegd de auteur Haider Ali, de bron
Bedoel je, je hebt geen idee wat de oorzaak van dit probleem is?
toegevoegd de auteur phpnerd, de bron
Controleer het geheugengebruik voor en na elk gesprek.
toegevoegd de auteur phpnerd, de bron

Het probleem doet zich voor omdat een privémethode zichzelf steeds opnieuw heeft aangeroepen totdat het toegewezen geheugen is uitgeput en het script de uitvoering stopt

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

Dit is een stomme menselijke fout, de bovenstaande methode zou opnieuw moeten zijn geschreven zoals hieronder

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

Sorry, en bedankt iedereen.

0
toegevoegd

If you want to know where the memory goes you should look into PHP memory profiling: PHP memory profiling

Persoonlijk zou ik gewoon de PHP max_memory verhogen naar 256 MB en kijken of het genoeg is;)

0
toegevoegd

Als iemand anders dit probleem heeft:

zorg ervoor dat uw geheugengrootte in php.ini na het nummer een M heeft.

Ik had er 512 ... toen ik het veranderde in 512M ..... geen probleem meer.

z

0
toegevoegd