Somewhere in this code seems to be a memory leak. A couple of users were exceeding 512Mb and I'm not sure how.
Adapted the following SO code to try and test memory usage of each function on the (OpenCart extension) page:
public function mem_test($func_name){
declare(ticks=1);
$handle = fopen("/Users/mikekilmer/Sites/mzoo/dev/php/open_cart_memory.txt", "a+");
$mem = memory_get_usage();
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
fwrite($handle, $bt[0]["file"]."\t: ".$func_name." :".$bt[0]["line"]."\t".$mem."\n");
$vars = get_defined_vars();
foreach($vars as $var){
if(is_array($var)){
foreach($var as $v){
fwrite($handle, implode(", ", $v)." (in array) \n");
}
}else{
fwrite($handle, $var."\n");
}
}
}
All of which are returning less than 1MB (around 700000 - 900000). Added the get_defined_vars()
to see if there were some large variables being toted around, which returns four small variables.
Here is the offending code:
public function alert_stock($pid, $qtd) {
$this->mem_test("alert_stock");
$qry = $this->db->query("SELECT quantity, model FROM " . DB_PREFIX . "product WHERE product_id = '" . $pid . "'");
if ($qry->row['quantity'] < 5) {
$mail = new Mail($this->config->get('config_mail_protocol'), $this->config->get('config_smtp_host'), $this->config->get('config_smtp_username'), html_entity_decode($this->config->get('config_smtp_password'), ENT_QUOTES, 'UTF-8'), $this->config->get('config_smtp_port'), $this->config->get('config_smtp_timeout'));
$mail->setTo($this->config->get('config_email'));
$mail->setFrom($this->config->get('config_email'));
$mail->setSender($this->config->get('config_email'));
$mail->setSubject('Low Stock on: ' . $qry->row['model']);
$mail->setText('Low Stock on: ' . $qry->row['model'] . "\n" . $qry->row['quantity'] . " remaining.\nThank you for your great work and have a wonderful day.");
$mail->send();
}
}
public function sub_stock($pid, $qtd, $chave) {
$this->mem_test("sub_stock");
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value SET quantity = (quantity - " . (int)$qtd . ") WHERE product_option_value_id = '" . (int)$chave . "' AND subtract = '1'");
$this->db->query("UPDATE " . DB_PREFIX . "product SET quantity = (quantity - " . (int) $qtd . ") WHERE product_id = '" . (int) $pid . "' AND subtract = '1'");
}
public function upd_stock($key,$qty) {
$this->mem_test("upd_stock");
$products = $this->getProducts();
$pid = $products[$key]['product_id'];
$qtd = $products[$key]['quantity'];
if ((int) $qty != (int) $qtd) {
if ($products[$key]['option']) {
$opt_id = $products[$key]['option'][0]['product_option_value_id'];
if ($qty > $qtd) {
$qtx = (int) $qty - (int) $qtd;
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value SET quantity = (quantity - " . (int) $qtx . ") WHERE product_option_value_id = '" . (int) $opt_id . "' AND subtract = '1'");
} else {
$qtx = (int) $qtd - (int) $qty;
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value SET quantity = (quantity + " . (int) $qtx . ") WHERE product_option_value_id = '" . (int) $opt_id . "' AND subtract = '1'");
}
}
if ($qty > $qtd) {
$qtx = (int) $qty - (int) $qtd;
$this->db->query("UPDATE " . DB_PREFIX . "product SET quantity = (quantity - " . (int) $qtx . ") WHERE product_id = '" . (int) $pid . "' AND subtract = '1'");
} else {
$qtx = (int) $qtd - (int) $qty;
$this->db->query("UPDATE " . DB_PREFIX . "product SET quantity = (quantity + " . (int) $qtx . ") WHERE product_id = '" . (int) $pid . "' AND subtract = '1'");
}
}
}
public function add_stock($key) {
$this->mem_test("add_stock");
$products = $this->getProducts();
print_r($products);
die();
$pid = $products[$key]['product_id'];
$qtd = $products[$key]['quantity'];
if ($products[$key]['option']) {
$opt_id = $products[$key]['option'][0]['product_option_value_id'];
$this->db->query("UPDATE " . DB_PREFIX . "product_option_value SET quantity = (quantity + " . (int) $qtd . ") WHERE product_option_value_id = '" . (int) $opt_id . "' AND subtract = '1'");
}
$this->db->query("UPDATE " . DB_PREFIX . "product SET quantity = (quantity + " . (int) $qtd . ") WHERE product_id = '" . (int) $pid . "' AND subtract = '1'");
}
Does anyone see anything in the code that might be causing a memory leak, or can offer suggestions for further testing/investigating?