Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

odd SQL issue with fActiveRecord

posted by oliverd 8 years ago

I'm having a very strange issue with fActiveRecord that I can't figure out.

I have a User class that has a static method getGroupId. This method checks to see if $_SERVER['REMOTE_USER'] contains a value. If it does, it tries to find a user in the database with that username. Here's the relevant functions within my User class that extends fActiveRecord:

	public static function getUsername()
	{
		return isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : false;
	}
	
	public static function getGroupId()
	{
		if (!User::getUsername())
		{
			$value = 3;
		}
		else
		{
			try
			{
				$user = new User(array('name' => User::getUsername()));
				$value = $user->values['group_id'];
			}
			catch (fNotFoundException $e)
			{
				$value = 3;
			}
		}
		
		return $value;
	}

This works perfectly both on my local machine and in another dev environment. However, on the client's staging environment, it throws the following exception:

Uncaught fSQLException
----------------------
[internal function]: fTemplating->__destruct()
/usr/local/irodb/lib/flourish/fTemplating.php(86): fTemplating->placeBuffered()
/usr/local/irodb/lib/flourish/fTemplating.php(437): preg_replace('/%%fTemplating:...', 'fBuffer::startC...', '%%fTemplating::...')
/usr/local/irodb/lib/flourish/fTemplating.php(437) : regexp code(1): fTemplating->placeElement('header', '')
/usr/local/irodb/lib/flourish/fTemplating.php(316): fTemplating->placePHP('header', 'defaultHeader.p...')
/usr/local/irodb/lib/flourish/fTemplating.php(384): include('/usr/local/irod...')
/usr/local/irodb/lib/template/defaultHeader.php(91): User::getGroupId()
/usr/local/irodb/lib/class/User.php(30): fActiveRecord->__construct(Array)
/usr/local/irodb/lib/flourish/fActiveRecord.php(1127): fActiveRecord->fetchResultFromUniqueKey(Array)
/usr/local/irodb/lib/flourish/fActiveRecord.php(1740): call_user_func_array(Array, Array)
[internal function]: fDatabase->translatedQuery('SELECT * FROM %...', 'users', 'name', 'adam')
/usr/local/irodb/lib/flourish/fDatabase.php(2422): fDatabase->runQuery('SELECT * FROM "...', 'fResult')
/usr/local/irodb/lib/flourish/fDatabase.php(2228): fDatabase->executeQuery(Object(fResult))
/usr/local/irodb/lib/flourish/fDatabase.php(1445): fDatabase->checkForError(Object(fResult))
/usr/local/irodb/lib/flourish/fDatabase.php(361)
MySQL error ({false}) in SELECT * FROM "users" WHERE "name" = ''

As you can clearly see, in the fDatabase->translatedQuery call "adam" is passed as the name of the user. However, the value never appears in the actual MySQL query.

Any ideas as to what is going on?

Errors like this are usually related to the deconstruction of objects based on the order they were instantiated in. I think this is what is happening in your case, however I could be wrong. I know I've seen different behaviors with destructor execution order on different versions of PHP.

Since you are using fTemplating::buffer(), the actual printing of the template doesn't happen until the fTemplating object is destroyed. What appears to be happening is that the fDatabase connection is no longer valid when it is called. fDatabase's destructor disconnects it from the database. Thus, I believe you need to make sure your fDatabase object is being instantiated before instantiating your fTemplating object.

// Good!
$db = new fDatabase();
$template = new fTemplating();
$template->set('db', $db);

// BAD!!!
$template = new fTemplating();
$db = new fDatabase();
$template->set('db', $db);

I just updated the fTemplating documentation to reflect this edge case.

posted by wbond 8 years ago

Interesting theory but unfortunately doesn't apply to my problem as I'm already creating $db before $template.

posted by oliverd 8 years ago