Click to See Complete Forum and Search --> : Function outside of a class with a class reference


sitehatchery
02-06-2007, 06:01 PM
class EI{
function echoIt($val){
return $val;
}
}

$_ei=new EI();

function getEI(){
$val=$_ei->echoIt("Hi There");
return $val;
}

echo getEI();


I scaled this down considerably to simplify the question. I need to refer to the object inside a function which is outside of a class. How do I make this work? Again, this is very simplified - just know that I need to make it work.

sitehatchery
02-06-2007, 06:06 PM
PS I do know that I can declare the class within the function getEI(). However, the real application has multiple functions (not class-related) that need to use the methods within the EI object. I cannot redeclare a class each time I need to use a function.

sitehatchery
02-06-2007, 06:09 PM
I also know that I can wrap all my other functions in a class:

class EI{
function echoIt($val){
return $val;
}
}

class OI extends EI{
function getEI(){
$val=$this->echoIt("Hi There");
return $val;
}
}

$_oi=new OI();

echo $_oi->getEI();

pcthug
02-06-2007, 06:23 PM
Within your standalone getEI() function you're accessing a local (function scope) variable, not the global $_ei variable [object].class EI{
function echoIt($val){
return $val;
}
}

$_ei=new EI();

function getEI($obj){
$val=$obj->echoIt("Hi There");
return $val;
}

echo getEI($_ei);

sitehatchery
02-06-2007, 06:39 PM
I need a way to access the the object within a local function

sitehatchery
02-07-2007, 11:26 AM
Aha! This works:

<?php
class EI{
function echoIt($val){
return $val;
}
}

$_ei=new EI();

function getEI($_ei){
$val=$_ei->echoIt("Hi There");
return $val;
}

echo getEI($_ei);

?>

bokeh
02-07-2007, 12:04 PM
It's difficult to know what you are asking because your code seems to be going around in circles. Are you asking how to access one of your class's methods without Instantiation 1.
<?php
class EI{
function echoIt($val){
return $val;
}
}

function getEI(){
return EI::echoIt("Hi There");
}

echo getEI();

?>

1 Wikipedia - Instantiation is the process of creating a specific object which is a member or instance of a class.

sitehatchery
02-07-2007, 05:55 PM
I'm reprogramming oscommerce to use a sqlite database instead of mysql and making it compatible with default PHP 5 settings. At the same time, I am rewriting the code which forces the server to have register_globals and register_long_arrays enabled. Seems to be a bigger task than I thought, but I've found a way.

I at first instantiated a database object and wanted to use the resource throughout the script - but I came to a standstill when I ran into independent functions that needed the handle as well.

I found a way around this by passing the object variable to functions. But, I was stumped again when certain session functions were callback functions - and the object variable could not be passed.

So, my workaround was to revert back to not using a database class. Instead I just passed the database handle to the $_REQUEST array and I am now able to use it within functions and classes without having to pass it.

Is there any kind of security concern passing the database handle to the $_REQUEST array?

bokeh
02-08-2007, 10:30 AM
Why do you need the DB resource anyway? Is your script accessing two DB servers at the same time? If not you don't need the resource.Is there any kind of security concern passing the database handle to the $_REQUEST array?I can see one. Even if someone did get their hands on it what use would it be anyone?

sitehatchery
02-08-2007, 11:53 AM
You need it for the sqlite_query function. I've built a simple wrapper function which doesn't require me to enter the resource each time.

function query($query){
$result=sqlite_query($_REQUEST['dbhandle'], $query);
return $result;
}

