Jump to content


Photo

passing object to function ??


  • Please log in to reply
19 replies to this topic

#1 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 20 October 2006 - 09:49 AM

Hello,

I am trying to slowly move to a more OO approach of my code but of course I have a few questions.
here is a specific problem I have that is a symptom of the general design change

I have an object to connect to my DB
$dbread = &ADONewConnection('mysql');
$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); 
$dbread->debug = $debug; 

I have to pass that object to a function
$result=get_message(1, $dbread);

//here is the function
function get_message($mess, $dbread)
{
//	echo $mess;
	$lan= "Lan_".$_SESSION['userlanguage'];
	$table01 = "language_message";
	$query = "SELECT Lan_001, $lan
				FROM $table01
				WHERE Id = $mess;";
				
//	echo $query;
	$result = $dbread->CacheGetRow(60,$query);
//	$result->Close();
	return $result; 

}

but if I want to call that function from another function I have to pass the object again to the first function to pass the object to the function (get_message()) that the first function (login_table) calls.
here is an example
login_table($dbread);
//here is the function
FUNCTION login_table($dbread)
{
// 	comment start: START form voor login
//	comment end
?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] . "?page=authenticate"?>" >
<?php
//		comment start: START nested tabel voor login form
//		comment end
?>
<table width ="100%" border ="1" cellpadding ="2" cellspacing ="0">
<tr><td align = "left" valign = "top">
<?php  $result=get_message(3, $dbread); display_message($result);?>: </td></tr>
<tr><td><INPUT size="16" type="text" name="UserHandle" /></td></tr>
<tr><td align="left" valign="top"><?php  $result=get_message(4, $dbread); display_message($result);?>: </td></tr>
<tr><td><INPUT size="16" type="password" name="UserPassword" /></td></tr>
<tr>
<td>
<input type="submit" name="submit" value="Submit">
<input type="reset" value="Clear">
</td>
</tr>
</table>
<?php
//		comment start: END nested tabel voor login form
//		comment end
?>
</form>
<?php
//		comment start: END form voor login
//		comment end
}

I fear that this is a totally wrong approach.
Could anybody please comment on this ?
would it be better to create an object login_table ?
and does anyone know a good OO php tutorial specifically explaining what is allowed and what not ?
I learned programming in JAVA (long time ago) but I am not sure if all the JAVA OO principles are allowed in PHP.
I am mostly interessted in inheritance and public / private implementation in PHP.

Or do you think that the way it is now is fine ?
I fear that it is not a memory efficient way of coding.

kind regards
anatak
takasi.8008@docomo.ne.jp
tourokum@0508.jp

#2 Daniel0

Daniel0
  • Staff Alumni
  • Advanced Member
  • 11,956 posts

Posted 20 October 2006 - 10:08 AM

For the 'pass object to function'-part you may change
$result=get_message(1, $dbread);
to
$result=get_message(1, &$dbread);


#3 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 20 October 2006 - 10:19 AM

Hey Daniel0
can you please explain what the difference is ?
takasi.8008@docomo.ne.jp
tourokum@0508.jp

#4 Daniel0

Daniel0
  • Staff Alumni
  • Advanced Member
  • 11,956 posts

Posted 20 October 2006 - 10:23 AM

& is the reference operator, it makes it refer to the object instead of copying it.

#5 roopurt18

roopurt18
  • Staff Alumni
  • Advanced Member
  • 3,749 posts
  • LocationCalifornia, southern

Posted 20 October 2006 - 05:46 PM

Just to expand on Daniel0's reply for anyone newer to programming:

When you pass variables into functions, they're usually passed by value.  Let's say you have the following function:
<?php
function some_func($arg1, $arg2){
  // does something cool
}
?>

When you call some_func from somewhere else in your code:
<?php
  $val1 = 2;
  $val2 = 3;
  some_func($val1, $val2);
?>
At the point of the function call, memory is allocated and set aside for the function.  The amount of memory allocated is dependent on how many arguments and local variables the function contains.  In the case of some func, it needs to allocate memory for at least the two incoming arguments.  What happens is the values that $val1 and $val2 contain are copied into the newly allocated memory; hence we call this type of argument passing by value.

Here is a more detailed look at the memory to help illustrate:
Memory Address   |  Value | Variable
0xFF00A100            15        $val1
0xFF00A104            32        $val2

