I'm having several problems with an implementation in php for working with mongoDB
My case is that I made a function which recover an mongoDB database in $_SESSION['mongoDb'] variable, selects a collection and then use the function find($where, $fields).
My error is
Fatal error: Call to a member function find() on a non-object in...
I've tried checking mongodb php driver and others but the problem still existing...
EDIT: More info about.
Thanks for the post Eternal1, it's a bit confusing because same code is working in a production server but not my localhost XAMPP server.
For the one who ask me for the code, here you are:
public function generic_select_mongo ($collection, $fields, $where, $order, $limit)
{
$mongoBd = $_SESSION['mongoBd'];
$col = $mongoBd->$collection;
$res = $col->find($where, $fields);
$res->sort($order);
$result = array();
while ($docs = $res->getNext())
{
$result[] = $docs;
}
return $result;
}
I'm gonna investigate about Session in php. Sorry for the answer with additional info.
MongoDB connection, as other DB connections, is of resource type, which can't be serialized and therefore properly stored into session. PHP session manual states:
Some types of data can not be serialized thus stored in sessions. It
includes resource variables or objects with circular references (i.e.
objects which passes a reference to itself to another object)
PHP Sessions
Related
I am facing a very strange Session problem on PHP 8(even though it doesn't work with 7.4 also, but on 7.3 it works great).
What i do is i cerated a class where i set up the Export Object and store it on Session $_SESSION['AjaxExport'][sessionid]. Now i want to load this object stored by reference on the ifram which processes the export. When i session_start it fails to load the session at all.
AjaxExporter Class
private function ExportIntro(){
while (ob_end_clean());
// remove any old ajax exports
unset($_SESSION['AjaxExport']);
$rnd = rand(1, 99999);
$this->sessionid = uniqid($rnd, true);
$_SESSION['AjaxExport'][$this->sessionid] = &$this;
Above, loads the modal where the user gets a link to start the Export. by clicking on that link i load the Below function which loads the Object from Session and start exporting by auto-reloading to export in process like (10%-20%...)
class NG_ADMIN_AJAXEXPORTER_CONTROLLER extends NG_ADMIN_BASE {
public function Export()
{
$sessionid = '';
if (!empty($_REQUEST['exportsess']) && isset($_SESSION['AjaxExport'][$_REQUEST['exportsess']])) {
$sessionid = $_REQUEST['exportsess'];
}
else {
return;
}
$exporter = &$_SESSION['AjaxExport'][$sessionid];
$exporter->sessionid = $sessionid;
$exporter->HandleToDo($_REQUEST['action']);
}
}
When the process tries to start, i get no session at all.
session_start(): Failed to decode session object. Session has been destroyed in...
Also tried to implement Seriazable on both classes but that not seam to work either because, even though the object is stored, there are no values in its properties so it's useless (even though i used reference &).
As i mentioned above, this code works just fine in php 7.3, the problems started since 7.4 and php 8
So, finally figured this out.
As a friend told me that if a class has static properties serialization may not work and i was loading Twig v3 on parent class, so i destroyed all the properties that may contained the "template" property from Twig and it worked.
Generally, cleaned my object to only contain the necessary sub-objects that needed to complete my exports.
I have a stored procedure that client has made.
Now I have to access it and process data in my laravel app.
I have no problems with connecting to SQL but the problems starts when passing in parameters.
Here is my code:
$connections = DB::connection('sqlsrv')
->select(EXEC [stored].[procedure].[here] $param1, $param2);
The error I got back is:
The active result for the query contains no fields
I have searched for many hours in forums and here is what I have found:
$connections = DB::connection('sqlsrv')
->select(DB::raw('EXEC [stored].[procedure].[here] $param1, $param2'));
Error I got back is:
The active result for the query contains no fields.
I have installed SQL driver and OBDC driver.
Any help would be much appreciated
Don't know if this will help but this answer suggests you put your DB::raw around just the params instead of the EXEC stored.proc.name.
So instead of
$connections = DB::connection('sqlsrv')->select(DB::raw('EXEC [stored].[procedure].[here] $param1, $param2'));
Try
$connections = DB::connection('sqlsrv')->select('EXEC stored.proc.name' . DB::raw($param1, $param2));
OK. So I found out the issue.
It turns out the client sent me over a variable with xml.
As far as I figured out from Microsoft docs then you cant pass xml as a varable because if you call the SP from an application it is gonna pass it as an array and application cant parse xml into array directly. You have to do it on your own.
What can be done instead is to pass xml as a value of an array and then take it from there.
I'm having troubles with PHP MongoCursor since I upgraded to Mongo PHP Driver from 1.5.8 to 1.6.0
The following code works well with version 1.5.8, but crashes with version 1.6
PHP version is 5.5.21., Apache version is Apache/2.4.10 (Ubuntu)
$mongoClient = new \MongoClient($serverUrl, ['readPreference'=>\MongoClient::RP_NEAREST]);
$database = $mongoClient->selectDB($dbName);
$collection = $database->selectCollection($collectionName);
// count() works fine and returns the right nb on documents
echo '<br/>count returned '.$collection->count();
// find() exectues with no error...
$cursor = $collection->find();
$documents = [];
// ...and hasNext() crashes with the Excetion below
while($cursor->hasNext()){$documents[] = $cursor->getNext();}
return $documents;
And so the hasNext() call crashes with this message :
CRITICAL: MongoException: The MongoCursor object has not been correctly initialized by its constructor (uncaught exception)...
Am I doing something wrong ?
Thanks for you help !
This may be related to a bug that was introduced in 1.6.0 regarding iteration with hasNext() and getNext(): PHP-1382. A fix has since been merged to the v1.6 branch and should be released later this week as 1.6.1.
That said, the bug regarding hasNext() was actually that the last document in the result set would be missed while iterating. If I run your original script against 1.6.0, the array contains a null value as its last element. With the fix in place, the array will contain all documents as is expected. I cannot reproduce the exception you're seeing with either version.
That exception is actually thrown from an internal checks on the C data structures, to ensure that the cursor object is properly associated with a MongoClient and socket connection. See the MONGO_CHECK_INITIALIZED() macro calls in this file. Most all of the cursor methods check that a MongoClient is associated, but hasNext() is unique in that it also checks for the socket object (I believe other methods just assume a cursor with a MongoClient also has a socket). If that exception is truly reproducible for you and you're willing to do some debugging with the extension, I'd be very interested to know which of the two checks is throwing the error.
As a side note, you should also be specifying the "replicaSet" option when constructing MongoClient. This should have the replica set name, which ensures that the driver can properly ignore connections to hosts that are not a member of the intended replica set.
I just encountered the same issue; I refactored my code to use the cursor iterator instead, ie:
foreach( $cursor as $doc ) {
$documents[] = $doc;
}
I was looking for a code example of how to implement a tailable cursor and found this question. The following code is a simple example of a tailable cursor (via the $cursor variable) which you provide on a capped mongodb collection.
$cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}
I have a really serious problem that I have not seen before.
On a website we are using opensource SQC eshop, PHP Version 5.3.3-7+squeeze15 and there is some kind of problem with variable memory I think.
SQC uses notORM and here the problem starts with fatal error "Call to function on non object notORMResult" .
So I dug deeper and found the constructor of NotORM that looks like this:
function __construct(PDO $connection, NotORM_Structure $structure = null,NotORM_Cache $cache = null) {
$this->connection = $connection;
if($_GET['test']){
var_dump($structure);
}
if (!isset($structure)) {
$structure = new NotORM_Structure_Convention;
}
if($_GET['test']){
var_dump($structure);
}
$this->structure = $structure;
if($_GET['test']){
var_dump($this->structure);
exit("1");
}
$this->cache = $cache;
}
And so the output is NULL because the constructor gets no structure param so we create an object. Second output is the object. Then we set the object to attribute and then the THIRD OUTPUT IS NULL
How is this even possible? The site was running for about year and half and no problems till yesterday. I didn't made yet any updates to php and this thing really freaks me out 'cause it's not a constant problem. It just happens sometimes after 2 hours, sometimes after 2 mins and I have really no idea why is this happening.
And btw ... this is just the start it happens across the whole script. Object attributes are set but when you want to read them they give you NULL. There is also second website running on the same server, same php same configuration without problem.
Thanks for any ideas :)
I found this interesting behavior in PHP. I can't understand why the object in session is getting updated even though I'm not explicitly storing it in session after it's been manipulated.
Can someone please enlighten me?
While the snippet below is written using Laravel 4 framework, the underlying session-related behavior is a function of PHP. Example code:
Route::get('/', function()
{
$stored = Session::get('testing');
if (!$stored)
{
$stored = new StdClass;
$stored->counter = 0;
Session::set('testing', $stored);
}
$stored->counter ++;
// Session::set('testing', $stored);
// if the above line were NOT commented out, i could understand why the counter keeps on increasing.
var_dump($stored->counter);
});
Since PHP objects are passed by reference (since PHP 5.0) and session write (if not executed directly with session_write_close() function) happens after script execution it is expected behavior from PHP itself.
So it goes as follows (I am not really speaking how exactly it goes in Laravel itself, but more in PHP's internals) :
You write object into SESSION
You change the object state
Scripts ends and write to a file happens with object changed state.
So if object is stored in session - always the latest object's state is written into session file.