anatak Posted October 20, 2006 Share Posted October 20, 2006 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 changeI have an object to connect to my DB[code]$dbread = &ADONewConnection('mysql');$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); $dbread->debug = $debug; [/code]I have to pass that object to a function[code]$result=get_message(1, $dbread);//here is the functionfunction 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; }[/code]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[code]login_table($dbread);//here is the functionFUNCTION 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}[/code]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 regardsanatak Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted October 20, 2006 Share Posted October 20, 2006 For the 'pass object to function'-part you may change [code]$result=get_message(1, $dbread);[/code] to [code]$result=get_message(1, &$dbread);[/code] Quote Link to comment Share on other sites More sharing options...
anatak Posted October 20, 2006 Author Share Posted October 20, 2006 Hey Daniel0can you please explain what the difference is ? Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted October 20, 2006 Share Posted October 20, 2006 & is the reference operator, it makes it refer to the object instead of copying it. Quote Link to comment Share on other sites More sharing options...
roopurt18 Posted October 20, 2006 Share Posted October 20, 2006 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:[code]<?phpfunction some_func($arg1, $arg2){ // does something cool}?>[/code]When you call some_func from somewhere else in your code:[code]<?php $val1 = 2; $val2 = 3; some_func($val1, $val2);?>[/code]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 [i]values[/i] that $val1 and $val2 contain are [i]copied[/i] into the newly allocated memory; hence we call this type of argument [i]passing by value[/i].Here is a more detailed look at the memory to help illustrate:Memory Address | Value | Variable0xFF00A100 15 $val10xFF00A104 32 $val2Now you call the function and memory is created, those values are copied into the new memory:Memory Address | Value | Variable0xFF00A100 15 $val10xFF00A104 32 $val2...0xFF00B100 15 $arg10xFF00B104 32 $arg2For 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 [i]passing by reference[/i] 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 | Variable0xFF00A100 15 $val10xFF00A104 32 $val2...0xFF00B100 0xFF00A100 $arg10xFF00B104 0xFF00A104 $arg2Notice now that $arg1 and $arg2 hold the [i]address[/i] 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 [i]original[/i] 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 [b]const[/b] 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 [i]original[/i] data! Quote Link to comment Share on other sites More sharing options...
Barand Posted October 22, 2006 Share Posted October 22, 2006 [quote author=anatak link=topic=112100.msg454845#msg454845 date=1161337762]I am mostly interessted in inheritance and public / private implementation in PHP.[/quote]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. Quote Link to comment Share on other sites More sharing options...
anatak Posted October 23, 2006 Author Share Posted October 23, 2006 [quote author=Daniel0 link=topic=112100.msg454857#msg454857 date=1161338918]For the 'pass object to function'-part you may change [code]$result=get_message(1, $dbread);[/code] to [code]$result=get_message(1, &$dbread);[/code][/quote]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 ?thanksanatak Quote Link to comment Share on other sites More sharing options...
neylitalo Posted October 23, 2006 Share Posted October 23, 2006 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.[code]<?php$object = new Object(); //Object is some pre-defined class.$object2 = $object; ?>[/code]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:[code]<?php$object2 = clone $object;?>[/code] Quote Link to comment Share on other sites More sharing options...
anatak Posted October 23, 2006 Author Share Posted October 23, 2006 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 ? Quote Link to comment Share on other sites More sharing options...
Jenk Posted October 23, 2006 Share Posted October 23, 2006 [quote author=Daniel0 link=topic=112100.msg454857#msg454857 date=1161338918]For the 'pass object to function'-part you may change [code]$result=get_message(1, $dbread);[/code] to [code]$result=get_message(1, &$dbread);[/code][/quote]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:[code]function get_message($number, &$dbread){ // do stuff..}[/code] Quote Link to comment Share on other sites More sharing options...
neylitalo Posted October 23, 2006 Share Posted October 23, 2006 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:[code]#!/usr/bin/php<?phpclass Test{ protected $asdf;}$test = new Test();$test2 &= $test;$test3 = $test;print_r($test);print_r($test2);print_r($test3);?>[/code]And this output:[code] $ ./test.phpTest Object( [asdf:protected] =>)0Test Object( [asdf:protected] =>)[/code]Note the 0 before the second Test Object - that's the result of the &= operator. Absolutely nothing. Quote Link to comment Share on other sites More sharing options...
Jenk Posted October 23, 2006 Share Posted October 23, 2006 Actually, the 0 is a result of your incorrect Syntax. It's =& not &=Try this ;)[code]<?phpclass Test{ protected $asdf;}$test = new Test();$test2 =& $test;$test3 = $test;print_r($test);print_r($test2);print_r($test3);?>[/code]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. Quote Link to comment Share on other sites More sharing options...
neylitalo Posted October 23, 2006 Share Posted October 23, 2006 well, by golly, I was wrong again. That puts me into the double digits, darn it.Thanks for pointing it out, Jenk. Quote Link to comment Share on other sites More sharing options...
Jenk Posted October 23, 2006 Share Posted October 23, 2006 No probs :) Quote Link to comment Share on other sites More sharing options...
anatak Posted October 25, 2006 Author Share Posted October 25, 2006 hmm passing by reference behaves a bit weird around here :Dso I have my object dbread[code]$dbread = &ADONewConnection('mysql');$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); [/code]and then a function wich uses that object[code]$result=get_message(1, &$dbread);[/code]here is the function[code]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; }[/code]If I pass by reference with &I get these errorsWarning: 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 68If 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 Quote Link to comment Share on other sites More sharing options...
Jenk Posted October 25, 2006 Share Posted October 25, 2006 http://www.phpfreaks.com/forums/index.php/topic,112100.msg456283.html#msg456283 Quote Link to comment Share on other sites More sharing options...
anatak Posted October 26, 2006 Author Share Posted October 26, 2006 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 ?[code]$dbread = &ADONewConnection('mysql');$dbread->Connect($Host, $SelectUser, $SelectPassword, $Database); $dbread->debug = $debug; [/code][code]$result=get_message(1, $dbread);[/code][code]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; }[/code]and passing from function to function[code]login_table($dbread);//here is the functionFUNCTION 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}[/code]is this line of code then correct[code]<?php $result=get_message(3, $dbread); display_message($result);?>: </td></tr>[/code]or should it be like this ? because the function login_table(&$dbread) accepts &$dbread ?[code]<?php $result=get_message(3, &$dbread); display_message($result);?>: </td></tr>[/code]I am still confused on how many different objects I would have with the above code ??? Quote Link to comment Share on other sites More sharing options...
Jenk Posted October 26, 2006 Share Posted October 26, 2006 [code]<?phpclass 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();?>[/code] Quote Link to comment Share on other sites More sharing options...
Zane Posted November 3, 2006 Share Posted November 3, 2006 [quote]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.[/quote]I think you mean public/private functionsIn 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 classAdditionally in a static function: You can only access the function from outside the class....and not the object eitherExample[code=php:0]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 whateverFoo:functionC(); //would show Static C[/code] Quote Link to comment Share on other sites More sharing options...
Jenk Posted November 6, 2006 Share Posted November 6, 2006 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.[code]<?phpclass Foo{ static $bar; static function fooBarToo() { echo self::$foo; } public function fooBar() { self::fooBarToo(); }}?>[/code]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.[code]<?phpclass 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;}?>[/code]for an example of real world use. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.