Now you call the function and memory is created, those values are copied into the new memory:
Memory Address   |  Value | Variable
0xFF00A100            15        $val1
0xFF00A104            32        $val2
.
.
.
0xFF00B100            15         $arg1
0xFF00B104            32         $arg2

For regular variables, this isn't a huge issue.  There's a lot of factors that play into this, but most "regular" variables are 4 or 8 bytes in length.  So to have the computer constantly allocate and free a small amount of memory isn't a big deal.

But let's say you're passing an object.  Let's also say this object represents an employee at your work.  In addition to containing a lot of properties such as the employee's name, address, social security, phone number, age, description, etc. it also contains a photo and a voice audio sample.  The photo and the audio sample are going to be big; at least a few hundred kilobytes, maybe even several megabytes.

Now let's say you want to pass this employee object to several functions.  You certainly don't want the computer to constantly allocate and free megabytes of memory if you can avoid it.  This is where passing by reference comes in.  Instead of passing a copy of the object, we'll pass instead the memory address where the original object lives.

Memory Address   |  Value              | Variable
0xFF00A100            15                    $val1
0xFF00A104            32                    $val2
.
.
.
0xFF00B100            0xFF00A100         $arg1
0xFF00B104            0xFF00A104         $arg2


Notice now that $arg1 and $arg2 hold the address of the original data.  There is a side effect to passing by reference; anything you do in the function to the data will have happened to the original data!  So if you change the data and leave the function, the original data will have changed as well.  In other languages, you can declare an argument to a function as const which prevents the function from changing the data; I'm not sure if a similar mechanism is provided by PHP.

A small disclaimer, I am in no way, shape, or form an expert on the internal mechanisms by which PHP passes arguments to function.  The memory examples I gave are accurate for passing pointers in C and C++.  I'm not sure exactly how references are passed internally in any language, although I can't imagine they're passed much differently than a pointer.  That said, the overall idea is accurate:

If you have large objects, that is they require lots of memory, pass them by reference to your functions but be aware that changing them within the function will change the original data!
PHP Forms : Part I | Part II

JavaScript: Singleton

http://www.rbredlau.com

#6 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,017 posts

Posted 22 October 2006 - 10:21 AM

I am mostly interessted in inheritance and public / private implementation in PHP.



If you want to use public/private ownerships you need to use PHP5. You'll find its object model much closer to Java implementation. And objects are passed by reference by default with PHP5 whereas PHP4, by default, passes copies of objects.
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#7 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 23 October 2006 - 01:41 AM

For the 'pass object to function'-part you may change

$result=get_message(1, $dbread);
to
$result=get_message(1, &$dbread);


Is it allowed to pass by reference using the & in PHP5 ?
Or is there a drawback in using the & in php5 ?
Does PHP5 allow this or will it give problems ?

thanks
anatak
takasi.8008@docomo.ne.jp
tourokum@0508.jp

#8 neylitalo

neylitalo
  • Staff Alumni
  • Advanced Member
  • 1,854 posts
  • LocationMichigan, USA

Posted 23 October 2006 - 02:18 AM

You can still use =& in PHP 5, but it will do absolutely nothing if you're using it on objects. The default (only) behavior in PHP 5 for referring to objects does the same exact thing as using =&. If you do, indeed, want a copy of an object, then use the clone keyword - as follows.

This code is PHP 5.

<?php
$object = new Object(); //Object is some pre-defined class.
$object2 = $object; 
?>

And now, if we were to print_r on $object2 and $object, we would find that they point to the same exact object. To actually create a duplicate object of $object, we'd do this:

<?php
$object2 = clone $object;
?>

http://nealylitalo.net - My personal website, and home of The Netizen's Journal.

#9 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 23 October 2006 - 05:14 AM

Thank you everybody.
Passing by reference is now a lot clearer to me and I realize I have to change almost all my code as I thought that passing by reference was the default behaviour.

I would like to know the scope and syntax of public private classes now.
how do you create a public class ?
what are the drawbacks of public classes ?
If I remember correctly in Java my teacher used to say that we should try to use as much private classes as public classes tended to be a risk to mess up later programming.

the problem is that I forgot most of it I am afraid.

I think he meant that a public class / variables where available to all classes and thus posed the risk that the public variables can be altered by all methods.
A private variable can only be altered by the methods defined in the class wich the variable belongs to.

Is this more or less correct ?


takasi.8008@docomo.ne.jp
tourokum@0508.jp