bokeh
02-08-2007, 12:24 PM
You need it for the sqlite_query function.
sqlite_query() (http://www.php.net/sqlite_query)

Parameters
dbhandle
[...] This parameter is not required when using the object-oriented method. ...

sitehatchery
02-08-2007, 03:33 PM
I'm back to the same problem with using the object oriented method. There are quite a few stand alone functions that make calls to the database. So, using an Object variable to call the class function will not work unless I rewrite all the functions and pass the Object variable as a parameter. Actually, a couple of days ago, I did rewrite all the functions. But, I came to trouble when certain callback functions were required - and I couldn't pass the Object variable to the callback functions that needed to access the database.

bokeh
02-08-2007, 04:37 PM
I couldn't pass the Object variable to the callback functions that needed to access the database.Why not? Can you write a simple example?

sitehatchery
02-08-2007, 04:48 PM
session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');

function _sess_gc($maxlifetime) {
tep_db_query( "delete from " . TABLE_SESSIONS . " where expiry < '" . time() . "'");

return true;
}


The above only shows one of the callback functions used by the session_set_save_handler function.

'_sess_gc' is only looking for one parameter. So, if I add a second parameter, it doesn't see it.

sitehatchery
02-08-2007, 04:51 PM
Hmm... I wonder if I could use a $_REQUEST array to hold the Object variable. I'll try that.

sitehatchery
02-09-2007, 03:08 PM
And ladies and gentlemen, it works!

check it out:

function db_connect($database) {

if(!$_REQUEST['dbhandle'] = new SQLiteDatabase($database)){
die("The database cannot be opened");
}
}

function query($query) {
$result = $_REQUEST['dbhandle']->query($query) or print_error("there was a database error.");
return $result;
}


So, now all I have to do is: $result=query("select * from table");

I'm accessing the database object in a procedural fashion. Why did I do this? Well, for at least 2 reasons.

1. sqlite 3 uses the object-oriented approach. I haven't had luck using the procedural approach with sqlite 3. So, doing it my way gives me the flexibility of going about it either way.
2. There were hundreds of calls to the database that I would have had to modify. This approach minimized the amount of work I had to do. In fact, the only thing I had to alter was this one database functions file.

bokeh
02-09-2007, 04:48 PM
That is a botch; one of the main points OOP is to avoid passing variables around in global scope. You've gone one worse; you're passing them around in superglobal scope. If you need to do that there is something very wrong with your logic/code structure.

sitehatchery
02-09-2007, 05:18 PM
I would have to rewrite just about every page of osCommerce... too much work. I'm just trying to use sqlite instead of mysql. Using this method allows the user to use the sqlite procedural or object method and allows the use of any mysql method as well.

As far as I can tell, there should be no security problem with passing the db handle to $_REQUEST.

sitehatchery
02-09-2007, 05:26 PM
See, there were too many standalone functions that used the database object.

For instance:

function dosomething(){
$result=query_function("select * from table");
...
}

I could have changed everything like this:

function dosomething($db){
$db->result=query_function("select * from table");
}

That worked, but not on the callback functions.

I also could have grouped all the functions and converted them to classes and had them inherit a database class. I started this but it was like trying to open a tight foil ball.

So, this seemed to be the needed short cut with no downside... unless you can show me there is a security concern.

bokeh
02-09-2007, 05:31 PM
Can you show a working example with a call-back function?

sitehatchery
02-09-2007, 06:12 PM
session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy', '_sess_gc');

function _sess_gc($maxlifetime) {
tep_db_query( "delete from " . TABLE_SESSIONS . " where expiry < '" . time() . "'");

return true;
}


If I'm reading it correctly, http://www.php.net/manual/en/function.session-set-save-handler.php warns that the session handler function can't use objects. And I haven't yet figured out to use objects with callback functions anyway.

bokeh
02-10-2007, 03:50 PM
In the page you quoted:
Write and Close handlers are called after destructing objects since PHP 5.0.5. Thus destructors can use sessions but session handler can't use objects. In prior versions, they were called in the opposite order. It is possible to call session_write_close() from the destructor to solve this chicken and egg problem.

As far as the call-back issue goes do you know the syntax?

From PHP.NET
A method of an instantiated object is passed as an array containing an object as the element with index 0 and a method name as the element with index 1. (http://www.php.net/callback)That would look something like this: $this->SomethingElse = preg_replace_callback($regex, array($this, 'CallbackMethodName'),
$this->Something);That assumes the method is part of the current class.