0

Hi i am currntly creating a script to get data out of a odbc connection and store it in an array at the moment i get this error, i have another function called Data that does the same thing but does not put the data in to an array and that one works fine, i'm not sure what i'm doing wrong any help would be appreciated.

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 36 bytes) in

I have a similar function to this the Cycle function but it is not putting the data in to an array and it works perfectly here is that code

Public function Data() {

    $sql = "SELECT TOP 1 ReaderData.ReaderIndex, ReaderData.CardID, ReaderData.ReaderDate, ReaderData.ReaderTime, ReaderData.controllerID, Left([dtReading],10) AS [date], ReaderData.dtReading FROM ReaderData
                        WHERE ReaderData.controllerID=$this->Id AND ReaderData.CardID = 'FFFFFFF0  '
                    ORDER BY ReaderData.ReaderIndex DESC;";

    $rs = $this->Db($sql,"dtReading");

    while ($rs) {

        $this->DtReading = $rs;

        $result = strtotime($this->DtReading) + 2 * 60 * 60;

        $this->time = time() + 60 * 60 - $result;
        return round($this->time / 60, 2);
    }
}

This is the function with the error

   public function Cycle() {

    $sql = "SELECT TOP 2 ReaderData.ReaderIndex, ReaderData.CardID, ReaderData.ReaderDate, ReaderData.ReaderTime, ReaderData.controllerID, Left([dtReading],10) AS [date], ReaderData.dtReading FROM ReaderData WHERE ReaderData.controllerID=$this->Id AND ReaderData.CardID = 'FFFFFFF0  '  ORDER BY ReaderData.ReaderIndex DESC;";
    $rs = $this->Db($sql,"dtReading");
    $data = array();

    while ($rs) {
        $data[] = $this->DtReading = $rs;
    }
        // var_dump($data);
    $this->Time1 = ($data[0]);
    $this->Time2 = ($data[1]);
    $Time1E = strtotime($this->Time1) + 2 * 60 * 60;
    $Time2E = strtotime($this->Time2) + 2 * 60 * 60;
    $this->cycle = $Time1E - $Time2E;

    return round($this->cycle, 2);

This is the Db connect function

Public function Db($sql,$index) {
    $conn = new database_odbc('monitor', '', '');

    $rs = $conn->justquery($sql);
            while (odbc_fetch_row($rs)) {
       $result =  $this->val = odbc_result($rs, $index);
    return $result;
            }

Here is a Var_dump from $rs in the cycle function

string(23) "2014-07-22 06:20:30.000"
.......string(23) "2014-07-22 11:49:00.000"
.......string(23) "2014-07-22 11:52:26.000"
.......string(23) "2014-07-22 10:48:59.000"
.......string(23) "2014-07-22 11:52:24.000"  
.......string(23) "2014-07-22 11:49:09.000"
.......string(23) "2014-07-22 11:52:30.000"
.......string(23) "2014-07-22 11:53:30.000"
.......string(23) "2014-07-22 11:54:53.000"
.......string(23) "2014-07-22 11:52:38.000"
.......string(23) "2014-07-19 13:19:21.000"
.......string(23) "2014-07-22 11:23:58.000"
.......string(23) "2014-07-21 13:33:06.000"
.......string(23) "2014-06-23 11:15:43.000"

1 Answer 1

3

You've written an infinite loop in both of your first snippets:

$rs = $this->Db($sql,"dtReading");
while ($rs) {
    $data[] = $this->DtReading = $rs;
}

The Db method returns a result. Fine, but that means $rs won't be falsy (false, null, empty array/string, ...).

The while condition, then, is always true, and so you keep pushing $rs's value to $data, which will grow and grow, until there is no more memory left available for it to grow.

There are a number of other issues, which need addressing. A short list:

  • Please, subscribe to the coding standards
  • in your Db method: $result = $this->val = odbc_result($rs, $index); merely reassigns $result over and over, I suspect you want $result to be an array
  • In your first snippet: return round($this->time / 60, 2); is inside of a while loop. Why bother with a loop that won't loop?
  • Google existing DB abstraction layers. There are many out there. Spend some time learning those, instead of writing your own.

In response to your comment (on how to best loop through the results):
My experience with ODBC is rather limited, especially my experience with ODBC + PHP (No exp whatsoever). But a quick look at the docs leads me to believe that this is the way to go about your business:

$res = odbc_exec($connection, 'QUERY');
if (!$res)
    throw new RuntimeException('Query failed');
$result = array();//array of results
while($row = odbc_fetch_array($res))
{
    $result[] = $row;
}

Be careful, though, when using odbc_fetch_array, as is noted on in the docs, if your query string looks like this:

SELECT * FROM tbl;

The array returned by odbc_fetch_array will not be an associative array. All things aside SELECT * is bad form anyway, and you shouldn't use it, but if you insist, the safer (but more verbose) way would be:

$res = odbc_exec($connection, 'QUERY');
if (!$res)
    throw new RuntimeException('Query failed');//use odbc_error and odbc_errormsg!
//according to the docs, though index starts at 1, you need to do this:
$idx = 0;
$result = array();
odbc_fetch_row($res, $idx++);
while (odbc_fetch_row($res, $idx++))
{
    $row = array(
        'field1' => odbc_result($res, 'field1'),
        'field2' => odbc_result($res, 'field2'),
        'field3' => odbc_result($res, 3),//field number is fine, too
    );
    $result[] = $row;
}

For details on each of the functiosn I mentioned here, check the manual, and don't forget to have fun.

Sign up to request clarification or add additional context in comments.

5 Comments

Not in both snippets - Looks like in the 1st loop he returns during the 1st iteration, which is why he only has the memory issue with the second
falsy – I love that.
@user574632: Edited that just now, Had a closer look and noticed that, too
What would be the best way to run the loop?
@Oisian2: Added a couple of examples + links to documentation. Like I said in my edit: I don't have a lot of experience with ODBC, but the functions are all documented, and it seems to me to be pretty self-explanatory

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.