#10 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 23 October 2006 - 01:32 PM

For the 'pass object to function'-part you may change

$result=get_message(1, $dbread);
to
$result=get_message(1, &$dbread);

Those are actually incorrect, runtime parameter references were disabled many moons ago. However, this doesn't appear to be what you were referring to, below is what I think you wanted:

function get_message($number, &$dbread)
{
  // do stuff..
}


#11 neylitalo

neylitalo
  • Staff Alumni
  • Advanced Member
  • 1,854 posts
  • LocationMichigan, USA

Posted 23 October 2006 - 01:48 PM

I'm not sure how many times I can say this, but if you use PHP 5, you DO NOT NEED the & operator. As a matter of fact, if you use the & operator, it will break. And judging from the third or so post in, we're talking about PHP 5 here.

Note this code:
#!/usr/bin/php
<?php

class Test
{
    protected $asdf;
}

$test = new Test();
$test2 &= $test;
$test3 = $test;

print_r($test);
print_r($test2);
print_r($test3);
?>

And this output:

$ ./test.php
Test Object
(
    [asdf:protected] =>
)
0Test Object
(
    [asdf:protected] =>
)

Note the 0 before the second Test Object - that's the result of the &= operator. Absolutely nothing.

http://nealylitalo.net - My personal website, and home of The Netizen's Journal.

#12 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 23 October 2006 - 01:58 PM

Actually, the 0 is a result of your incorrect Syntax. It's =& not &=

Try this ;)
<?php

class Test
{
    protected $asdf;
}

$test = new Test();
$test2 =& $test;
$test3 = $test;

print_r($test);
print_r($test2);
print_r($test3);
?>

You'll get an E_STRICT message informing you that php5 no longer requires reference operator, and that's it. All else will continue as is in PHP4.

#13 neylitalo

neylitalo
  • Staff Alumni
  • Advanced Member
  • 1,854 posts
  • LocationMichigan, USA

Posted 23 October 2006 - 03:38 PM

well, by golly, I was wrong again. That puts me into the double digits, darn it.

Thanks for pointing it out, Jenk.
http://nealylitalo.net - My personal website, and home of The Netizen's Journal.

#14 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 23 October 2006 - 03:39 PM

No probs :)

#15 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 25 October 2006 - 11:03 PM

hmm passing by reference behaves a bit weird around here :D

so I have my object dbread
$dbread = &ADONewConnection('mysql');
$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); 

and then a function wich uses that object
$result=get_message(1, &$dbread);

here is the function
function get_message($mess, $dbread)
{
//	echo $mess;
	$lan= "Lan_".$_SESSION['userlanguage'];
	$table01 = "language_message";
	$query = "SELECT Lan_1, $lan
				FROM $table01
				WHERE Id = $mess;";
				
//	echo $query;
	$result = &$dbread->CacheGetRow(60,$query);
//	$result->Close();
	return $result; 

}

If I pass by reference with &
I get these errors

Warning: Call-time pass-by-reference has been deprecated - argument passed by value; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file. However, future versions may not support this any longer. in c:\program files\easyphp1-8\www\kyushunetwork\public_html\index.php on line 68

If I change in the function get_message($mess, $dbread)
this line
$result = $dbread->CacheGetRow(60,$query);
into this
$result = &$dbread->CacheGetRow(60,$query);

I don't get any errors.
I am a bit confused here.
I thought to pass by reference you had to pass the object with & to the function that uses the object.
Am I creating multiple objects (using PHP4 ?) I understand that in PHP5 this is not a problem.

anatak
takasi.8008@docomo.ne.jp
tourokum@0508.jp

#16 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 25 October 2006 - 11:20 PM

http://www.phpfreaks....html#msg456283

#17 anatak

anatak
  • Members
  • PipPipPip
  • Advanced Member
  • 406 posts
  • LocationJapan, Fukuoka prefecture, Kitakyushu City

Posted 26 October 2006 - 06:22 AM

whoooops
sorry misviewed this.
so when you instantiate an object you don't use &
when you pass the object you don't use the &
in the function that receives the object you use the &

is this correct ?
$dbread = &ADONewConnection('mysql');
$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); 
$dbread->debug = $debug; 

$result=get_message(1, $dbread);

