Search code examples
phpzend-frameworkodbccronibm-midrange

Zend Framework 1.12 + Crontab + odbc query - Fatal error: Allowed memory size


currently I have a developed app at Zend Zend Framework 1.12 in a server Ubuntu 14.04.2 with iSeries Access ODBC Driver 64-bit

When I manually execute the following query from a controller, I correctly receive the result:

class MaestrosController extends Zend_Controller_Action {

public function indexAction() {    
    $this->_query("SELECT OKCUNO AS VALUE, OKCUNM AS OPTION FROM OCUSMA WHERE OKCONO = 1");
}

private function _query($query) {             
    try {
        $conexion = $this->_connect();
        $result = odbc_exec($conexion, $query);
    }catch (Exception $e){
        die($e->getMessage());
    }
    $salida = array();
    while( ($row = odbc_fetch_array($result)) !== false ) {
        array_push($salida, $row);
    }
    $this->_disconect($conexion);
    return $salida;
}

private function _connect()
{
   $objConnect =  odbc_connect('EXPO', $this->odbc_user,$this->odbc_calve) or die('Connect: '.odbc_errormsg()."\n");
   return $objConnect;
}

private function _disconect($conexion)
{
   odbc_close($conexion);
}
}

However, when I execute it through contrab:

php /var/www/vhosts/core.lan/application/cronjobs/cronjob.php >> /tmp/logcron.log

cronjob.php

define("_CRONJOB_",true);
require_once('/var/www/vhosts/core.lan/httpdocs/index.php');

(...)

$this->_query("SELECT OKCUNO AS VALUE, OKCUNM AS OPTION FROM OCUSMA WHERE OKCONO = 1");

(...)

The following error message appears:

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 16815550472902410251 bytes) in /var/www/vhosts/core.lan/application/models/DbTable/M3.php on line 259. 

The line 259 corresponds to $result = odbc_exec($conexion, $query);

In order to execute through cron, my index has been configurated as follows:

(...)

$application->bootstrap();

//Cronjobs don't need all the extra's so we don't execute the bootstrap
if(!defined('_CRONJOB_') || _CRONJOB_ == false){
    $application->bootstrap()->run();
}

There is nothing else in the logs, none error message excepts the memory size.


Looking for a solution I’ve found out that if I execute the following query through contrab:

SELECT OKCUNO AS VALUE, OKCUNM AS OPTION FROM OCUSMA WHERE OKCONO = 1 FETCH FIRST 14 ROWS ONLY

It perfectly Works:

+-----------+-------------------------------------+
| VALUE     | OPTION                              |
+-----------+-------------------------------------+
| 0000001   | ANIBAL                              |
| 0000002   | MODAS                               |
| 0000003   | NOVIAS                              |
| 0000004   | ROSA                                |
| 0000005   | RC                                  |
| 0000006   | BELLAESPOSA                         |
| 0000007   | RICARDO                             |
| 0000008   | YOLANDA                             |
| 0000009   | HUELVA .                            |
| 0000010   | DROP                                |
| 0000011   | DOBADOCA                            |
| 0000013   | MARIA                               |
| 0000014   | MODA                                |
| 0000015   | HABITUS                             |
+-----------+-------------------------------------+

nevertheless, if I execute the following one a fatal error appears:

SELECT OKCUNO AS VALUE, OKCUNM AS OPTION FROM OCUSMA WHERE OKCONO = 1 FETCH FIRST 15 ROWS ONLY

If I want to see that information is shown in that line I execute isql -v EXPO and I receive the following result

+-----------+-------------------------------------+
| VALUE     | OPTION                              |
+-----------+-------------------------------------+
| 0000001   | ANIBAL                              |
| 0000002   | MODAS                               |
| 0000003   | NOVIAS                              |
| 0000004   | ROSA                                |
| 0000005   | JON                                 |
| 0000006   | BELLAESPOSA                         |
| 0000007   | CHARLES                             |
| 0000008   | YOLANDA                             |
| 0000009   | HUELVA                              |
| 0000010   | DROP                                |
| 0000011   | DOBADOCA                            |
| 0000013   | MARIA                               |
| 0000014   | MODA                                |
| 0000015   | HABITUS                             |
| 0000016   | Mª ANGELES                          |
+-----------+-------------------------------------+

I deduce the problem could come from the character ª.


I’ve read the following article in the website IBM https://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_61/rzatv/rzatvlanguageodbc.htm:

ODBC Application Character Set

The ODBC application character set is defined by the current locale's character set.

$ locale return the following:

LANG=es_ES.UTF-8
LANGUAGE=
LC_CTYPE="es_ES.UTF-8"
LC_NUMERIC="es_ES.UTF-8"
LC_TIME="es_ES.UTF-8"
LC_COLLATE="es_ES.UTF-8"
LC_MONETARY="es_ES.UTF-8"
LC_MESSAGES="es_ES.UTF-8"
LC_PAPER="es_ES.UTF-8"
LC_NAME="es_ES.UTF-8"
LC_ADDRESS="es_ES.UTF-8"
LC_TELEPHONE="es_ES.UTF-8"
LC_MEASUREMENT="es_ES.UTF-8"
LC_IDENTIFICATION="es_ES.UTF-8"
LC_ALL=

But, the command $ sudo /opt/ibm/iSeriesAccess/bin64/cwbnltbl gives me that:

cwbnltbl - Download conversion table utility
Usage: cwbnltbl source-code-page target-code-page [host] [uid] [pwd]
Linux locale codeset=UTF-8 ccsid=1208

and I do not know what to do with it.

The only information I could find and which is more or less similar than the problem I have is this post: Linux odbc Fatal error: Allowed memory size, however the solution proposed cannot help me at all.

I kindly ask somebody to give me some support in this issue.

Thanks!


Solution

  • The problem was related to the locale of the environment where the php script is executed.

    Running the following statement I could fix it:

    LANG = es_ES;
    

    If I run the following via crontab, I have no problems:

    LANG = es_ES; php -f /var/www/vhosts/core.lan/application/cronjobs/cronjob.php >> /tmp/logcron.log
    

    So the solution is to fix the php locale.