oci_free_statement doesn't always free up cursors. I had a query where I performed the following functions in a loop:

OCIParseOCIExecuteOci_fetch_assoc(Grab some field values)OciFreeStatement

I didn't specify the use of a cursor, but ran into a "maximum open cursors exceeded" error. Within my code, I had one "select * from table_with_lobs" query. When I changed the query to be "select a, b, c, from table_with_lobs" (where I specified the actual column names and where those columns were not LOB fields) the error message went away and I didn't have to resort to upping the max_open_cursors value in Oracle.