function get_message($mess, &$dbread)
{
//	echo $mess;
	$lan= "Lan_".$_SESSION['userlanguage'];
	$table01 = "language_message";
	$query = "SELECT Lan_001, $lan
				FROM $table01
				WHERE Id = $mess;";
				
//	echo $query;
	$result = &$dbread->CacheGetRow(60,$query);
//	$result->Close();
	return $result; 

}

and passing from function to function
login_table($dbread);
//here is the function
FUNCTION login_table(&$dbread)
{
// 	comment start: START form voor login
//	comment end
?>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF'] . "?page=authenticate"?>" >
<?php
//		comment start: START nested tabel voor login form
//		comment end
?>
<table width ="100%" border ="1" cellpadding ="2" cellspacing ="0">
<tr><td align = "left" valign = "top">
<?php  $result=get_message(3, $dbread); display_message($result);?>: </td></tr>
<tr><td><INPUT size="16" type="text" name="UserHandle" /></td></tr>
<tr><td align="left" valign="top"><?php  $result=get_message(4, $dbread); display_message($result);?>: </td></tr>
<tr><td><INPUT size="16" type="password" name="UserPassword" /></td></tr>
<tr>
<td>
<input type="submit" name="submit" value="Submit">
<input type="reset" value="Clear">
</td>
</tr>
</table>
<?php
//		comment start: END nested tabel voor login form
//		comment end
?>
</form>
<?php
//		comment start: END form voor login
//		comment end
}

is this line of code then correct
<?php  $result=get_message(3, $dbread); display_message($result);?>: </td></tr>
or should it be like this ? because the function login_table(&$dbread) accepts &$dbread ?
<?php  $result=get_message(3, &$dbread); display_message($result);?>: </td></tr>

I am still confused on how many different objects I would have with the above code  ???
takasi.8008@docomo.ne.jp
tourokum@0508.jp

#18 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 26 October 2006 - 08:13 AM

<?php

class Foo
{
    var $bar = 'foo';
    function doSomething()
    {
        $this->bar = 'foobar!';
    }
    function shoutBar()
    {
        echo $this->bar;
    }
}

function doSomething(&$object)
{
    $object->doSomething();
}

$var = new Foo;
$var->shoutBar();
doSomething($var);
$var->shoutBar();

?>


#19 Zane

Zane
  • Administrators
  • Advanced Member
  • 4,134 posts

Posted 03 November 2006 - 05:42 AM

what are the drawbacks of public classes ?
If I remember correctly in Java my teacher used to say that we should try to use as much private classes as public classes tended to be a risk to mess up later programming.


I think you mean public/private functions

In a public function: You can access the function from within the class and outside the class (from the object)
In a private function: You can only access the function from within the class
Additionally in a static function: You can only access the function from outside the class....and not the object either

Example

class Foo
  public Foo() {
  }
  public functionA($showB = false) {
     echo "A";
     if($showB)
         $this->functionB();
  }
  private functionB() {
     echo "B";
  }
  static functionC() {
      echo "Static C";
   }
}

$var = new Foo();
$var->functionA(); //would show A
$var->functionA(true); //would show AB

$var->functionB(); //would return an error because it's private
$var->functionC(); //would return an error for non-object whatever

Foo:functionC(); //would show Static C




btn_donate_SM.gif Want to thank me? Contribute to my PayPal piggy-bank
 

172938.png

#20 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 06 November 2006 - 01:04 PM

Just to extend on Zanus' post, you can reference a static method from within an object, however you must remember that static properties and methods are not included in the object instantiation. ergo they are not part of the object and must be used and referenced as such.

<?php

class Foo
{
    static $bar;

    static function fooBarToo()
    {
        echo self::$foo;
    }

    public function fooBar()
    {
        self::fooBarToo();
    }
}

?>

This is handy for instances where you will have one function that will accomodate in all objects of that class, but you don't want that function weighing down all of the objects, such as a text formatting function or similar.

<?php

class Loader
{
    private static function formatName($name)
    {
        $name = str_replace('_', ' ', $name);
        $name = str_replace(' ', '/', ucwords($name));
        return $name;
    }

    public function loadClass($className)
    {
        $className = self::formatName($className) . '.php';
        if (!is_file($className) || !is_readable($className))
        {
            throw new Loader_Exception('the file "' . $className . '" does not exist, or cannot be read');
        }
        else
        {
            include($className);
        }
    }
}

$load = new Loader;

try
{
    $load->loadClass('Path_To_My_Class.php');
}
catch (Loader_Exception $e)
{
    echo $e;
}

?>
for an example of real world use.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users